[lld] r249340 - Create R_X86_64_RELATIVE when needed.

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 15 07:13:39 PDT 2015


Hi Rafael,

Could you please better comment the semantics of isRelRelative? Is it true that, for -shared and any relocation for which isRelRelative returns false, getRelativeReloc() is generated? If not, what other conditions affect when getRelativeReloc() is generated?

Thanks again,
Hal

----- Original Message -----
> From: "Rafael Espindola via llvm-commits" <llvm-commits at lists.llvm.org>
> To: llvm-commits at lists.llvm.org
> Sent: Monday, October 5, 2015 2:30:12 PM
> Subject: [lld] r249340 - Create R_X86_64_RELATIVE when needed.
> 
> Author: rafael
> Date: Mon Oct  5 14:30:12 2015
> New Revision: 249340
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=249340&view=rev
> Log:
> Create R_X86_64_RELATIVE when needed.
> 
> The dynamic relocation code needs refactoring, but it is probably
> better
> to do it with this test passing.
> 
> Added:
>     lld/trunk/test/elf2/relative-dynamic-reloc.s
> Modified:
>     lld/trunk/ELF/OutputSections.cpp
>     lld/trunk/ELF/Target.cpp
>     lld/trunk/ELF/Target.h
>     lld/trunk/ELF/Writer.cpp
> 
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249340&r1=249339&r2=249340&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Mon Oct  5 14:30:12 2015
> @@ -104,16 +104,23 @@ template <class ELFT> void RelocationSec
>      uint32_t SymIndex = RI.getSymbol(IsMips64EL);
>      const SymbolBody *Body = C.getFile()->getSymbolBody(SymIndex);
>      uint32_t Type = RI.getType(IsMips64EL);
> -    if (Target->relocNeedsGot(Type, *Body)) {
> +    if (Body && Target->relocNeedsGot(Type, *Body)) {
>        P->r_offset = GotSec.getEntryAddr(*Body);
>        P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
>                            Target->getGotReloc(), IsMips64EL);
>      } else {
>        P->r_offset = RI.r_offset + C.getOutputSectionOff() +
>        Out->getVA();
> -      P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type,
> IsMips64EL);
> -      if (IsRela)
> -        static_cast<Elf_Rela *>(P)->r_addend =
> -            static_cast<const Elf_Rela &>(RI).r_addend;
> +      if (Body && Body->isShared()) {
> +        P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
> Type,
> +                            IsMips64EL);
> +        if (IsRela)
> +          static_cast<Elf_Rela *>(P)->r_addend =
> +              static_cast<const Elf_Rela &>(RI).r_addend;
> +      } else {
> +        P->setSymbolAndType(0, Target->getRelativeReloc(),
> IsMips64EL);
> +        if (IsRela)
> +          static_cast<Elf_Rela *>(P)->r_addend = P->r_offset;
> +      }
>      }
>    }
>  }
> 
> Modified: lld/trunk/ELF/Target.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=249340&r1=249339&r2=249340&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Target.cpp (original)
> +++ lld/trunk/ELF/Target.cpp Mon Oct  5 14:30:12 2015
> @@ -30,6 +30,8 @@ TargetInfo::~TargetInfo() {}
>  
>  bool TargetInfo::relocPointsToGot(uint32_t Type) const { return
>  false; }
>  
> +bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
> +
>  X86TargetInfo::X86TargetInfo() {
>    PCRelReloc = R_386_PC32;
>    GotReloc = R_386_GLOB_DAT;
> @@ -87,6 +89,7 @@ X86_64TargetInfo::X86_64TargetInfo() {
>    PCRelReloc = R_X86_64_PC32;
>    GotReloc = R_X86_64_GLOB_DAT;
>    GotRefReloc = R_X86_64_PC32;
> +  RelativeReloc = R_X86_64_RELATIVE;
>  }
>  
>  void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t
>  GotEntryAddr,
> @@ -139,6 +142,18 @@ bool X86_64TargetInfo::relocNeedsPlt(uin
>      return true;
>    }
>  }
> +
> +bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
> +  switch (Type) {
> +  default:
> +    return false;
> +  case R_X86_64_PC64:
> +  case R_X86_64_PC32:
> +  case R_X86_64_PC16:
> +  case R_X86_64_PC8:
> +    return true;
> +  }
> +}
>  
>  void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
>                                     uint32_t Type, uint64_t BaseAddr,
> 
> Modified: lld/trunk/ELF/Target.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=249340&r1=249339&r2=249340&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Target.h (original)
> +++ lld/trunk/ELF/Target.h Mon Oct  5 14:30:12 2015
> @@ -23,9 +23,11 @@ public:
>    llvm::StringRef getDefaultEntry() const { return DefaultEntry; }
>    unsigned getPCRelReloc() const { return PCRelReloc; }
>    unsigned getGotReloc() const { return GotReloc; }
> -  unsigned getGotRefReloc() const { return GotRefReloc; };
> +  unsigned getGotRefReloc() const { return GotRefReloc; }
> +  unsigned getRelativeReloc() const { return RelativeReloc; }
>    virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
>                               uint64_t PltEntryAddr) const = 0;
> +  virtual bool isRelRelative(uint32_t Type) const;
>    virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S)
>    const = 0;
>    virtual bool relocPointsToGot(uint32_t Type) const;
>    virtual bool relocNeedsPlt(uint32_t Type, const SymbolBody &S)
>    const = 0;
> @@ -39,6 +41,7 @@ protected:
>    unsigned PCRelReloc;
>    unsigned GotRefReloc;
>    unsigned GotReloc;
> +  unsigned RelativeReloc;
>    llvm::StringRef DefaultEntry = "_start";
>  };
>  
> @@ -65,6 +68,7 @@ public:
>    void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
>                     uint64_t BaseAddr, uint64_t SymVA,
>                     uint64_t GotVA) const override;
> +  bool isRelRelative(uint32_t Type) const override;
>  };
>  
>  class PPC64TargetInfo final : public TargetInfo {
> 
> Modified: lld/trunk/ELF/Writer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249340&r1=249339&r2=249340&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Mon Oct  5 14:30:12 2015
> @@ -217,22 +217,29 @@ void Writer<ELFT>::scanRelocs(
>    for (const RelType &RI : Rels) {
>      uint32_t SymIndex = RI.getSymbol(IsMips64EL);
>      SymbolBody *Body = File.getSymbolBody(SymIndex);
> -    if (!Body)
> -      continue;
>      uint32_t Type = RI.getType(IsMips64EL);
> -    if (Target->relocNeedsPlt(Type, *Body)) {
> -      if (Body->isInPlt())
> +    if (Body) {
> +      if (Target->relocNeedsPlt(Type, *Body)) {
> +        if (Body->isInPlt())
> +          continue;
> +        PltSec.addEntry(Body);
> +      }
> +      if (Target->relocNeedsGot(Type, *Body)) {
> +        if (Body->isInGot())
> +          continue;
> +        GotSec.addEntry(Body);
> +        Body->setUsedInDynamicReloc();
> +        RelaDynSec.addReloc({C, RI});
>          continue;
> -      PltSec.addEntry(Body);
> -    }
> -    if (Target->relocNeedsGot(Type, *Body)) {
> -      if (Body->isInGot())
> +      }
> +      if (Body->isShared()) {
> +        Body->setUsedInDynamicReloc();
> +        RelaDynSec.addReloc({C, RI});
>          continue;
> -      GotSec.addEntry(Body);
> -    } else if (!isa<SharedSymbol<ELFT>>(Body))
> -      continue;
> -    Body->setUsedInDynamicReloc();
> -    RelaDynSec.addReloc({C, RI});
> +      }
> +    }
> +    if (Config->Shared && !Target->isRelRelative(Type))
> +      RelaDynSec.addReloc({C, RI});
>    }
>  }
>  
> 
> Added: lld/trunk/test/elf2/relative-dynamic-reloc.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/relative-dynamic-reloc.s?rev=249340&view=auto
> ==============================================================================
> --- lld/trunk/test/elf2/relative-dynamic-reloc.s (added)
> +++ lld/trunk/test/elf2/relative-dynamic-reloc.s Mon Oct  5 14:30:12
> 2015
> @@ -0,0 +1,40 @@
> +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o
> %t.o
> +// RUN: ld.lld2 -shared %t.o -o %t.so
> +// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
> +
> +// Test that we create R_X86_64_RELATIVE relocations but don't put
> any
> +// symbols in the dynamic symbol table.
> +
> +// CHECK:      Relocations [
> +// CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
> +// CHECK-NEXT:     [[FOO_ADDR:.*]] R_X86_64_RELATIVE - [[FOO_ADDR]]
> +// CHECK-NEXT:     [[BAR_ADDR:.*]] R_X86_64_RELATIVE - [[BAR_ADDR]]
> +// CHECK-NEXT:   }
> +// CHECK-NEXT: ]
> +
> +// CHECK:      Symbols [
> +// CHECK:        Name: foo
> +// CHECK-NEXT:   Value: [[FOO_ADDR]]
> +// CHECK:        Name: bar
> +// CHECK-NEXT:   Value: [[BAR_ADDR]]
> +// CHECK:      ]
> +
> +// CHECK:      DynamicSymbols [
> +// CHECK-NEXT:   Symbol {
> +// CHECK-NEXT:     Name: @ (0)
> +// CHECK-NEXT:     Value: 0x0
> +// CHECK-NEXT:     Size: 0
> +// CHECK-NEXT:     Binding: Local
> +// CHECK-NEXT:     Type: None
> +// CHECK-NEXT:     Other: 0
> +// CHECK-NEXT:     Section: Undefined
> +// CHECK-NEXT:   }
> +// CHECK-NEXT: ]
> +
> +foo:
> +        .quad foo
> +
> +        .hidden bar
> +        .global bar
> +bar:
> +        .quad bar
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory


More information about the llvm-commits mailing list