[PATCH] D46319: [MC][ARM] Emit R_ARM_BASE_PREL for _GLOBAL_OFFSET_TABLE_ expressions

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 1 09:11:06 PDT 2018


peter.smith created this revision.
peter.smith added reviewers: espindola, olista01, rengolin.
Herald added subscribers: chrib, fedor.sergeev, kristof.beyls, jyknight.
Herald added a reviewer: javed.absar.

The _GLOBAL_OFFSET_TABLE_ in SysVr4 ELF is conventionally the base of the .got or .got.prel sections. Expressions such as _GLOBAL_OFFSET_TABLE - (.https://reviews.llvm.org/L1+8) are used
 in assembler code to calculate offsets into the .got. At present MC outputs a R_ARM_REL32 with respect to the _GLOBAL_OFFSET_TABLE_ symbol, whereas gas outputs a
 R_ARM_BASE_PREL relocation with respect to the _GLOBAL_OFFSET_TABLE_ symbol. While both are correct, the R_ARM_REL32 depends on the value of the
 _GLOBAL_OFFSET_TABLE_ symbol, whereas the R_ARM_BASE_PREL relocation is independent of the symbol (it resolves to the base of whatever the linker defines the base of the .got to be). The R_ARM_BASE_PREL is therefore slightly more robust to linker's that may not follow the convention of placement of the _GLOBAL_OFFSET_TABLE_; for example LLD for some time defined _GLOBAL_OFFSET_TABLE_ to 0.

Fixes PR33511 (https://bugs.llvm.org/show_bug.cgi?id=33511)

There are a number of other backends (Sparc, X86 and PPC) that special case _GLOBAL_OFFSET_TABLE_ although all need to do it for different cases. The GNU as conversion can be found in tc-arm.c (search for BFD_RELOC_ARMGOTPC), gas also substitutes R_ARM_BASE_PREL for absolute expressions involving _GLOBAL_OFFSET_TABLE_, I'm not sure that this is correct as R_ARM_BASE_PREL is a relative relocation so I've not followed that behaviour.

Arm relocations defined in http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044f/IHI0044F_aaelf.pdf


https://reviews.llvm.org/D46319

Files:
  lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
  test/MC/ARM/symbol-variants.s


Index: test/MC/ARM/symbol-variants.s
===================================================================
--- test/MC/ARM/symbol-variants.s
+++ test/MC/ARM/symbol-variants.s
@@ -96,8 +96,16 @@
 @CHECK: 70 R_ARM_TLS_LDM32 f28
 @CHECK: 74 R_ARM_TLS_LDM32 f29
 
+@ relative
+.word f30 - (.Lsym+8)
+ at CHECK: 78 R_ARM_REL32 f30
+
+@ _GLOBAL_OFFSET_TABLE_ relative
+.word _GLOBAL_OFFSET_TABLE_ - (.Lsym+8)
+ at CHECK: 7c R_ARM_BASE_PREL _GLOBAL_OFFSET_TABLE_
+
 @ got_prel
-.word	f30(GOT_PREL) + (. - .Lsym)
-	ldr r3, =f31(GOT_PREL)
-@ CHECK: 78 R_ARM_GOT_PREL f30
-@ CHECK: 80 R_ARM_GOT_PREL f31
+.word   f31(GOT_PREL) + (. - .Lsym)
+        ldr r3, =f32(GOT_PREL)
+ at CHECK: 80 R_ARM_GOT_PREL f31
+ at CHECK: 88 R_ARM_GOT_PREL f32
Index: lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
===================================================================
--- lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+++ lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
@@ -88,8 +88,15 @@
       switch (Modifier) {
       default:
         llvm_unreachable("Unsupported Modifier");
-      case MCSymbolRefExpr::VK_None:
+      case MCSymbolRefExpr::VK_None: {
+        if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
+          // For GNU AS compatibility expressions such as
+          // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
+          if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
+            return ELF::R_ARM_BASE_PREL;
+        }
         return ELF::R_ARM_REL32;
+      }
       case MCSymbolRefExpr::VK_GOTTPOFF:
         return ELF::R_ARM_TLS_IE32;
       case MCSymbolRefExpr::VK_ARM_GOT_PREL:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46319.144732.patch
Type: text/x-patch
Size: 1641 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180501/05ca0621/attachment.bin>


More information about the llvm-commits mailing list