[PATCH] D34355: [LLD][ELF] Define _GLOBAL_OFFSET_TABLE_ to base of .got for ARM

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 19 09:54:25 PDT 2017


peter.smith created this revision.
Herald added subscribers: kristof.beyls, javed.absar, aemerson.

On many architectures gcc and clang will recognize _GLOBAL_OFFSET_TABLE_ - . and produce a relocation that can be processed without needing to know the value of _GLOBAL_OFFSET_TABLE_. For ARM gcc produces R_ARM_BASE_PREL but clang produces the more general R_ARM_REL32 to _GLOBAL_OFFSET_TABLE_. To evaluate this relocation correctly _GLOBAL_OFFSET_TABLE_ must be defined to be the base of the GOT (R_ARM_BASE_PREL evaluates to this value).

If/when llvm-mc is changed to recognize _GLOBAL_OFFSET_TABLE_ - . this change will not be necessary for new objects. However there may still be old objects and versions of clang so I think it is worth making the change in lld as well as fixing llvm-mc.

This partially fixes pr33511, the R_ARM_REL32 relocation error messages disappear but there are a couple more relocation errors relating to R_ARM_GOTOFF32, I think that these are unrelated to _GLOBAL_OFFSET_TABLE_ though.


https://reviews.llvm.org/D34355

Files:
  ELF/Writer.cpp
  test/ELF/arm-got-relative.s


Index: test/ELF/arm-got-relative.s
===================================================================
--- test/ELF/arm-got-relative.s
+++ test/ELF/arm-got-relative.s
@@ -16,9 +16,9 @@
  bx lr
  .align 2
 .LGOT:
- // gas implicitly uses (GOT_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
- // llvm-mc needs the (GOT_PREL) suffix or it generates R_ARM_REL32
- .word _GLOBAL_OFFSET_TABLE_(GOT_PREL) - (.LPIC+8)
+ // gas implicitly uses (R_ARM_BASE_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
+ // llvm-mc generates R_ARM_REL32, this will need updating when MC changes
+ .word _GLOBAL_OFFSET_TABLE_ - (.LPIC+8)
  .word function(GOT)
 
  .globl function
@@ -28,17 +28,17 @@
  bx lr
 
 // CHECK: Dynamic Relocations {
-// CHECK-NEXT:  0x204C R_ARM_GLOB_DAT function 0x0
+// CHECK-NEXT:  0x2048 R_ARM_GLOB_DAT function 0x0
 
 // CHECK: Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT:    Value: 0x0
+// CHECK-NEXT:    Value: 0x2048
 // CHECK-NEXT:    Size:
 // CHECK-NEXT:    Binding: Local
 // CHECK-NEXT:    Type: None
 // CHECK-NEXT:    Other [
 // CHECK-NEXT:      STV_HIDDEN
 // CHECK-NEXT:    ]
-// CHECK-NEXT:    Section: Absolute
+// CHECK-NEXT:    Section: .got
 
 // CODE: Disassembly of section .text:
 // CODE-NEXT: _start:
@@ -49,5 +49,5 @@
 // CODE:$d.1:
 // (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038
 // CODE-NEXT:    1010:        38 10 00 00
-// (Got(function) - GotBase = 0x4
-// CODE-NEXT:    1014:        04 00 00 00
+// (Got(function) - GotBase = 0x0
+// CODE-NEXT:    1014:        00 00 00 00
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -825,9 +825,16 @@
   // The situation is even stranger on x86_64 where the assembly doesn't
   // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
   // an undefined symbol in the .o files.
-  // Given that the symbol is effectively unused, we just create a dummy
-  // hidden one to avoid the undefined symbol error.
-  Symtab<ELFT>::X->addIgnored("_GLOBAL_OFFSET_TABLE_");
+  // For ARM the clang assembler may not have treated _GLOBAL_OFFSET_TABLE_ as
+  // special so we may encounter a R_ARM_REL32 to _GLOBAL_OFFSET_TABLE_ which
+  // will only evaluate correctly if _GLOBAL_OFFSET_TABLE_ is at the base of the
+  // .got section. for other architectures, given that the symbol is
+  // effectively unused, we just create a dummy hidden one to avoid the
+  // undefined symbol error.
+  if (Config->EMachine == EM_ARM && InX::Got)
+    addOptionalRegular<ELFT>("_GLOBAL_OFFSET_TABLE_", InX::Got, 0);
+  else
+    Symtab<ELFT>::X->addIgnored("_GLOBAL_OFFSET_TABLE_");
 
   // __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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34355.103065.patch
Type: text/x-patch
Size: 2784 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170619/470e0c1c/attachment.bin>


More information about the llvm-commits mailing list