@@ -171,7 +171,14 @@ enum EdgeKind_aarch64 : Edge::Kind {
171171 // /
172172 // / Fixup expression:
173173 // /
174- // / Fixup <- (Target - Fixup) >> 2 : int19
174+ // / Fixup <- (Target - Fixup + Addend) >> 2 : int19
175+ // /
176+ // / Notes:
177+ // / The '19' in the name refers to the number operand bits and follows the
178+ // / naming convention used by the corresponding ELF relocation.
179+ // / Since the low two bits must be zero (because of the 32-bit alignment of
180+ // / the target) the operand is effectively a signed 21-bit number.
181+ // /
175182 // /
176183 // / Errors:
177184 // / - The result of the unshifted part of the fixup expression must be
@@ -377,6 +384,11 @@ inline bool isADR(uint32_t Instr) {
377384 return (Instr & ADRMask) == 0x10000000 ;
378385}
379386
387+ inline bool isLDRLiteral (uint32_t Instr) {
388+ constexpr uint32_t LDRLitMask = 0x3b000000 ;
389+ return (Instr & LDRLitMask) == 0x18000000 ;
390+ }
391+
380392// Returns the amount the address operand of LD/ST (imm12)
381393// should be shifted right by.
382394//
@@ -494,16 +506,14 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) {
494506 }
495507 case LDRLiteral19: {
496508 assert ((FixupAddress.getValue () & 0x3 ) == 0 && " LDR is not 32-bit aligned" );
497- assert (E.getAddend () == 0 && " LDRLiteral19 with non-zero addend" );
498509 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
499- assert (RawInstr == 0x58000010 && " RawInstr isn't a 64-bit LDR literal " );
500- int64_t Delta = E.getTarget ().getAddress () - FixupAddress;
510+ assert (isLDRLiteral ( RawInstr) && " RawInstr is not an LDR Literal " );
511+ int64_t Delta = E.getTarget ().getAddress () + E. getAddend () - FixupAddress;
501512 if (Delta & 0x3 )
502513 return make_error<JITLinkError>(" LDR literal target is not 32-bit "
503514 " aligned" );
504- if (Delta < -( 1 << 20 ) || Delta > (( 1 << 20 ) - 1 ))
515+ if (!isInt< 21 >(Delta ))
505516 return makeTargetOutOfRangeError (G, B, E);
506-
507517 uint32_t EncodedImm = ((static_cast <uint32_t >(Delta) >> 2 ) & 0x7ffff ) << 5 ;
508518 uint32_t FixedInstr = RawInstr | EncodedImm;
509519 *(ulittle32_t *)FixupPtr = FixedInstr;
0 commit comments