mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 00:21:03 +00:00
MC/Mach-O/x86_64: Darwin's special "signed_N" relocation types should only be
used to replace a normal relocation, not a reference to a GOT entry. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103789 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -609,10 +609,31 @@ public:
|
||||
Type = RIT_X86_64_GOTLoad;
|
||||
else
|
||||
Type = RIT_X86_64_GOT;
|
||||
} else if (Modifier != MCSymbolRefExpr::VK_None)
|
||||
} else if (Modifier != MCSymbolRefExpr::VK_None) {
|
||||
report_fatal_error("unsupported symbol modifier in relocation");
|
||||
else
|
||||
} else {
|
||||
Type = RIT_X86_64_Signed;
|
||||
|
||||
// The Darwin x86_64 relocation format has a problem where it cannot
|
||||
// encode an address (L<foo> + <constant>) which is outside the atom
|
||||
// containing L<foo>. Generally, this shouldn't occur but it does
|
||||
// happen when we have a RIPrel instruction with data following the
|
||||
// relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel
|
||||
// adjustment Darwin x86_64 uses, the offset is still negative and
|
||||
// the linker has no way to recognize this.
|
||||
//
|
||||
// To work around this, Darwin uses several special relocation types
|
||||
// to indicate the offsets. However, the specification or
|
||||
// implementation of these seems to also be incomplete; they should
|
||||
// adjust the addend as well based on the actual encoded instruction
|
||||
// (the additional bias), but instead appear to just look at the
|
||||
// final offset.
|
||||
switch (-(Target.getConstant() + (1LL << Log2Size))) {
|
||||
case 1: Type = RIT_X86_64_Signed1; break;
|
||||
case 2: Type = RIT_X86_64_Signed2; break;
|
||||
case 4: Type = RIT_X86_64_Signed4; break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Modifier != MCSymbolRefExpr::VK_None)
|
||||
report_fatal_error("unsupported symbol modifier in branch "
|
||||
@@ -620,27 +641,6 @@ public:
|
||||
|
||||
Type = RIT_X86_64_Branch;
|
||||
}
|
||||
|
||||
// The Darwin x86_64 relocation format has a problem where it cannot
|
||||
// encode an address (L<foo> + <constant>) which is outside the atom
|
||||
// containing L<foo>. Generally, this shouldn't occur but it does happen
|
||||
// when we have a RIPrel instruction with data following the relocation
|
||||
// entry (e.g., movb $012, L0(%rip)). Even with the PCrel adjustment
|
||||
// Darwin x86_64 uses, the offset is still negative and the linker has
|
||||
// no way to recognize this.
|
||||
//
|
||||
// To work around this, Darwin uses several special relocation types to
|
||||
// indicate the offsets. However, the specification or implementation of
|
||||
// these seems to also be incomplete; they should adjust the addend as
|
||||
// well based on the actual encoded instruction (the additional bias),
|
||||
// but instead appear to just look at the final offset.
|
||||
if (IsRIPRel) {
|
||||
switch (-(Target.getConstant() + (1LL << Log2Size))) {
|
||||
case 1: Type = RIT_X86_64_Signed1; break;
|
||||
case 2: Type = RIT_X86_64_Signed2; break;
|
||||
case 4: Type = RIT_X86_64_Signed4; break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Modifier == MCSymbolRefExpr::VK_GOT) {
|
||||
Type = RIT_X86_64_GOT;
|
||||
|
Reference in New Issue
Block a user