diff options
-rw-r--r-- | lld/ELF/Writer.cpp | 12 | ||||
-rw-r--r-- | lld/test/ELF/arm-static-defines.s | 44 |
2 files changed, 52 insertions, 4 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7106e16f94e..a280194ee5d 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -632,10 +632,11 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() { // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For // static linking the linker is required to optimize away any references to // __tls_get_addr, so it's not defined anywhere. Create a hidden definition - // to avoid the undefined symbol error. As usual as special case is MIPS - - // MIPS libc defines __tls_get_addr itself because there are no TLS - // optimizations for this target. - if (!Out<ELFT>::DynSymTab && Config->EMachine != EM_MIPS) + // to avoid the undefined symbol error. As usual special cases are ARM and + // MIPS - the libc for these targets defines __tls_get_addr itself because + // there are no TLS optimizations for these targets. + if (!Out<ELFT>::DynSymTab && + (Config->EMachine != EM_MIPS && Config->EMachine != EM_ARM)) Symtab<ELFT>::X->addIgnored("__tls_get_addr"); // If linker script do layout we do not need to create any standart symbols. @@ -967,6 +968,9 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { Out<ELFT>::PreinitArray); Define("__init_array_start", "__init_array_end", Out<ELFT>::InitArray); Define("__fini_array_start", "__fini_array_end", Out<ELFT>::FiniArray); + + if (OutputSectionBase<ELFT> *Sec = findSection(".ARM.exidx")) + Define("__exidx_start", "__exidx_end", Sec); } // If a section name is valid as a C identifier (which is rare because of diff --git a/lld/test/ELF/arm-static-defines.s b/lld/test/ELF/arm-static-defines.s new file mode 100644 index 00000000000..5b9d950e6bf --- /dev/null +++ b/lld/test/ELF/arm-static-defines.s @@ -0,0 +1,44 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t --static -o %t2 2>&1 +// RUN: llvm-readobj --symbols %t2 | FileCheck %s +// REQUIRES: arm + +// Check that on ARM we don't get a multiply defined symbol for __tls_get_addr +// and undefined symbols for references to __exidx_start and __exidx_end + .syntax unified +.section .text + .global __tls_get_addr +__tls_get_addr: + bx lr + + .global _start + .global __exidx_start + .global __exidx_end +_start: + .fnstart + bx lr + .word __exidx_start + .word __exidx_end + .cantunwind + .fnend + +// CHECK: Name: __exidx_end +// CHECK-NEXT: Value: 0x100DC +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .ARM.exidx +// CHECK: Name: __exidx_start +// CHECK-NEXT: Value: 0x100D4 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .ARM.exidx +// CHECK: Symbol { +// CHECK-NEXT: Name: __tls_get_addr |