getRelocationKind(const MachO::relocation_info &RI) {
switch (RI.r_type) {
case MachO::X86_64_RELOC_UNSIGNED:
- if (!RI.r_pcrel && RI.r_length == 3)
- return RI.r_extern ? Pointer64 : Pointer64Anon;
+ if (!RI.r_pcrel) {
+ if (RI.r_length == 3)
+ return RI.r_extern ? Pointer64 : Pointer64Anon;
+ else if (RI.r_extern && RI.r_length == 2)
+ return Pointer32;
+ }
break;
case MachO::X86_64_RELOC_SIGNED:
if (RI.r_pcrel && RI.r_length == 2)
return TargetAtomOrErr.takeError();
Addend = *(const ulittle32_t *)FixupContent;
break;
+ case Pointer32:
+ if (auto TargetAtomOrErr = findAtomBySymbolIndex(RI))
+ TargetAtom = &*TargetAtomOrErr;
+ else
+ return TargetAtomOrErr.takeError();
+ Addend = *(const ulittle32_t *)FixupContent;
+ break;
case Pointer64:
if (auto TargetAtomOrErr = findAtomBySymbolIndex(RI))
TargetAtom = &*TargetAtomOrErr;
*(little64_t *)FixupPtr = Value;
break;
}
+ case Pointer32: {
+ uint64_t Value = E.getTarget().getAddress() + E.getAddend();
+ if (Value > std::numeric_limits<uint32_t>::max())
+ return targetOutOfRangeError(A, E);
+ *(ulittle32_t *)FixupPtr = Value;
+ break;
+ }
default:
llvm_unreachable("Unrecognized edge kind");
}
switch (R) {
case Branch32:
return "Branch32";
+ case Pointer32:
+ return "Pointer32";
case Pointer64:
return "Pointer64";
case Pointer64Anon:
named_data_alt_entry:
.quad 0
-# Check X86_64_RELOC_UNSIGNED / extern handling by putting the address of a
-# local named function in a pointer variable.
+# Check X86_64_RELOC_UNSIGNED / quad / extern handling by putting the address of
+# a local named function into a quad symbol.
#
-# jitlink-check: *{8}named_func_addr = named_func
- .globl named_func_addr
+# jitlink-check: *{8}named_func_addr_quad = named_func
+ .globl named_func_addr_quad
.p2align 3
-named_func_addr:
+named_func_addr_quad:
.quad named_func
-# Check X86_64_RELOC_UNSIGNED / non-extern handling by putting the address of a
-# local anonymous function in a pointer variable.
+# Check X86_64_RELOC_UNSIGNED / long / extern handling by putting the address of
+# an external function (defined to reside in the low 4Gb) into a long symbol.
#
-# jitlink-check: *{8}anon_func_addr = section_addr(macho_reloc.o, __text)
- .globl anon_func_addr
+# jitlink-check: *{8}named_func_addr_long = external_func
+ .globl named_func_addr_long
+ .p2align 2
+named_func_addr_long:
+ .long external_func
+
+# Check X86_64_RELOC_UNSIGNED / quad / non-extern handling by putting the
+# address of a local anonymous function into a quad symbol.
+#
+# jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __text)
+ .globl anon_func_addr_quad
.p2align 3
-anon_func_addr:
+anon_func_addr_quad:
.quad Lanon_func
# X86_64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend