Page MenuHomePhabricator

[MC][ELF][ARM] Add relocations for some ARM pc-relative fixups.
Needs ReviewPublic

Authored by psmith on Feb 28 2020, 5:38 AM.

Details

Summary

Add ELF relocations for the following fixups:

  • fixup_arm_ldst_pcrel_12 -> R_ARM_LDR_PC_G0
  • fixup_arm_adr_pcrel_12 -> R_ARM_ALU_PC_G0

These relocations map to the pseudo instructions:

  • ldr rd, label
  • adr rd, label

They are short ranged and normally resolved by the fixup, however MC will no longer resolve the fixups to global symbols due to interpositioning concerns. We can handle these at link time by implementing the relocations.

This is the ARM equivalent of D75039, LLD patch implementing the relocations will be submitted later today.

Diff Detail

Event Timeline

psmith created this revision.Feb 28 2020, 5:38 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 28 2020, 5:38 AM
MaskRay edited reviewers, added: efriedma; removed: eli.friedman.Mar 1 2020, 5:07 PM
MaskRay added inline comments.Mar 1 2020, 5:09 PM
llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
140

From the fixup name it is hard to predicate the name of the relocation type. Does anyone know why?

psmith marked an inline comment as done.Mar 6 2020, 11:08 AM
psmith added inline comments.
llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
140

Apologies for the delay in responding. I missed the notification in the inbox. I don't have a particularly good answer, my guess is that there is a mix of ELF and MachO terminology from the assembler, with more of a slant towards MachO than ELF. The 12 will refer to the number of bits in the immediate.

The G0 is short for Group 0. The relocations while too short ranged to be useful on their own can be used in groups to load much more useful constants. The intention is to write something like the Arm PLT entry. In LLD we hard code the masks but in principle they can be calculated by relocations.

ADD ip, pc, #-8:PC_OFFSET_27_20: X ; R_ARM_ALU_PC_G0_NC(X)
ADD ip, ip, #-4:PC_OFFSET_19_12: X ; R_ARM_ALU_PC_G1_NC(X)
LDR pc, [ip, #0:PC_OFFSET_11_0: X]! ; R_ARM_LDR_PC_G2(X)

The G0 and G1 each take 8 bytes of the offset to X then LDR uses the bottom 12 for the offset. For example:

ip = pc + (X & 0x0ff00000)
ip = ip + (X & 0x000ff000)
pc = [ip + 0x00000fff]