1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[JITLink] Add support for MachO/x86-64 UNSIGNED relocs with length=2.

MachO/x86-64 UNSIGNED relocs are almost always 64-bit (length=3), but UNSIGNED
relocs of length=2 are allowed if the target resides in the low 32-bits. This
patch adds support for such relocations in JITLink (previously they would have
triggered an unsupported relocation error).

llvm-svn: 367764
This commit is contained in:
Lang Hames 2019-08-03 20:17:10 +00:00
parent 67654ccd88
commit 06b5e41b2a
3 changed files with 42 additions and 12 deletions

View File

@ -22,6 +22,7 @@ namespace MachO_x86_64_Edges {
enum MachOX86RelocationKind : Edge::Kind {
Branch32 = Edge::FirstRelocation,
Pointer32,
Pointer64,
Pointer64Anon,
PCRel32,

View File

@ -40,8 +40,12 @@ private:
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)
@ -260,6 +264,13 @@ private:
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;
@ -526,6 +537,13 @@ private:
*(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");
}
@ -565,6 +583,8 @@ StringRef getMachOX86RelocationKindName(Edge::Kind R) {
switch (R) {
case Branch32:
return "Branch32";
case Pointer32:
return "Pointer32";
case Pointer64:
return "Pointer64";
case Pointer64Anon:

View File

@ -154,22 +154,31 @@ named_data:
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