[LLVMdev] [RFC PATCH 2/2] x86: First attempt at supporting reloc_signed_2byte
David Woodhouse
dwmw2 at infradead.org
Thu Dec 12 08:54:46 PST 2013
Although this fixes all the test cases I've tested with so far, this is
almost certainly broken in a number of cases where the *signedness*
matters. Could really do with some help from someone with a bit more
clue about the details...
diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index ab95eb6..24c2bb1 100644
--- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -42,6 +42,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
case FK_SecRel_1:
case FK_Data_1: return 0;
case FK_PCRel_2:
+ case X86::reloc_signed_2byte:
case FK_SecRel_2:
case FK_Data_2: return 1;
case FK_PCRel_4:
@@ -88,6 +89,7 @@ public:
{ "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel },
{ "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel},
{ "reloc_signed_4byte", 0, 4 * 8, 0},
+ { "reloc_signed_2byte", 0, 2 * 8, 0},
{ "reloc_global_offset_table", 0, 4 * 8, 0}
};
diff --git a/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 3ddd865..c1be5ba 100644
--- a/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -89,6 +89,7 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
break;
}
break;
+ case X86::reloc_signed_2byte:
case FK_PCRel_2:
assert(Modifier == MCSymbolRefExpr::VK_None);
Type = ELF::R_X86_64_PC16;
@@ -146,6 +147,15 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
case FK_Data_4:
Type = ELF::R_X86_64_32;
break;
+ case X86::reloc_signed_2byte:
+ switch (Modifier) {
+ default:
+ llvm_unreachable("Unimplemented");
+ case MCSymbolRefExpr::VK_None:
+ Type = ELF::R_X86_64_16;
+ break;
+ }
+ break;
case FK_Data_2: Type = ELF::R_X86_64_16; break;
case FK_PCRel_1:
case FK_Data_1: Type = ELF::R_X86_64_8; break;
@@ -226,6 +236,7 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
break;
}
break;
+ case X86::reloc_signed_2byte:
case FK_Data_2: Type = ELF::R_386_16; break;
case FK_PCRel_1:
case FK_Data_1: Type = ELF::R_386_8; break;
diff --git a/lib/Target/X86/MCTargetDesc/X86FixupKinds.h b/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
index f2e34cb..6ea3d70 100644
--- a/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
+++ b/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
@@ -20,6 +20,9 @@ enum Fixups {
reloc_signed_4byte, // 32-bit signed. Unlike FK_Data_4
// this will be sign extended at
// runtime.
+ reloc_signed_2byte, // 16-bit signed. Unlike FK_Data_2
+ // this will be sign extended at
+ // runtime.
reloc_global_offset_table, // 32-bit, relative to the start
// of the instruction. Used only
// for _GLOBAL_OFFSET_TABLE_.
diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 12a30cf..3f7ed26 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -321,7 +321,8 @@ EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
// If we have an immoffset, add it to the expression.
if ((FixupKind == FK_Data_4 ||
FixupKind == FK_Data_8 ||
- FixupKind == MCFixupKind(X86::reloc_signed_4byte))) {
+ FixupKind == MCFixupKind(X86::reloc_signed_4byte) ||
+ FixupKind == MCFixupKind(X86::reloc_signed_2byte))) {
GlobalOffsetTableExprKind Kind = StartsWithGlobalOffsetTable(Expr);
if (Kind != GOT_None) {
assert(ImmOffset == 0);
@@ -331,13 +332,13 @@ EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
ImmOffset = CurByte;
} else if (Expr->getKind() == MCExpr::SymbolRef) {
if (HasSecRelSymbolRef(Expr)) {
- FixupKind = MCFixupKind(FK_SecRel_4);
+ FixupKind = MCFixupKind(Size == 2 ? FK_SecRel_2 : FK_SecRel_4);
}
} else if (Expr->getKind() == MCExpr::Binary) {
const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr*>(Expr);
if (HasSecRelSymbolRef(Bin->getLHS())
|| HasSecRelSymbolRef(Bin->getRHS())) {
- FixupKind = MCFixupKind(FK_SecRel_4);
+ FixupKind = MCFixupKind(Size == 2 ? FK_SecRel_2 : FK_SecRel_4);
}
}
}
@@ -445,10 +446,9 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
EmitByte(ModRMByte(0, RegOpcodeField, 6), CurByte, OS);
}
- // FIXME: Yes we can!
- assert(Disp.isImm() && "cannot emit 16-bit relocation");
// Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases.
- EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups);
+ EmitImmediate(Disp, MI.getLoc(), 2, MCFixupKind(X86::reloc_signed_2byte), CurByte, OS,
+ Fixups);
return;
}
diff --git a/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
index 0f16621..8a9ac87 100644
--- a/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
@@ -86,6 +86,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
case FK_PCRel_1:
case FK_Data_1: return 0;
case FK_PCRel_2:
+ case X86::reloc_signed_2byte:
case FK_Data_2: return 1;
case FK_PCRel_4:
// FIXME: Remove these!!!
@@ -336,6 +337,9 @@ void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,
if (Kind == X86::reloc_signed_4byte)
report_fatal_error("32-bit absolute addressing is not supported in "
"64-bit mode", false);
+ else if (Kind == X86::reloc_signed_2byte)
+ report_fatal_error("16-bit absolute addressing is not supported in "
+ "64-bit mode", false);
}
}
}
--
1.8.3.1
--
David Woodhouse Open Source Technology Centre
David.Woodhouse at intel.com Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131212/8c42a15f/attachment.bin>
More information about the llvm-dev
mailing list