Skip to content

Commit 31c8e11

Browse files
committed
[MC][ARM] Emit R_ARM_BASE_PREL for _GLOBAL_OFFSET_TABLE_ expressions
The _GLOBAL_OFFSET_TABLE_ in SysVr4 ELF is conventionally the base of the .got or .got.prel sections. Expressions such as _GLOBAL_OFFSET_TABLE_ - (.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, wheras te R_ARM_BASE_PREL relocation is idependent of the symbol. The R_ARM_BASE_PREL is therefore slightly more robust to linker's that may not follow the conventional placement of _GLOBAL_OFFSET_TABLE_; for example LLD for some time defined _GLOBAL_OFFSET_TABLE_ to 0. Differential Revision: https://reviews.llvm.org/D46319
1 parent e0dbd02 commit 31c8e11

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,15 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
9393
switch (Modifier) {
9494
default:
9595
llvm_unreachable("Unsupported Modifier");
96-
case MCSymbolRefExpr::VK_None:
96+
case MCSymbolRefExpr::VK_None: {
97+
if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
98+
// For GNU AS compatibility expressions such as
99+
// _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
100+
if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
101+
return ELF::R_ARM_BASE_PREL;
102+
}
97103
return ELF::R_ARM_REL32;
104+
}
98105
case MCSymbolRefExpr::VK_GOTTPOFF:
99106
return ELF::R_ARM_TLS_IE32;
100107
case MCSymbolRefExpr::VK_ARM_GOT_PREL:

llvm/test/MC/ARM/symbol-variants.s

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,16 @@ bl f05(plt)
9696
@CHECK: 70 R_ARM_TLS_LDM32 f28
9797
@CHECK: 74 R_ARM_TLS_LDM32 f29
9898

99+
@ relative
100+
.word f30 - (.Lsym+8)
101+
@CHECK: 78 R_ARM_REL32 f30
102+
103+
@ _GLOBAL_OFFSET_TABLE_ relative
104+
.word _GLOBAL_OFFSET_TABLE_ - (.Lsym+8)
105+
@CHECK: 7c R_ARM_BASE_PREL _GLOBAL_OFFSET_TABLE_
106+
99107
@ got_prel
100-
.word f30(GOT_PREL) + (. - .Lsym)
101-
ldr r3, =f31(GOT_PREL)
102-
@ CHECK: 78 R_ARM_GOT_PREL f30
103-
@ CHECK: 80 R_ARM_GOT_PREL f31
108+
.word f31(GOT_PREL) + (. - .Lsym)
109+
ldr r3, =f32(GOT_PREL)
110+
@CHECK: 80 R_ARM_GOT_PREL f31
111+
@CHECK: 88 R_ARM_GOT_PREL f32

0 commit comments

Comments
 (0)