This is an archive of the discontinued LLVM Phabricator instance.

[MC][ARM] Emit R_ARM_BASE_PREL for _GLOBAL_OFFSET_TABLE_ expressions
ClosedPublic

Authored by peter.smith on May 1 2018, 9:11 AM.

Details

Summary

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, 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

Diff Detail

Event Timeline

peter.smith created this revision.May 1 2018, 9:11 AM
MaskRay accepted this revision.Apr 12 2020, 11:21 PM
MaskRay added a subscriber: MaskRay.

This patch still applies. This is similar to D47507 (x86).

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.

Agree that this is slightly more robust. We may not need to worry much about the cases when _GLOBAL_OFFSET_TABLE_ is missing in the symbol table, because glibc crti.o (sysdeps/arm/crti.S) references it:

.word _GLOBAL_OFFSET_TABLE_-(.LPIC+8)
This revision is now accepted and ready to land.Apr 12 2020, 11:21 PM

Thanks for the review, will retest and commit tomorrow (public holiday in UK today)

This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptApr 14 2020, 3:09 AM
Herald added a subscriber: hiraditya. · View Herald Transcript