Skip to content

[JITLink][AArch32] Add support for ELF::R_ARM_THM_MOV{W_PREL_NC,T_PREL} #70364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,15 @@ enum EdgeKind_aarch32 : Edge::Kind {
/// Write immediate value to the top halfword of the destination register
Thumb_MovtAbs,

LastThumbRelocation = Thumb_MovtAbs,
/// Write PC-relative immediate value to the lower halfword of the destination
/// register
Thumb_MovwPrelNC,

/// Write PC-relative immediate value to the top halfword of the destination
/// register
Thumb_MovtPrel,

LastThumbRelocation = Thumb_MovtPrel,
};

/// Flags enum for AArch32-specific symbol properties
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ Expected<aarch32::EdgeKind_aarch32> getJITLinkEdgeKind(uint32_t ELFType) {
return aarch32::Thumb_MovwAbsNC;
case ELF::R_ARM_THM_MOVT_ABS:
return aarch32::Thumb_MovtAbs;
case ELF::R_ARM_THM_MOVW_PREL_NC:
return aarch32::Thumb_MovwPrelNC;
case ELF::R_ARM_THM_MOVT_PREL:
return aarch32::Thumb_MovtPrel;
}

return make_error<JITLinkError>(
Expand Down Expand Up @@ -83,6 +87,10 @@ Expected<uint32_t> getELFRelocationType(Edge::Kind Kind) {
return ELF::R_ARM_THM_MOVW_ABS_NC;
case aarch32::Thumb_MovtAbs:
return ELF::R_ARM_THM_MOVT_ABS;
case aarch32::Thumb_MovwPrelNC:
return ELF::R_ARM_THM_MOVW_PREL_NC;
case aarch32::Thumb_MovtPrel:
return ELF::R_ARM_THM_MOVT_PREL;
}

return make_error<JITLinkError>(formatv("Invalid aarch32 edge {0:d}: ",
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,12 +377,14 @@ Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, const Edge &E,
: decodeImmBT4BlT1BlxT2(R.Hi, R.Lo);

case Thumb_MovwAbsNC:
case Thumb_MovwPrelNC:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were talking about the opcode checks and duplication in both, code and constants. I've been working on a patch to compensate for it here: #71649 With that the asymmetry in opcode checks will go away. I think we can land this as is.

if (!checkOpcode<Thumb_MovwAbsNC>(R))
return makeUnexpectedOpcodeError(G, R, Kind);
// Initial addend is interpreted as a signed value
return SignExtend64<16>(decodeImmMovtT1MovwT3(R.Hi, R.Lo));

case Thumb_MovtAbs:
case Thumb_MovtPrel:
if (!checkOpcode<Thumb_MovtAbs>(R))
return makeUnexpectedOpcodeError(G, R, Kind);
// Initial addend is interpreted as a signed value
Expand Down Expand Up @@ -610,6 +612,20 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
writeImmediate<Thumb_MovtAbs>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}
case Thumb_MovwPrelNC: {
if (!checkOpcode<Thumb_MovwAbsNC>(R))
return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = ((TargetAddress + Addend - FixupAddress) & 0xffff);
writeImmediate<Thumb_MovwAbsNC>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}
case Thumb_MovtPrel: {
if (!checkOpcode<Thumb_MovtAbs>(R))
return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = (((TargetAddress + Addend - FixupAddress) >> 16) & 0xffff);
writeImmediate<Thumb_MovtAbs>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}

default:
return make_error<JITLinkError>(
Expand Down Expand Up @@ -659,6 +675,8 @@ const char *getEdgeKindName(Edge::Kind K) {
KIND_NAME_CASE(Thumb_Jump24)
KIND_NAME_CASE(Thumb_MovwAbsNC)
KIND_NAME_CASE(Thumb_MovtAbs)
KIND_NAME_CASE(Thumb_MovwPrelNC)
KIND_NAME_CASE(Thumb_MovtPrel)
default:
return getGenericEdgeKindName(K);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# RUN: llvm-objdump -r %t.o | FileCheck --check-prefix=CHECK-TYPE %s
# RUN: llvm-objdump --disassemble %t.o | FileCheck --check-prefix=CHECK-INSTR %s
# RUN: llvm-jitlink -noexec -slab-address 0x76ff0000 -slab-allocate 10Kb \
# RUN: -slab-page-size 4096 -show-entry-es -check %s %t.o
# RUN: -slab-page-size 4096 -abs external_func=0x76bbe880 \
# RUN: -check %s %t.o


.text
Expand Down Expand Up @@ -95,6 +96,34 @@ data_symbol:

.text

# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_THM_MOVW_PREL_NC external_func
# CHECK-INSTR: 00000014 <movw_prel>:
# CHECK-INSTR: 14: f240 0000 movw r0, #0x0
# jitlink-check: decode_operand(movw_prel, 1) = \
# jitlink-check: ((external_func - movw_prel)&0x0000ffff)
.globl movw_prel
.type movw_prel,%function
.p2align 1
.code 16
.thumb_func
movw_prel:
movw r0, :lower16:external_func - .
.size movw_prel, .-movw_prel

# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_THM_MOVT_PREL external_func
# CHECK-INSTR: 00000018 <movt_prel>:
# CHECK-INSTR: 18: f2c0 0000 movt r0, #0x0
# jitlink-check: decode_operand(movt_prel, 2) = \
# jitlink-check: ((external_func - movt_prel)&0xffff0000>>16)
.globl movt_prel
.type movt_prel,%function
.p2align 1
.code 16
.thumb_func
movt_prel:
movt r0, :upper16:external_func - .
.size movt_prel, .-movt_prel

# Empty main function for jitlink to be happy
.globl main
.type main,%function
Expand Down