This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELF][ARM] Implement Thumb pc-relative relocations for adr and ldr
ClosedPublic

Authored by psmith on Feb 24 2020, 4:59 AM.

Details

Summary

MC if D75039 is accepted will output the R_ARM_THM_PC8, R_ARM_THM_PC12 and R_ARM_THM_PREL_11_0 relocations. These are short-ranged relocations that are used to implement the adr rd, literal and ldr rd, literal pseudo instructions.

The instructions use a new RelExpr called R_ARM_PCA in order to calculate the required S + A - Pa expression, where Pa is AlignDown(P, 4) as the instructions add their immediate to AlignDown(PC, 4). We also do not want these relocations to generate or resolve against a PLT entry as the range of these relocations (4095 bytes) is so short they would never reach.

The R_ARM_THM_PC8 has a special encoding convention for the relocation addend, the immediate field is unsigned, yet the addend must be -4 to account for the Thumb PC bias. The ABI (not the architecture) uses the convention that the 8-byte immediate of 0xff represents -4.

References:

In particular: F5.1.73 LDR (literal) and F5.1.10 ADR

Fixes part of pr 44929 https://bugs.llvm.org/show_bug.cgi?id=44929

TODO:

  • Implement the ARM state pc-relative relocations in both MC and LLD

Diff Detail

Event Timeline

psmith created this revision.Feb 24 2020, 4:59 AM
MaskRay added inline comments.Feb 24 2020, 4:54 PM
lld/ELF/Arch/ARM.cpp
596

I believe rel.sym is never nullptr, even if ELF32_R_SYM(r) is 0.

The field Relocation::sym is a pointer to:

Symbol &sym = file->getRelocTargetSym(rel);
608

ditto

lld/test/ELF/arm-thumb-adr-err.s
3

Is --nmagic (-n) needed?

lld/test/ELF/arm-thumb2-adr-err.s
3

%t -> /dev/null

Delete -n

lld/test/ELF/arm-thumb2-ldrlit.s
11

Delete -n (--nmagic)

psmith updated this revision to Diff 246461.Feb 25 2020, 7:46 AM

Thanks for the comments, I've removed the checks for Symbol being nullptr, these could exist if we were to call with relocateNoSym, but we don't do that at present. Removed -n and used /dev/null in all error tests.

MaskRay added inline comments.Feb 25 2020, 10:52 PM
lld/test/ELF/arm-thumb2-adr.s
22

Should dat1 data2 ... be global?

psmith marked an inline comment as done.Feb 26 2020, 2:48 AM
psmith added inline comments.
lld/test/ELF/arm-thumb2-adr.s
22

They don't need to be global as they are in a different section to the adr. The assembler can only resolve an adr if the destination is in the same section. Happy to change it if you prefer.

MaskRay accepted this revision.Feb 26 2020, 8:37 AM
This revision is now accepted and ready to land.Feb 26 2020, 8:37 AM
This revision was automatically updated to reflect the committed changes.