Skip to content

Commit 1fc8d94

Browse files
[JITLink][AArch32] Implement R_ARM_PREL31 and stop skipping .ARM.exidx sections (wip)
1 parent 14ec373 commit 1fc8d94

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ enum EdgeKind_aarch32 : Edge::Kind {
4141
/// Absolute 32-bit value relocation
4242
Data_Pointer32,
4343

44+
Data_PRel31,
45+
4446
/// Create GOT entry and store offset
4547
Data_RequestGOTAndTransformToDelta32,
4648

llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ getJITLinkEdgeKind(uint32_t ELFType, const aarch32::ArmConfig &ArmCfg) {
5050
return aarch32::Arm_MovtAbs;
5151
case ELF::R_ARM_NONE:
5252
return aarch32::None;
53+
case ELF::R_ARM_PREL31:
54+
return aarch32::Data_PRel31;
5355
case ELF::R_ARM_TARGET1:
5456
return (ArmCfg.Target1Rel) ? aarch32::Data_Delta32
5557
: aarch32::Data_Pointer32;
@@ -79,6 +81,8 @@ Expected<uint32_t> getELFRelocationType(Edge::Kind Kind) {
7981
return ELF::R_ARM_REL32;
8082
case aarch32::Data_Pointer32:
8183
return ELF::R_ARM_ABS32;
84+
case aarch32::Data_PRel31:
85+
return ELF::R_ARM_PREL31;
8286
case aarch32::Data_RequestGOTAndTransformToDelta32:
8387
return ELF::R_ARM_GOT_PREL;
8488
case aarch32::Arm_Call:
@@ -147,6 +151,15 @@ class ELFLinkGraphBuilder_aarch32
147151
// Handling ABI for the Arm® Architecture -> Index table entries
148152
if (Sect.sh_type == ELF::SHT_ARM_EXIDX)
149153
return true;
154+
// Skip .ARM.extab sections. They are only ever referenced from .ARM.exidx,
155+
// i.e. when unwind instructions don't fit into 4 bytes.
156+
if (Sect.sh_type == ELF::SHT_PROGBITS && (Sect.sh_flags & ELF::SHF_ALLOC)) {
157+
if (Sect.sh_name && Sect.sh_name < Base::SectionStringTab.size()) {
158+
StringRef SectionName = Base::SectionStringTab.data() + Sect.sh_name;
159+
if (SectionName.starts_with(".ARM.extab"))
160+
return true;
161+
}
162+
}
150163
return false;
151164
}
152165

llvm/lib/ExecutionEngine/JITLink/aarch32.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
398398
case Data_Pointer32:
399399
case Data_RequestGOTAndTransformToDelta32:
400400
return SignExtend64<32>(support::endian::read32(FixupPtr, Endian));
401+
case Data_PRel31:
402+
return SignExtend64<31>(support::endian::read32(FixupPtr, Endian));
401403
default:
402404
return make_error<JITLinkError>(
403405
"In graph " + G.getName() + ", section " + B.getSection().getName() +
@@ -472,9 +474,8 @@ Error applyFixupData(LinkGraph &G, Block &B, const Edge &E) {
472474
Symbol &TargetSymbol = E.getTarget();
473475
uint64_t TargetAddress = TargetSymbol.getAddress().getValue();
474476

475-
// Regular data relocations have size 4, alignment 1 and write the full 32-bit
476-
// result to the place; no need for overflow checking. There are three
477-
// exceptions: R_ARM_ABS8, R_ARM_ABS16, R_ARM_PREL31
477+
// Data relocations have alignment 1, size 4 (except R_ARM_ABS8 and
478+
// R_ARM_ABS16) and write the full 32-bit result (except R_ARM_PREL31).
478479
switch (Kind) {
479480
case Data_Delta32: {
480481
int64_t Value = TargetAddress - FixupAddress + Addend;
@@ -496,6 +497,19 @@ Error applyFixupData(LinkGraph &G, Block &B, const Edge &E) {
496497
endian::write32be(FixupPtr, Value);
497498
return Error::success();
498499
}
500+
case Data_PRel31: {
501+
int64_t Value = TargetAddress - FixupAddress + Addend;
502+
if (!isInt<31>(Value))
503+
return makeTargetOutOfRangeError(G, B, E);
504+
if (LLVM_LIKELY(G.getEndianness() == endianness::little)) {
505+
uint32_t MSB = endian::read32le(FixupPtr) & 0x80000000;
506+
endian::write32le(FixupPtr, MSB | (Value & ~0x80000000));
507+
} else {
508+
uint32_t MSB = endian::read32be(FixupPtr) & 0x80000000;
509+
endian::write32be(FixupPtr, MSB | (Value & ~0x80000000));
510+
}
511+
return Error::success();
512+
}
499513
case Data_RequestGOTAndTransformToDelta32:
500514
llvm_unreachable("Should be transformed");
501515
default:
@@ -856,6 +870,7 @@ const char *getEdgeKindName(Edge::Kind K) {
856870
switch (K) {
857871
KIND_NAME_CASE(Data_Delta32)
858872
KIND_NAME_CASE(Data_Pointer32)
873+
KIND_NAME_CASE(Data_PRel31)
859874
KIND_NAME_CASE(Data_RequestGOTAndTransformToDelta32)
860875
KIND_NAME_CASE(Arm_Call)
861876
KIND_NAME_CASE(Arm_Jump24)

llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_data.s

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,35 @@ got_prel_offset:
5757
.size got_prel_offset, .-got_prel_offset
5858
.size got_prel, .-got_prel
5959

60+
# Dummy personality routine. It will be referenced from .ARM.exidx
61+
# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_NONE __aeabi_unwind_cpp_pr0
62+
.globl __aeabi_unwind_cpp_pr0
63+
.type __aeabi_unwind_cpp_pr0,%function
64+
.align 2
65+
__aeabi_unwind_cpp_pr0:
66+
bx lr
67+
68+
# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_PREL31 .text
69+
#
70+
# Used in the .ARM.exidx exception tables. The linker must preserve the most-
71+
# significant bit. It denotes whether the field is an inline entry (1) or a
72+
# relocation (0).
73+
#
74+
# jitlink-check: *{4}(section_addr(out.o, .ARM.exidx)) = (prel31 - (section_addr(out.o, .ARM.exidx))) & 0x7fffffff
75+
.globl prel31
76+
.type prel31,%function
77+
.align 2
78+
prel31:
79+
.fnstart
80+
.save {r11, lr}
81+
push {r11, lr}
82+
.setfp r11, sp
83+
mov r11, sp
84+
pop {r11, lr}
85+
mov pc, lr
86+
.size prel31,.-prel31
87+
.fnend
88+
6089
# This test is executable with any 4-byte external target:
6190
# > echo "unsigned target = 42;" | clang -target armv7-linux-gnueabihf -o target.o -c -xc -
6291
# > llvm-jitlink target.o armv7/out.o
@@ -67,5 +96,6 @@ got_prel_offset:
6796
main:
6897
push {lr}
6998
bl got_prel
99+
bl prel31
70100
pop {pc}
71101
.size main, .-main

0 commit comments

Comments
 (0)