1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

X86: produce more friendly errors during MachO relocation handling

llvm-svn: 255036
This commit is contained in:
Tim Northover 2015-12-08 18:31:35 +00:00
parent 119a82eabd
commit db905d06b1
3 changed files with 94 additions and 32 deletions

View File

@ -149,14 +149,19 @@ void X86MachObjectWriter::RecordX86_64Relocation(
// Neither symbol can be modified. // Neither symbol can be modified.
if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None || if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None ||
Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) {
report_fatal_error("unsupported relocation of modified symbol", false); Asm.getContext().reportError(Fixup.getLoc(),
"unsupported relocation of modified symbol");
return;
}
// We don't support PCrel relocations of differences. Darwin 'as' doesn't // We don't support PCrel relocations of differences. Darwin 'as' doesn't
// implement most of these correctly. // implement most of these correctly.
if (IsPCRel) if (IsPCRel) {
report_fatal_error("unsupported pc-relative relocation of difference", Asm.getContext().reportError(
false); Fixup.getLoc(), "unsupported pc-relative relocation of difference");
return;
}
// The support for the situation where one or both of the symbols would // The support for the situation where one or both of the symbols would
// require a local relocation is handled just like if the symbols were // require a local relocation is handled just like if the symbols were
@ -168,8 +173,11 @@ void X86MachObjectWriter::RecordX86_64Relocation(
// Darwin 'as' doesn't emit correct relocations for this (it ends up with a // Darwin 'as' doesn't emit correct relocations for this (it ends up with a
// single SIGNED relocation); reject it for now. Except the case where both // single SIGNED relocation); reject it for now. Except the case where both
// symbols don't have a base, equal but both NULL. // symbols don't have a base, equal but both NULL.
if (A_Base == B_Base && A_Base) if (A_Base == B_Base && A_Base) {
report_fatal_error("unsupported relocation with identical base", false); Asm.getContext().reportError(
Fixup.getLoc(), "unsupported relocation with identical base");
return;
}
// A subtraction expression where either symbol is undefined is a // A subtraction expression where either symbol is undefined is a
// non-relocatable expression. // non-relocatable expression.
@ -245,12 +253,16 @@ void X86MachObjectWriter::RecordX86_64Relocation(
FixedValue = Res; FixedValue = Res;
return; return;
} else { } else {
report_fatal_error("unsupported relocation of variable '" + Asm.getContext().reportError(Fixup.getLoc(),
Symbol->getName() + "'", false); "unsupported relocation of variable '" +
Symbol->getName() + "'");
return;
} }
} else { } else {
report_fatal_error("unsupported relocation of undefined symbol '" + Asm.getContext().reportError(
Symbol->getName() + "'", false); Fixup.getLoc(), "unsupported relocation of undefined symbol '" +
Symbol->getName() + "'");
return;
} }
MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
@ -267,8 +279,9 @@ void X86MachObjectWriter::RecordX86_64Relocation(
} else if (Modifier == MCSymbolRefExpr::VK_TLVP) { } else if (Modifier == MCSymbolRefExpr::VK_TLVP) {
Type = MachO::X86_64_RELOC_TLV; Type = MachO::X86_64_RELOC_TLV;
} else if (Modifier != MCSymbolRefExpr::VK_None) { } else if (Modifier != MCSymbolRefExpr::VK_None) {
report_fatal_error("unsupported symbol modifier in relocation", Asm.getContext().reportError(
false); Fixup.getLoc(), "unsupported symbol modifier in relocation");
return;
} else { } else {
Type = MachO::X86_64_RELOC_SIGNED; Type = MachO::X86_64_RELOC_SIGNED;
@ -293,9 +306,12 @@ void X86MachObjectWriter::RecordX86_64Relocation(
} }
} }
} else { } else {
if (Modifier != MCSymbolRefExpr::VK_None) if (Modifier != MCSymbolRefExpr::VK_None) {
report_fatal_error("unsupported symbol modifier in branch " Asm.getContext().reportError(
"relocation", false); Fixup.getLoc(),
"unsupported symbol modifier in branch relocation");
return;
}
Type = MachO::X86_64_RELOC_BRANCH; Type = MachO::X86_64_RELOC_BRANCH;
} }
@ -310,16 +326,22 @@ void X86MachObjectWriter::RecordX86_64Relocation(
Type = MachO::X86_64_RELOC_GOT; Type = MachO::X86_64_RELOC_GOT;
IsPCRel = 1; IsPCRel = 1;
} else if (Modifier == MCSymbolRefExpr::VK_TLVP) { } else if (Modifier == MCSymbolRefExpr::VK_TLVP) {
report_fatal_error("TLVP symbol modifier should have been rip-rel", Asm.getContext().reportError(
false); Fixup.getLoc(), "TLVP symbol modifier should have been rip-rel");
} else if (Modifier != MCSymbolRefExpr::VK_None) return;
report_fatal_error("unsupported symbol modifier in relocation", false); } else if (Modifier != MCSymbolRefExpr::VK_None) {
else { Asm.getContext().reportError(
Fixup.getLoc(), "unsupported symbol modifier in relocation");
return;
} else {
Type = MachO::X86_64_RELOC_UNSIGNED; Type = MachO::X86_64_RELOC_UNSIGNED;
unsigned Kind = Fixup.getKind(); unsigned Kind = Fixup.getKind();
if (Kind == X86::reloc_signed_4byte) if (Kind == X86::reloc_signed_4byte) {
report_fatal_error("32-bit absolute addressing is not supported in " Asm.getContext().reportError(
"64-bit mode", false); Fixup.getLoc(),
"32-bit absolute addressing is not supported in 64-bit mode");
return;
}
} }
} }
} }
@ -351,10 +373,13 @@ bool X86MachObjectWriter::recordScatteredRelocation(MachObjectWriter *Writer,
// See <reloc.h>. // See <reloc.h>.
const MCSymbol *A = &Target.getSymA()->getSymbol(); const MCSymbol *A = &Target.getSymA()->getSymbol();
if (!A->getFragment()) if (!A->getFragment()) {
report_fatal_error("symbol '" + A->getName() + Asm.getContext().reportError(
"' can not be undefined in a subtraction expression", Fixup.getLoc(),
false); "symbol '" + A->getName() +
"' can not be undefined in a subtraction expression");
return false;
}
uint32_t Value = Writer->getSymbolAddress(*A, Layout); uint32_t Value = Writer->getSymbolAddress(*A, Layout);
uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent()); uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent());
@ -364,10 +389,13 @@ bool X86MachObjectWriter::recordScatteredRelocation(MachObjectWriter *Writer,
if (const MCSymbolRefExpr *B = Target.getSymB()) { if (const MCSymbolRefExpr *B = Target.getSymB()) {
const MCSymbol *SB = &B->getSymbol(); const MCSymbol *SB = &B->getSymbol();
if (!SB->getFragment()) if (!SB->getFragment()) {
report_fatal_error("symbol '" + B->getSymbol().getName() + Asm.getContext().reportError(
"' can not be undefined in a subtraction expression", Fixup.getLoc(),
false); "symbol '" + B->getSymbol().getName() +
"' can not be undefined in a subtraction expression");
return false;
}
// Select the appropriate difference relocation type. // Select the appropriate difference relocation type.
// //

View File

@ -0,0 +1,15 @@
// RUN: not llvm-mc -triple=i686-apple-darwin -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
.space 0x1000000
mov %eax, thing-thing2
mov %eax, defined-thing2
mov %eax, later-defined
.section __DATA,__tim
defined:
.section __DATA,__tim2
later:
// CHECK-ERROR: 3:9: error: symbol 'thing' can not be undefined in a subtraction expression
// CHECK-ERROR: 4:9: error: symbol 'thing2' can not be undefined in a subtraction expression
// CHECK-ERROR: 5:9: error: Section too large, can't encode r_address (0x100000b) into 24 bits of scattered relocation entry.

View File

@ -0,0 +1,19 @@
// RUN: not llvm-mc -triple=x86_64-apple-darwin -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
mov %rax, thing
mov %rax, thing@GOT-thing2@GOT
mov %rax, (thing-thing2)(%rip)
mov %rax, thing-thing
mov %rax, thing-thing2
mov %rax, thing@PLT
jmp thing@PLT
mov %rax, thing@TLVP
// CHECK-ERROR: 3:9: error: 32-bit absolute addressing is not supported in 64-bit mode
// CHECK-ERROR: 4:9: error: unsupported relocation of modified symbol
// CHECK-ERROR: 5:9: error: unsupported pc-relative relocation of difference
// CHECK-ERROR: 6:9: error: unsupported relocation with identical base
// CHECK-ERROR: 7:9: error: unsupported relocation with subtraction expression, symbol 'thing' can not be undefined in a subtraction expression
// CHECK-ERROR: 8:9: error: unsupported symbol modifier in relocation
// CHECK-ERROR: 9:9: error: unsupported symbol modifier in branch relocation
// CHECK-ERROR: 10:9: error: TLVP symbol modifier should have been rip-rel