[lld] r261678 - Fix the aarch64 logic for dynamic relocations.

Adhemerval Zanella via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 24 07:37:57 PST 2016


I am linking against default gcc-4.9 files from Ubuntu 15.04.

On 24-02-2016 12:16, Rafael EspĂ­ndola wrote:
> Can you attach (os post somewhere) the following files:
> 
> crtbeginS.o
> crti.o
> crtendS.o
> libgcc.so
> libgcc_s.so
> libc.so (this may be a script, in which case I need the files it includes)
> crtn.o
> 
> Thanks,
> Rafael
> 
> 
> 
> 
> On 24 February 2016 at 09:43, Adhemerval Zanella
> <adhemerval.zanella at linaro.org> wrote:
>> I am getting shared library dynamic relocations issues since this 'fix'
>> for aarch64:
>>
>> $ cat tls_test.h
>> #ifndef TLS_TEST_H
>> # define TLS_TEST_H
>>
>> int f1 ();
>> int f2 ();
>>
>> extern int __thread o1;
>>
>> #endif
>> $ cat tls_shared.c
>> #include "tls_test.h"
>>
>> int v1;
>> int v2 = 5;
>>
>> int f1 ()
>> {
>>   return v1;
>> }
>>
>> int f2 ()
>> {
>>   return v2;
>> }
>>
>> __thread int o1 = 7;
>> $ cat tls_main.c
>> #include <assert.h>
>> #include "tls_test.h"
>>
>> int main ()
>> {
>>   // Run the tests.
>>   assert(f1() == 0);
>>   assert(f2() == 5);
>>   assert(o1 == 7);
>>
>>   return 0;
>> }
>> $ clang -Wall -O3 -target aarch64-linux-gnu  -fpic -c -o tls_shared.o tls_shared.c
>> $ clang -target aarch64-linux-gnu -shared -Wl,-soname,libtls_test.so tls_shared.o -o libtls_test.so
>> $ clang -Wall -O3 -target aarch64-linux-gnu -c -o tls_main.o tls_main.c
>> $ clang -Wall -O3 -target aarch64-linux-gnu tls_main.o -o tls_main -pthread -L`pwd` -ltls_test
>>
>> $ LD_LIBRARY_PATH=. ./tls_main
>> Segmentation fault (core dumped)
>>
>> $ gdb ./tls_main
>> (gdb) set env LD_LIBRARY_PATH=.
>> (gdb) r
>> Starting program: /home/adhemerval.zanella/llvm/tls/test02/tls_main
>>
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x0000007fb7fdd194 in elf_machine_rela (reloc=0x7fb7ff6540, reloc=0x7fb7ff6540, skip_ifunc=<optimized out>, reloc_addr_arg=0x7fb7ff7124, version=0x0, sym=0x7fb7ff6238,
>>     map=0x7fb7ffb5b0) at ../sysdeps/aarch64/dl-machine.h:242
>> 242     ../sysdeps/aarch64/dl-machine.h: No such file or directory.
>>
>> It is creating a lot of bogus R_AARCH64_RELATIVE relocations:
>>
>> $ objdump -R libtls_test.so
>>
>> libtls_test.so:     file format elf64-littleaarch64
>>
>> DYNAMIC RELOCATION RECORDS
>> OFFSET           TYPE              VALUE
>> 0000000000002170 R_AARCH64_GLOB_DAT  __gmon_start__
>> 0000000000001124 R_AARCH64_RELATIVE  *ABS*+0x0000000000001000
>> 0000000000001014 R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 0000000000001018 R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 000000000000101c R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 0000000000001020 R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 0000000000002178 R_AARCH64_GLOB_DAT  _ITM_deregisterTMCloneTable
>> 0000000000001048 R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 000000000000104c R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 0000000000001050 R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 0000000000001054 R_AARCH64_RELATIVE  *ABS*+0x0000000000003010
>> 0000000000002180 R_AARCH64_GLOB_DAT  _ITM_registerTMCloneTable
>> 000000000000108c R_AARCH64_RELATIVE  *ABS*+0x0000000000003038
>> 0000000000001090 R_AARCH64_RELATIVE  *ABS*+0x0000000000003038
>> 0000000000002188 R_AARCH64_GLOB_DAT  __cxa_finalize
>> 00000000000010a4 R_AARCH64_RELATIVE  *ABS*+0x0000000000003000
>> 00000000000010a8 R_AARCH64_RELATIVE  *ABS*+0x0000000000003000
>> 00000000000010b8 R_AARCH64_RELATIVE  *ABS*+0x0000000000003038
>> 00000000000010cc R_AARCH64_RELATIVE  *ABS*+0x0000000000002008
>> 00000000000010d4 R_AARCH64_RELATIVE  *ABS*+0x0000000000002008
>> 0000000000002190 R_AARCH64_GLOB_DAT  _Jv_RegisterClasses
>> 0000000000003000 R_AARCH64_RELATIVE  *ABS*+0x0000000000003000
>> 0000000000002010 R_AARCH64_RELATIVE  *ABS*+0x0000000000001080
>> 0000000000002018 R_AARCH64_RELATIVE  *ABS*+0x00000000000010c8
>> 0000000000002198 R_AARCH64_GLOB_DAT  v1
>> 00000000000021a0 R_AARCH64_GLOB_DAT  v2
>> 0000000000003028 R_AARCH64_JUMP_SLOT  __gmon_start__
>> 0000000000003030 R_AARCH64_JUMP_SLOT  __cxa_finalize
>>
>> Where we should expect only three:
>>
>> $ objdump -R libtls_test-gcc.so
>>
>> libtls_test-gcc.so:     file format elf64-littleaarch64
>>
>> DYNAMIC RELOCATION RECORDS
>> OFFSET           TYPE              VALUE
>> 0000000000010dc0 R_AARCH64_RELATIVE  *ABS*+0x00000000000007e8
>> 0000000000010dc8 R_AARCH64_RELATIVE  *ABS*+0x00000000000007a0
>> 0000000000011010 R_AARCH64_RELATIVE  *ABS*+0x0000000000011010
>>
>> These are the init_array one against <frame_dummy> (0x7e8),
>> <__do_global_dtors_aux> (0x7a0), and <__dso_handle> (0x11010)
>>
>> On 23-02-2016 17:19, Rafael Espindola via llvm-commits wrote:
>>> Author: rafael
>>> Date: Tue Feb 23 14:19:44 2016
>>> New Revision: 261678
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=261678&view=rev
>>> Log:
>>> Fix the aarch64 logic for dynamic relocations.
>>>
>>> There is nothing aarch64 specific in here. If a symbol can be preempted,
>>> we need to copy the full relocation to the dynamic linker.
>>>
>>> If a symbol cannot be preempted, we can make the dynamic linker life
>>> easier and produce a relative relocation.
>>>
>>> This is directly equivalent to R_X86_64_64 to R_x86_64_RELATIVE
>>> conversion.
>>>
>>> Modified:
>>>     lld/trunk/ELF/OutputSections.cpp
>>>     lld/trunk/ELF/OutputSections.h
>>>     lld/trunk/ELF/Target.cpp
>>>     lld/trunk/ELF/Writer.cpp
>>>     lld/trunk/test/ELF/aarch64-abs64-dyn.s
>>>
>>> Modified: lld/trunk/ELF/OutputSections.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=261678&r1=261677&r2=261678&view=diff
>>> ==============================================================================
>>> --- lld/trunk/ELF/OutputSections.cpp (original)
>>> +++ lld/trunk/ELF/OutputSections.cpp Tue Feb 23 14:19:44 2016
>>> @@ -253,18 +253,11 @@ template <class ELFT> void RelocationSec
>>>
>>>      if (IsRela) {
>>>        uintX_t VA = 0;
>>> -      if (Rel.UseSymVA) {
>>> +      if (Rel.UseSymVA)
>>>          VA = Sym->getVA<ELFT>();
>>> -      } else if (Rel.TargetSec) {
>>> +      else if (Rel.TargetSec)
>>>          VA = Rel.TargetSec->getOffset(Rel.OffsetInTargetSec) +
>>>               Rel.TargetSec->OutSec->getVA();
>>> -      } else if (!Sym && Rel.OffsetSec) {
>>> -        // Sym equal to nullptr means the dynamic relocation is against a
>>> -        // local symbol represented by Rel.SymIndex.
>>> -        ObjectFile<ELFT> *File = Rel.OffsetSec->getFile();
>>> -        const Elf_Sym *LocalSym = File->getLocalSymbol(Rel.SymIndex);
>>> -        VA = getLocalTarget(*File, *LocalSym, 0);
>>> -      }
>>>        reinterpret_cast<Elf_Rela *>(P)->r_addend = Rel.Addend + VA;
>>>      }
>>>
>>> @@ -869,6 +862,7 @@ elf2::getLocalRelTarget(const ObjectFile
>>>                          const Elf_Rel_Impl<ELFT, IsRela> &RI,
>>>                          typename ELFFile<ELFT>::uintX_t Addend) {
>>>    typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
>>> +  typedef typename ELFFile<ELFT>::uintX_t uintX_t;
>>>
>>>    // PPC64 has a special relocation representing the TOC base pointer
>>>    // that does not have a corresponding symbol.
>>> @@ -881,22 +875,10 @@ elf2::getLocalRelTarget(const ObjectFile
>>>    if (!Sym)
>>>      fatal("Unsupported relocation without symbol");
>>>
>>> -  return getLocalTarget(File, *Sym, Addend);
>>> -}
>>> -
>>> -template <class ELFT>
>>> -typename ELFFile<ELFT>::uintX_t
>>> -elf2::getLocalTarget(const ObjectFile<ELFT> &File,
>>> -                     const typename ELFFile<ELFT>::Elf_Sym &Sym,
>>> -                     typename ELFFile<ELFT>::uintX_t Addend) {
>>> -  typedef typename ELFFile<ELFT>::uintX_t uintX_t;
>>> -
>>> -  InputSectionBase<ELFT> *Section = File.getSection(Sym);
>>> -  if (!Section)
>>> -    return Addend;
>>> +  InputSectionBase<ELFT> *Section = File.getSection(*Sym);
>>>
>>> -  if (Sym.getType() == STT_TLS)
>>> -    return (Section->OutSec->getVA() + Section->getOffset(Sym) + Addend) -
>>> +  if (Sym->getType() == STT_TLS)
>>> +    return (Section->OutSec->getVA() + Section->getOffset(*Sym) + Addend) -
>>>             Out<ELFT>::TlsPhdr->p_vaddr;
>>>
>>>    // According to the ELF spec reference to a local symbol from outside
>>> @@ -906,8 +888,8 @@ elf2::getLocalTarget(const ObjectFile<EL
>>>    if (Section == &InputSection<ELFT>::Discarded || !Section->isLive())
>>>      return Addend;
>>>
>>> -  uintX_t Offset = Sym.st_value;
>>> -  if (Sym.getType() == STT_SECTION) {
>>> +  uintX_t Offset = Sym->st_value;
>>> +  if (Sym->getType() == STT_SECTION) {
>>>      Offset += Addend;
>>>      Addend = 0;
>>>    }
>>> @@ -1665,18 +1647,5 @@ template uint64_t getLocalRelTarget(cons
>>>  template uint64_t getLocalRelTarget(const ObjectFile<ELF64BE> &,
>>>                                      const ELFFile<ELF64BE>::Elf_Rela &,
>>>                                      uint64_t);
>>> -
>>> -template uint32_t getLocalTarget(const ObjectFile<ELF32LE> &,
>>> -                                 const ELFFile<ELF32LE>::Elf_Sym &Sym,
>>> -                                 uint32_t);
>>> -template uint32_t getLocalTarget(const ObjectFile<ELF32BE> &,
>>> -                                 const ELFFile<ELF32BE>::Elf_Sym &Sym,
>>> -                                 uint32_t);
>>> -template uint64_t getLocalTarget(const ObjectFile<ELF64LE> &,
>>> -                                 const ELFFile<ELF64LE>::Elf_Sym &Sym,
>>> -                                 uint64_t);
>>> -template uint64_t getLocalTarget(const ObjectFile<ELF64BE> &,
>>> -                                 const ELFFile<ELF64BE>::Elf_Sym &Sym,
>>> -                                 uint64_t);
>>>  }
>>>  }
>>>
>>> Modified: lld/trunk/ELF/OutputSections.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=261678&r1=261677&r2=261678&view=diff
>>> ==============================================================================
>>> --- lld/trunk/ELF/OutputSections.h (original)
>>> +++ lld/trunk/ELF/OutputSections.h Tue Feb 23 14:19:44 2016
>>> @@ -53,12 +53,6 @@ getLocalRelTarget(const ObjectFile<ELFT>
>>>                    const llvm::object::Elf_Rel_Impl<ELFT, IsRela> &Rel,
>>>                    typename llvm::object::ELFFile<ELFT>::uintX_t Addend);
>>>
>>> -template <class ELFT>
>>> -typename llvm::object::ELFFile<ELFT>::uintX_t
>>> -getLocalTarget(const ObjectFile<ELFT> &File,
>>> -               const typename llvm::object::ELFFile<ELFT>::Elf_Sym &Sym,
>>> -               typename llvm::object::ELFFile<ELFT>::uintX_t Addend);
>>> -
>>>  bool canBePreempted(const SymbolBody *Body, bool NeedsGot);
>>>
>>>  // This represents a section in an output file.
>>> @@ -193,7 +187,6 @@ template <class ELFT> struct DynamicRelo
>>>    } OKind;
>>>
>>>    SymbolBody *Sym = nullptr;
>>> -  uint32_t SymIndex = 0;
>>>    InputSectionBase<ELFT> *OffsetSec = nullptr;
>>>    uintX_t OffsetInSec = 0;
>>>    bool UseSymVA = false;
>>> @@ -214,12 +207,6 @@ template <class ELFT> struct DynamicRelo
>>>          OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {}
>>>
>>>    DynamicReloc(uint32_t Type, InputSectionBase<ELFT> *OffsetSec,
>>> -               uintX_t OffsetInSec, bool UseSymVA, uint32_t SymIndex,
>>> -               uintX_t Addend)
>>> -      : Type(Type), OKind(Off_Sec), SymIndex(SymIndex), OffsetSec(OffsetSec),
>>> -        OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {}
>>> -
>>> -  DynamicReloc(uint32_t Type, InputSectionBase<ELFT> *OffsetSec,
>>>                 uintX_t OffsetInSec, InputSectionBase<ELFT> *TargetSec,
>>>                 uintX_t OffsetInTargetSec, uintX_t Addend)
>>>        : Type(Type), OKind(Off_Sec), OffsetSec(OffsetSec),
>>> @@ -267,7 +254,6 @@ private:
>>>
>>>  template <class ELFT>
>>>  class RelocationSection final : public OutputSectionBase<ELFT> {
>>> -  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
>>>    typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
>>>    typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
>>>    typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
>>>
>>> Modified: lld/trunk/ELF/Target.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=261678&r1=261677&r2=261678&view=diff
>>> ==============================================================================
>>> --- lld/trunk/ELF/Target.cpp (original)
>>> +++ lld/trunk/ELF/Target.cpp Tue Feb 23 14:19:44 2016
>>> @@ -181,8 +181,8 @@ public:
>>>                  int32_t Index, unsigned RelOff) const override;
>>>    unsigned getTlsGotRel(unsigned Type) const override;
>>>    bool isTlsDynRel(unsigned Type, const SymbolBody &S) const override;
>>> +  bool isRelRelative(uint32_t Type) const override;
>>>    bool needsCopyRelImpl(uint32_t Type) const override;
>>> -  bool needsDynRelative(unsigned Type) const override;
>>>    bool needsGot(uint32_t Type, SymbolBody &S) const override;
>>>    PltNeed needsPlt(uint32_t Type, const SymbolBody &S) const override;
>>>    void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
>>> @@ -1209,6 +1209,8 @@ AArch64TargetInfo::AArch64TargetInfo() {
>>>    PltZeroSize = 32;
>>>  }
>>>
>>> +bool AArch64TargetInfo::isRelRelative(uint32_t Type) const { return false; }
>>> +
>>>  bool AArch64TargetInfo::isTlsGlobalDynamicRel(unsigned Type) const {
>>>    return Type == R_AARCH64_TLSDESC_ADR_PAGE21 ||
>>>           Type == R_AARCH64_TLSDESC_LD64_LO12_NC ||
>>> @@ -1305,10 +1307,6 @@ bool AArch64TargetInfo::needsCopyRelImpl
>>>    }
>>>  }
>>>
>>> -bool AArch64TargetInfo::needsDynRelative(unsigned Type) const {
>>> -  return Config->Shared && Type == R_AARCH64_ABS64;
>>> -}
>>> -
>>>  bool AArch64TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const {
>>>    switch (Type) {
>>>    case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
>>>
>>> Modified: lld/trunk/ELF/Writer.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=261678&r1=261677&r2=261678&view=diff
>>> ==============================================================================
>>> --- lld/trunk/ELF/Writer.cpp (original)
>>> +++ lld/trunk/ELF/Writer.cpp Tue Feb 23 14:19:44 2016
>>> @@ -311,16 +311,9 @@ void Writer<ELFT>::scanRelocs(
>>>      if (handleTlsRelocation<ELFT>(Type, Body, C, RI))
>>>        continue;
>>>
>>> -    if (Target->needsDynRelative(Type)) {
>>> -      // If Body is null it means the relocation is against a local symbol
>>> -      // and thus we need to pass the local symbol index instead.
>>> -      if (Body)
>>> -        Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true,
>>> -                                      Body, getAddend<ELFT>(RI)});
>>> -      else
>>> -        Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, false,
>>> -                                      SymIndex, getAddend<ELFT>(RI)});
>>> -    }
>>> +    if (Target->needsDynRelative(Type))
>>> +      Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true,
>>> +                                    Body, getAddend<ELFT>(RI)});
>>>
>>>      // MIPS has a special rule to create GOTs for local symbols.
>>>      if (Config->EMachine == EM_MIPS && !canBePreempted(Body, true) &&
>>>
>>> Modified: lld/trunk/test/ELF/aarch64-abs64-dyn.s
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-abs64-dyn.s?rev=261678&r1=261677&r2=261678&view=diff
>>> ==============================================================================
>>> --- lld/trunk/test/ELF/aarch64-abs64-dyn.s (original)
>>> +++ lld/trunk/test/ELF/aarch64-abs64-dyn.s Tue Feb 23 14:19:44 2016
>>> @@ -1,21 +1,27 @@
>>>  // REQUIRES: aarch64
>>>  // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
>>>
>>> -// Creates a R_AARCH64_ABS64 relocation against _foo. It will be used on a
>>> -// shared object to check for a dynamic relocation creation.
>>> -.globl _foo
>>> -_foo:
>>> -   ret
>>> -_foo_init_array:
>>> -  .xword _foo
>>> +// Creates a R_AARCH64_ABS64 relocation against foo and bar
>>> +        .globl foo
>>> +foo:
>>> +
>>> +        .global bar
>>> +        .hidden bar
>>> +bar:
>>> +
>>> +        .data
>>> +        .xword foo
>>> +        .xword bar
>>>
>>>  // RUN: ld.lld -shared -o %t.so %t.o
>>>  // RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
>>>
>>> -// CHECK:       Dynamic Relocations {
>>> -// CHECK-NEXT:      {{.*}} R_AARCH64_RELATIVE - [[FOO_ADDR:[0-9xa-f]+]]
>>> +// CHECK:      Dynamic Relocations {
>>> +// CHECK-NEXT:   {{.*}} R_AARCH64_ABS64 foo 0x0
>>> +// CHECK-NEXT:   {{.*}} R_AARCH64_RELATIVE - [[BAR_ADDR:.*]]
>>> +// CHECK-NEXT: }
>>>
>>> -// CHECK:       Symbols [
>>> -// CHECK:         Symbol {
>>> -// CHECK:           Name: _foo
>>> -// CHECK:           Value: [[FOO_ADDR]]
>>> +// CHECK:      Symbols [
>>> +// CHECK:        Symbol {
>>> +// CHECK:          Name: bar
>>> +// CHECK-NEXT:     Value: [[BAR_ADDR]]
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: files.tar.bz2
Type: application/x-bzip
Size: 644944 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160224/7098fc1d/attachment-0001.bin>


More information about the llvm-commits mailing list