forked from OSchip/llvm-project
1427 lines
62 KiB
Diff
1427 lines
62 KiB
Diff
Index: include/llvm/ADT/PointerUnion.h
|
||
===================================================================
|
||
--- include/llvm/ADT/PointerUnion.h (revision 152265)
|
||
+++ include/llvm/ADT/PointerUnion.h (working copy)
|
||
@@ -266,7 +266,7 @@
|
||
::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
|
||
::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
|
||
>::Return Ty;
|
||
- return Ty(Val).is<T>();
|
||
+ return Ty(Val).template is<T>();
|
||
}
|
||
|
||
/// get<T>() - Return the value of the specified pointer type. If the
|
||
@@ -279,7 +279,7 @@
|
||
::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
|
||
::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
|
||
>::Return Ty;
|
||
- return Ty(Val).get<T>();
|
||
+ return Ty(Val).template get<T>();
|
||
}
|
||
|
||
/// dyn_cast<T>() - If the current value is of the specified pointer type,
|
||
Index: include/llvm/ADT/IntervalMap.h
|
||
===================================================================
|
||
--- include/llvm/ADT/IntervalMap.h (revision 152265)
|
||
+++ include/llvm/ADT/IntervalMap.h (working copy)
|
||
@@ -1977,7 +1977,7 @@
|
||
CurSize[Nodes] = CurSize[NewNode];
|
||
Node[Nodes] = Node[NewNode];
|
||
CurSize[NewNode] = 0;
|
||
- Node[NewNode] = this->map->newNode<NodeT>();
|
||
+ Node[NewNode] = this->map->template newNode<NodeT>();
|
||
++Nodes;
|
||
}
|
||
|
||
Index: utils/TableGen/X86RecognizableInstr.cpp
|
||
===================================================================
|
||
--- utils/TableGen/X86RecognizableInstr.cpp (revision 152265)
|
||
+++ utils/TableGen/X86RecognizableInstr.cpp (working copy)
|
||
@@ -405,13 +405,13 @@
|
||
return FILTER_STRONG;
|
||
|
||
|
||
- // Filter out artificial instructions
|
||
+ // Filter out artificial instructions but leave in the LOCK_PREFIX so it is
|
||
+ // printed as a separate "instruction".
|
||
|
||
if (Name.find("_Int") != Name.npos ||
|
||
Name.find("Int_") != Name.npos ||
|
||
Name.find("_NOREX") != Name.npos ||
|
||
- Name.find("2SDL") != Name.npos ||
|
||
- Name == "LOCK_PREFIX")
|
||
+ Name.find("2SDL") != Name.npos)
|
||
return FILTER_STRONG;
|
||
|
||
// Filter out instructions with segment override prefixes.
|
||
Index: lib/Target/ARM/ARMJITInfo.cpp
|
||
===================================================================
|
||
--- lib/Target/ARM/ARMJITInfo.cpp (revision 152265)
|
||
+++ lib/Target/ARM/ARMJITInfo.cpp (working copy)
|
||
@@ -61,7 +61,7 @@
|
||
// concerned, so we can't just preserve the callee saved regs.
|
||
"stmdb sp!, {r0, r1, r2, r3, lr}\n"
|
||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||
- "fstmfdd sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
||
+ "vstmdb sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
||
#endif
|
||
// The LR contains the address of the stub function on entry.
|
||
// pass it as the argument to the C part of the callback
|
||
@@ -85,7 +85,7 @@
|
||
//
|
||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||
// Restore VFP caller-saved registers.
|
||
- "fldmfdd sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
||
+ "vldmia sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
||
#endif
|
||
//
|
||
// We need to exchange the values in slots 0 and 1 so we can
|
||
Index: lib/Target/ARM/ARMInstrNEON.td
|
||
===================================================================
|
||
--- lib/Target/ARM/ARMInstrNEON.td (revision 152265)
|
||
+++ lib/Target/ARM/ARMInstrNEON.td (working copy)
|
||
@@ -4795,12 +4795,12 @@
|
||
|
||
// Vector Swap
|
||
def VSWPd : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0,
|
||
- (outs DPR:$Vd, DPR:$Vd1), (ins DPR:$Vm, DPR:$Vm1),
|
||
- NoItinerary, "vswp", "$Vd, $Vd1", "$Vm = $Vd, $Vm1 = $Vd1",
|
||
+ (outs DPR:$Vd, DPR:$Vm), (ins DPR:$in1, DPR:$in2),
|
||
+ NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
|
||
[]>;
|
||
def VSWPq : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0,
|
||
- (outs QPR:$Vd, QPR:$Vd1), (ins QPR:$Vm, QPR:$Vm1),
|
||
- NoItinerary, "vswp", "$Vd, $Vd1", "$Vm = $Vd, $Vm1 = $Vd1",
|
||
+ (outs QPR:$Vd, QPR:$Vm), (ins QPR:$in1, QPR:$in2),
|
||
+ NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
|
||
[]>;
|
||
|
||
// Vector Move Operations.
|
||
Index: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
|
||
===================================================================
|
||
--- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (revision 152265)
|
||
+++ lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (working copy)
|
||
@@ -212,12 +212,12 @@
|
||
} else {
|
||
assert(Op.isExpr() && "unknown operand kind in printOperand");
|
||
// If a symbolic branch target was added as a constant expression then print
|
||
- // that address in hex.
|
||
+ // that address in hex. And only print 32 unsigned bits for the address.
|
||
const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
|
||
int64_t Address;
|
||
if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
|
||
O << "0x";
|
||
- O.write_hex(Address);
|
||
+ O.write_hex((uint32_t)Address);
|
||
}
|
||
else {
|
||
// Otherwise, just print the expression.
|
||
Index: lib/Target/ARM/ARMInstrThumb2.td
|
||
===================================================================
|
||
--- lib/Target/ARM/ARMInstrThumb2.td (revision 152265)
|
||
+++ lib/Target/ARM/ARMInstrThumb2.td (working copy)
|
||
@@ -3198,6 +3198,7 @@
|
||
let Inst{13} = target{17};
|
||
let Inst{21-16} = target{16-11};
|
||
let Inst{10-0} = target{10-0};
|
||
+ let DecoderMethod = "DecodeT2BInstruction";
|
||
}
|
||
|
||
let isNotDuplicable = 1, isIndirectBranch = 1 in {
|
||
Index: lib/Target/ARM/ARMInstrThumb.td
|
||
===================================================================
|
||
--- lib/Target/ARM/ARMInstrThumb.td (revision 152265)
|
||
+++ lib/Target/ARM/ARMInstrThumb.td (working copy)
|
||
@@ -413,11 +413,11 @@
|
||
"bl${p}\t$func",
|
||
[(ARMtcall tglobaladdr:$func)]>,
|
||
Requires<[IsThumb, IsNotIOS]> {
|
||
- bits<22> func;
|
||
- let Inst{26} = func{21};
|
||
+ bits<24> func;
|
||
+ let Inst{26} = func{23};
|
||
let Inst{25-16} = func{20-11};
|
||
- let Inst{13} = 1;
|
||
- let Inst{11} = 1;
|
||
+ let Inst{13} = func{22};
|
||
+ let Inst{11} = func{21};
|
||
let Inst{10-0} = func{10-0};
|
||
}
|
||
|
||
@@ -427,10 +427,11 @@
|
||
"blx${p}\t$func",
|
||
[(ARMcall tglobaladdr:$func)]>,
|
||
Requires<[IsThumb, HasV5T, IsNotIOS]> {
|
||
- bits<21> func;
|
||
+ bits<24> func;
|
||
+ let Inst{26} = func{23};
|
||
let Inst{25-16} = func{20-11};
|
||
- let Inst{13} = 1;
|
||
- let Inst{11} = 1;
|
||
+ let Inst{13} = func{22};
|
||
+ let Inst{11} = func{21};
|
||
let Inst{10-1} = func{10-1};
|
||
let Inst{0} = 0; // func{0} is assumed zero
|
||
}
|
||
Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
|
||
===================================================================
|
||
--- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (revision 152265)
|
||
+++ lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (working copy)
|
||
@@ -397,39 +397,65 @@
|
||
return swapped;
|
||
}
|
||
case ARM::fixup_arm_thumb_bl: {
|
||
- // The value doesn't encode the low bit (always zero) and is offset by
|
||
- // four. The value is encoded into disjoint bit positions in the destination
|
||
- // opcode. x = unchanged, I = immediate value bit, S = sign extension bit
|
||
- //
|
||
- // BL: xxxxxSIIIIIIIIII xxxxxIIIIIIIIIII
|
||
- //
|
||
- // Note that the halfwords are stored high first, low second; so we need
|
||
- // to transpose the fixup value here to map properly.
|
||
- unsigned isNeg = (int64_t(Value - 4) < 0) ? 1 : 0;
|
||
- uint32_t Binary = 0;
|
||
- Value = 0x3fffff & ((Value - 4) >> 1);
|
||
- Binary = (Value & 0x7ff) << 16; // Low imm11 value.
|
||
- Binary |= (Value & 0x1ffc00) >> 11; // High imm10 value.
|
||
- Binary |= isNeg << 10; // Sign bit.
|
||
- return Binary;
|
||
+ // The value doesn't encode the low bit (always zero) and is offset by
|
||
+ // four. The 32-bit immediate value is encoded as
|
||
+ // imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
|
||
+ // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
|
||
+ // The value is encoded into disjoint bit positions in the destination
|
||
+ // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
|
||
+ // J = either J1 or J2 bit
|
||
+ //
|
||
+ // BL: xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII
|
||
+ //
|
||
+ // Note that the halfwords are stored high first, low second; so we need
|
||
+ // to transpose the fixup value here to map properly.
|
||
+ uint32_t offset = (Value - 4) >> 1;
|
||
+ uint32_t signBit = (offset & 0x800000) >> 23;
|
||
+ uint32_t I1Bit = (offset & 0x400000) >> 22;
|
||
+ uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
|
||
+ uint32_t I2Bit = (offset & 0x200000) >> 21;
|
||
+ uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
|
||
+ uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
|
||
+ uint32_t imm11Bits = (offset & 0x000007FF);
|
||
+
|
||
+ uint32_t Binary = 0;
|
||
+ uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
|
||
+ uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
|
||
+ (uint16_t)imm11Bits);
|
||
+ Binary |= secondHalf << 16;
|
||
+ Binary |= firstHalf;
|
||
+ return Binary;
|
||
+
|
||
}
|
||
case ARM::fixup_arm_thumb_blx: {
|
||
- // The value doesn't encode the low two bits (always zero) and is offset by
|
||
- // four (see fixup_arm_thumb_cp). The value is encoded into disjoint bit
|
||
- // positions in the destination opcode. x = unchanged, I = immediate value
|
||
- // bit, S = sign extension bit, 0 = zero.
|
||
- //
|
||
- // BLX: xxxxxSIIIIIIIIII xxxxxIIIIIIIIII0
|
||
- //
|
||
- // Note that the halfwords are stored high first, low second; so we need
|
||
- // to transpose the fixup value here to map properly.
|
||
- unsigned isNeg = (int64_t(Value-4) < 0) ? 1 : 0;
|
||
- uint32_t Binary = 0;
|
||
- Value = 0xfffff & ((Value - 2) >> 2);
|
||
- Binary = (Value & 0x3ff) << 17; // Low imm10L value.
|
||
- Binary |= (Value & 0xffc00) >> 10; // High imm10H value.
|
||
- Binary |= isNeg << 10; // Sign bit.
|
||
- return Binary;
|
||
+ // The value doesn't encode the low two bits (always zero) and is offset by
|
||
+ // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
|
||
+ // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
|
||
+ // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
|
||
+ // The value is encoded into disjoint bit positions in the destination
|
||
+ // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
|
||
+ // J = either J1 or J2 bit, 0 = zero.
|
||
+ //
|
||
+ // BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0
|
||
+ //
|
||
+ // Note that the halfwords are stored high first, low second; so we need
|
||
+ // to transpose the fixup value here to map properly.
|
||
+ uint32_t offset = (Value - 2) >> 2;
|
||
+ uint32_t signBit = (offset & 0x400000) >> 22;
|
||
+ uint32_t I1Bit = (offset & 0x200000) >> 21;
|
||
+ uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
|
||
+ uint32_t I2Bit = (offset & 0x100000) >> 20;
|
||
+ uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
|
||
+ uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
|
||
+ uint32_t imm10LBits = (offset & 0x3FF);
|
||
+
|
||
+ uint32_t Binary = 0;
|
||
+ uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
|
||
+ uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
|
||
+ ((uint16_t)imm10LBits) << 1);
|
||
+ Binary |= secondHalf << 16;
|
||
+ Binary |= firstHalf;
|
||
+ return Binary;
|
||
}
|
||
case ARM::fixup_arm_thumb_cp:
|
||
// Offset by 4, and don't encode the low two bits. Two bytes of that
|
||
Index: lib/Target/ARM/Disassembler/ARMDisassembler.cpp
|
||
===================================================================
|
||
--- lib/Target/ARM/Disassembler/ARMDisassembler.cpp (revision 152265)
|
||
+++ lib/Target/ARM/Disassembler/ARMDisassembler.cpp (working copy)
|
||
@@ -182,6 +182,8 @@
|
||
uint64_t Address, const void *Decoder);
|
||
static DecodeStatus DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val,
|
||
uint64_t Address, const void *Decoder);
|
||
+static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
|
||
+ uint64_t Address, const void *Decoder);
|
||
static DecodeStatus DecodeBranchImmInstruction(llvm::MCInst &Inst,unsigned Insn,
|
||
uint64_t Address, const void *Decoder);
|
||
static DecodeStatus DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val,
|
||
@@ -1945,6 +1947,21 @@
|
||
}
|
||
|
||
static DecodeStatus
|
||
+DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
|
||
+ uint64_t Address, const void *Decoder) {
|
||
+ DecodeStatus S = MCDisassembler::Success;
|
||
+ unsigned imm = (fieldFromInstruction32(Insn, 0, 11) << 0) |
|
||
+ (fieldFromInstruction32(Insn, 11, 1) << 18) |
|
||
+ (fieldFromInstruction32(Insn, 13, 1) << 17) |
|
||
+ (fieldFromInstruction32(Insn, 16, 6) << 11) |
|
||
+ (fieldFromInstruction32(Insn, 26, 1) << 19);
|
||
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<20>(imm<<1) + 4,
|
||
+ true, 4, Inst, Decoder))
|
||
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<20>(imm << 1)));
|
||
+ return S;
|
||
+}
|
||
+
|
||
+static DecodeStatus
|
||
DecodeBranchImmInstruction(llvm::MCInst &Inst, unsigned Insn,
|
||
uint64_t Address, const void *Decoder) {
|
||
DecodeStatus S = MCDisassembler::Success;
|
||
@@ -2177,6 +2194,8 @@
|
||
case ARM::VLD2b8wb_register:
|
||
case ARM::VLD2b16wb_register:
|
||
case ARM::VLD2b32wb_register:
|
||
+ Inst.addOperand(MCOperand::CreateImm(0));
|
||
+ break;
|
||
case ARM::VLD3d8_UPD:
|
||
case ARM::VLD3d16_UPD:
|
||
case ARM::VLD3d32_UPD:
|
||
@@ -2245,6 +2264,16 @@
|
||
!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
|
||
return MCDisassembler::Fail;
|
||
break;
|
||
+ case ARM::VLD2d8wb_fixed:
|
||
+ case ARM::VLD2d16wb_fixed:
|
||
+ case ARM::VLD2d32wb_fixed:
|
||
+ case ARM::VLD2b8wb_fixed:
|
||
+ case ARM::VLD2b16wb_fixed:
|
||
+ case ARM::VLD2b32wb_fixed:
|
||
+ case ARM::VLD2q8wb_fixed:
|
||
+ case ARM::VLD2q16wb_fixed:
|
||
+ case ARM::VLD2q32wb_fixed:
|
||
+ break;
|
||
}
|
||
|
||
return S;
|
||
@@ -2313,6 +2342,10 @@
|
||
case ARM::VST2b8wb_register:
|
||
case ARM::VST2b16wb_register:
|
||
case ARM::VST2b32wb_register:
|
||
+ if (Rm == 0xF)
|
||
+ return MCDisassembler::Fail;
|
||
+ Inst.addOperand(MCOperand::CreateImm(0));
|
||
+ break;
|
||
case ARM::VST3d8_UPD:
|
||
case ARM::VST3d16_UPD:
|
||
case ARM::VST3d32_UPD:
|
||
@@ -2354,6 +2387,23 @@
|
||
case ARM::VST1q16wb_fixed:
|
||
case ARM::VST1q32wb_fixed:
|
||
case ARM::VST1q64wb_fixed:
|
||
+ case ARM::VST1d8Twb_fixed:
|
||
+ case ARM::VST1d16Twb_fixed:
|
||
+ case ARM::VST1d32Twb_fixed:
|
||
+ case ARM::VST1d64Twb_fixed:
|
||
+ case ARM::VST1d8Qwb_fixed:
|
||
+ case ARM::VST1d16Qwb_fixed:
|
||
+ case ARM::VST1d32Qwb_fixed:
|
||
+ case ARM::VST1d64Qwb_fixed:
|
||
+ case ARM::VST2d8wb_fixed:
|
||
+ case ARM::VST2d16wb_fixed:
|
||
+ case ARM::VST2d32wb_fixed:
|
||
+ case ARM::VST2q8wb_fixed:
|
||
+ case ARM::VST2q16wb_fixed:
|
||
+ case ARM::VST2q32wb_fixed:
|
||
+ case ARM::VST2b8wb_fixed:
|
||
+ case ARM::VST2b16wb_fixed:
|
||
+ case ARM::VST2b32wb_fixed:
|
||
break;
|
||
}
|
||
|
||
@@ -2555,7 +2605,6 @@
|
||
unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
|
||
unsigned align = fieldFromInstruction32(Insn, 4, 1);
|
||
unsigned size = 1 << fieldFromInstruction32(Insn, 6, 2);
|
||
- unsigned pred = fieldFromInstruction32(Insn, 22, 4);
|
||
align *= 2*size;
|
||
|
||
switch (Inst.getOpcode()) {
|
||
@@ -2586,16 +2635,11 @@
|
||
return MCDisassembler::Fail;
|
||
Inst.addOperand(MCOperand::CreateImm(align));
|
||
|
||
- if (Rm == 0xD)
|
||
- Inst.addOperand(MCOperand::CreateReg(0));
|
||
- else if (Rm != 0xF) {
|
||
+ if (Rm != 0xD && Rm != 0xF) {
|
||
if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
|
||
return MCDisassembler::Fail;
|
||
}
|
||
|
||
- if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
|
||
- return MCDisassembler::Fail;
|
||
-
|
||
return S;
|
||
}
|
||
|
||
@@ -2837,19 +2881,25 @@
|
||
|
||
static DecodeStatus DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val,
|
||
uint64_t Address, const void *Decoder) {
|
||
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
|
||
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
|
||
+ true, 2, Inst, Decoder))
|
||
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
|
||
return MCDisassembler::Success;
|
||
}
|
||
|
||
static DecodeStatus DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val,
|
||
uint64_t Address, const void *Decoder) {
|
||
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
|
||
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
|
||
+ true, 4, Inst, Decoder))
|
||
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
|
||
return MCDisassembler::Success;
|
||
}
|
||
|
||
static DecodeStatus DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val,
|
||
uint64_t Address, const void *Decoder) {
|
||
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1)));
|
||
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<7>(Val<<1) + 4,
|
||
+ true, 2, Inst, Decoder))
|
||
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1)));
|
||
return MCDisassembler::Success;
|
||
}
|
||
|
||
@@ -3162,10 +3212,25 @@
|
||
|
||
static DecodeStatus DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Val,
|
||
uint64_t Address, const void *Decoder) {
|
||
+ // Val is passed in as S:J1:J2:imm10H:imm10L:’0’
|
||
+ // Note only one trailing zero not two. Also the J1 and J2 values are from
|
||
+ // the encoded instruction. So here change to I1 and I2 values via:
|
||
+ // I1 = NOT(J1 EOR S);
|
||
+ // I2 = NOT(J2 EOR S);
|
||
+ // and build the imm32 with two trailing zeros as documented:
|
||
+ // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:’00’, 32);
|
||
+ unsigned S = (Val >> 23) & 1;
|
||
+ unsigned J1 = (Val >> 22) & 1;
|
||
+ unsigned J2 = (Val >> 21) & 1;
|
||
+ unsigned I1 = !(J1 ^ S);
|
||
+ unsigned I2 = !(J2 ^ S);
|
||
+ unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
|
||
+ int imm32 = SignExtend32<25>(tmp << 1);
|
||
+
|
||
if (!tryAddingSymbolicOperand(Address,
|
||
- (Address & ~2u) + SignExtend32<22>(Val << 1) + 4,
|
||
+ (Address & ~2u) + imm32 + 4,
|
||
true, 4, Inst, Decoder))
|
||
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
|
||
+ Inst.addOperand(MCOperand::CreateImm(imm32));
|
||
return MCDisassembler::Success;
|
||
}
|
||
|
||
@@ -3271,15 +3336,32 @@
|
||
static DecodeStatus
|
||
DecodeThumbBCCTargetOperand(llvm::MCInst &Inst, unsigned Val,
|
||
uint64_t Address, const void *Decoder){
|
||
- Inst.addOperand(MCOperand::CreateImm(Val << 1));
|
||
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<8>(Val<<1) + 4,
|
||
+ true, 2, Inst, Decoder))
|
||
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<8>(Val << 1)));
|
||
return MCDisassembler::Success;
|
||
}
|
||
|
||
static DecodeStatus DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
|
||
uint64_t Address, const void *Decoder){
|
||
- if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4,
|
||
+ // Val is passed in as S:J1:J2:imm10:imm11
|
||
+ // Note no trailing zero after imm11. Also the J1 and J2 values are from
|
||
+ // the encoded instruction. So here change to I1 and I2 values via:
|
||
+ // I1 = NOT(J1 EOR S);
|
||
+ // I2 = NOT(J2 EOR S);
|
||
+ // and build the imm32 with one trailing zero as documented:
|
||
+ // imm32 = SignExtend(S:I1:I2:imm10:imm11:’0’, 32);
|
||
+ unsigned S = (Val >> 23) & 1;
|
||
+ unsigned J1 = (Val >> 22) & 1;
|
||
+ unsigned J2 = (Val >> 21) & 1;
|
||
+ unsigned I1 = !(J1 ^ S);
|
||
+ unsigned I2 = !(J2 ^ S);
|
||
+ unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
|
||
+ int imm32 = SignExtend32<25>(tmp << 1);
|
||
+
|
||
+ if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
|
||
true, 4, Inst, Decoder))
|
||
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
|
||
+ Inst.addOperand(MCOperand::CreateImm(imm32));
|
||
return MCDisassembler::Success;
|
||
}
|
||
|
||
Index: lib/Target/X86/Disassembler/X86Disassembler.cpp
|
||
===================================================================
|
||
--- lib/Target/X86/Disassembler/X86Disassembler.cpp (revision 152265)
|
||
+++ lib/Target/X86/Disassembler/X86Disassembler.cpp (working copy)
|
||
@@ -322,7 +322,12 @@
|
||
|
||
OperandType type = (OperandType)operand.type;
|
||
|
||
+ bool isBranch = false;
|
||
+ uint64_t pcrel = 0;
|
||
if (type == TYPE_RELv) {
|
||
+ isBranch = true;
|
||
+ pcrel = insn.startLocation +
|
||
+ insn.immediateOffset + insn.immediateSize;
|
||
switch (insn.displacementSize) {
|
||
default:
|
||
break;
|
||
@@ -373,8 +378,6 @@
|
||
}
|
||
}
|
||
|
||
- bool isBranch = false;
|
||
- uint64_t pcrel = 0;
|
||
switch (type) {
|
||
case TYPE_XMM128:
|
||
mcInst.addOperand(MCOperand::CreateReg(X86::XMM0 + (immediate >> 4)));
|
||
Index: lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
|
||
===================================================================
|
||
--- lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (revision 152265)
|
||
+++ lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (working copy)
|
||
@@ -312,6 +312,13 @@
|
||
|
||
if (consumeByte(insn, &byte))
|
||
return -1;
|
||
+
|
||
+ // If the the first byte is a LOCK prefix break and let it be disassembled
|
||
+ // as a lock "instruction", by creating an <MCInst #xxxx LOCK_PREFIX>.
|
||
+ // FIXME there is currently no way to get the disassembler to print the
|
||
+ // lock prefix if it is not the first byte.
|
||
+ if (insn->readerCursor - 1 == insn->startLocation && byte == 0xf0)
|
||
+ break;
|
||
|
||
switch (byte) {
|
||
case 0xf0: /* LOCK */
|
||
Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
|
||
===================================================================
|
||
--- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (revision 152265)
|
||
+++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (working copy)
|
||
@@ -24,7 +24,8 @@
|
||
bool RuntimeDyldMachO::
|
||
resolveRelocation(uint8_t *LocalAddress,
|
||
uint64_t FinalAddress,
|
||
- uint64_t Value,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
bool isPCRel,
|
||
unsigned Type,
|
||
unsigned Size,
|
||
@@ -32,10 +33,20 @@
|
||
// This just dispatches to the proper target specific routine.
|
||
switch (CPUType) {
|
||
default: llvm_unreachable("Unsupported CPU type!");
|
||
+ case mach::CTM_i386:
|
||
+ return resolveI386Relocation(LocalAddress,
|
||
+ FinalAddress,
|
||
+ FinalSource1,
|
||
+ FinalSource2,
|
||
+ isPCRel,
|
||
+ Type,
|
||
+ Size,
|
||
+ Addend);
|
||
case mach::CTM_x86_64:
|
||
return resolveX86_64Relocation(LocalAddress,
|
||
FinalAddress,
|
||
- (uintptr_t)Value,
|
||
+ FinalSource1,
|
||
+ FinalSource2,
|
||
isPCRel,
|
||
Type,
|
||
Size,
|
||
@@ -43,7 +54,8 @@
|
||
case mach::CTM_ARM:
|
||
return resolveARMRelocation(LocalAddress,
|
||
FinalAddress,
|
||
- (uintptr_t)Value,
|
||
+ FinalSource1,
|
||
+ FinalSource2,
|
||
isPCRel,
|
||
Type,
|
||
Size,
|
||
@@ -52,19 +64,52 @@
|
||
}
|
||
|
||
bool RuntimeDyldMachO::
|
||
+resolveI386Relocation(uint8_t *LocalAddress,
|
||
+ uint64_t FinalAddress,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
+ bool isPCRel,
|
||
+ unsigned Type,
|
||
+ unsigned Size,
|
||
+ int64_t Addend) {
|
||
+ int64_t ValueToWrite = Addend;
|
||
+
|
||
+ switch (Type) {
|
||
+ default:
|
||
+ llvm_unreachable("Invalid relocation type!");
|
||
+ case macho::RIT_Vanilla:
|
||
+ ValueToWrite += FinalSource1;
|
||
+ break;
|
||
+ case macho::RIT_Difference:
|
||
+ case macho::RIT_Generic_LocalDifference:
|
||
+ case macho::RIT_Generic_PreboundLazyPointer:
|
||
+ ValueToWrite += FinalSource1;
|
||
+ ValueToWrite -= FinalSource2;
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ if (isPCRel)
|
||
+ ValueToWrite -= FinalAddress + 4; // see resolveX86_64Relocation
|
||
+
|
||
+ uint8_t *p = LocalAddress;
|
||
+ for (unsigned i = 0; i < Size; ++i) {
|
||
+ *p++ = (uint8_t)(ValueToWrite & 0xff);
|
||
+ ValueToWrite >>= 8;
|
||
+ }
|
||
+
|
||
+ return false;
|
||
+}
|
||
+
|
||
+bool RuntimeDyldMachO::
|
||
resolveX86_64Relocation(uint8_t *LocalAddress,
|
||
uint64_t FinalAddress,
|
||
- uint64_t Value,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
bool isPCRel,
|
||
unsigned Type,
|
||
unsigned Size,
|
||
int64_t Addend) {
|
||
- // If the relocation is PC-relative, the value to be encoded is the
|
||
- // pointer difference.
|
||
- if (isPCRel)
|
||
- // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
|
||
- // address. Is that expected? Only for branches, perhaps?
|
||
- Value -= FinalAddress + 4;
|
||
+ int64_t ValueToWrite = Addend;
|
||
|
||
switch(Type) {
|
||
default:
|
||
@@ -74,41 +119,53 @@
|
||
case macho::RIT_X86_64_Signed4:
|
||
case macho::RIT_X86_64_Signed:
|
||
case macho::RIT_X86_64_Unsigned:
|
||
- case macho::RIT_X86_64_Branch: {
|
||
- Value += Addend;
|
||
- // Mask in the target value a byte at a time (we don't have an alignment
|
||
- // guarantee for the target address, so this is safest).
|
||
- uint8_t *p = (uint8_t*)LocalAddress;
|
||
- for (unsigned i = 0; i < Size; ++i) {
|
||
- *p++ = (uint8_t)Value;
|
||
- Value >>= 8;
|
||
- }
|
||
- return false;
|
||
- }
|
||
+ case macho::RIT_X86_64_Branch:
|
||
+ ValueToWrite += FinalSource1;
|
||
+ break;
|
||
case macho::RIT_X86_64_GOTLoad:
|
||
case macho::RIT_X86_64_GOT:
|
||
case macho::RIT_X86_64_Subtractor:
|
||
case macho::RIT_X86_64_TLV:
|
||
return Error("Relocation type not implemented yet!");
|
||
}
|
||
+
|
||
+ // If the relocation is PC-relative, the value to be encoded is the
|
||
+ // pointer difference.
|
||
+ if (isPCRel)
|
||
+ // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
|
||
+ // address. Is that expected? Only for branches, perhaps?
|
||
+ ValueToWrite -= FinalAddress + 4;
|
||
+
|
||
+ // Mask in the target value a byte at a time (we don't have an alignment
|
||
+ // guarantee for the target address, so this is safest).
|
||
+ uint8_t *p = (uint8_t*)LocalAddress;
|
||
+ for (unsigned i = 0; i < Size; ++i) {
|
||
+ *p++ = (uint8_t)(ValueToWrite & 0xff);
|
||
+ ValueToWrite >>= 8;
|
||
+ }
|
||
+
|
||
+ return false;
|
||
}
|
||
|
||
bool RuntimeDyldMachO::
|
||
resolveARMRelocation(uint8_t *LocalAddress,
|
||
uint64_t FinalAddress,
|
||
- uint64_t Value,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
bool isPCRel,
|
||
unsigned Type,
|
||
unsigned Size,
|
||
int64_t Addend) {
|
||
+ int64_t ValueToWrite = Addend;
|
||
+
|
||
// If the relocation is PC-relative, the value to be encoded is the
|
||
// pointer difference.
|
||
if (isPCRel) {
|
||
- Value -= FinalAddress;
|
||
+ ValueToWrite -= FinalAddress;
|
||
// ARM PCRel relocations have an effective-PC offset of two instructions
|
||
// (four bytes in Thumb mode, 8 bytes in ARM mode).
|
||
// FIXME: For now, assume ARM mode.
|
||
- Value -= 8;
|
||
+ ValueToWrite -= 8;
|
||
}
|
||
|
||
switch(Type) {
|
||
@@ -119,8 +176,8 @@
|
||
// guarantee for the target address, so this is safest).
|
||
uint8_t *p = (uint8_t*)LocalAddress;
|
||
for (unsigned i = 0; i < Size; ++i) {
|
||
- *p++ = (uint8_t)Value;
|
||
- Value >>= 8;
|
||
+ *p++ = (uint8_t)(ValueToWrite & 0xff);
|
||
+ ValueToWrite >>= 8;
|
||
}
|
||
break;
|
||
}
|
||
@@ -129,15 +186,15 @@
|
||
// 32-bit aligned, so we can do it all at once.
|
||
uint32_t *p = (uint32_t*)LocalAddress;
|
||
// The low two bits of the value are not encoded.
|
||
- Value >>= 2;
|
||
+ ValueToWrite >>= 2;
|
||
// Mask the value to 24 bits.
|
||
- Value &= 0xffffff;
|
||
+ ValueToWrite &= 0xffffff;
|
||
// FIXME: If the destination is a Thumb function (and the instruction
|
||
// is a non-predicated BL instruction), we need to change it to a BLX
|
||
// instruction instead.
|
||
|
||
// Insert the value into the instruction.
|
||
- *p = (*p & ~0xffffff) | Value;
|
||
+ *p = (*p & ~0xffffff) | ValueToWrite;
|
||
break;
|
||
}
|
||
case macho::RIT_ARM_ThumbBranch22Bit:
|
||
@@ -153,6 +210,29 @@
|
||
return false;
|
||
}
|
||
|
||
+static bool
|
||
+ResolveSectionAndOffset(const MachOObject *Obj,
|
||
+ SmallVectorImpl<unsigned> &SectionMap,
|
||
+ const MachOObject::LoadCommandInfo *SegmentLCI,
|
||
+ InMemoryStruct<macho::SegmentLoadCommand> &SegmentLC,
|
||
+ uint64_t Address,
|
||
+ unsigned &SectionID,
|
||
+ uint64_t &Offset)
|
||
+{
|
||
+ for (unsigned SI = 0, SE = SegmentLC->NumSections; SI < SE; ++SI) {
|
||
+ InMemoryStruct<macho::Section> CandidateSection;
|
||
+ Obj->ReadSection(*SegmentLCI, SI, CandidateSection);
|
||
+ if (Address >= CandidateSection->Address &&
|
||
+ Address < CandidateSection->Address + CandidateSection->Size) {
|
||
+ SectionID = SectionMap[SI];
|
||
+ Offset = Address - CandidateSection->Address;
|
||
+ return true;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return false;
|
||
+}
|
||
+
|
||
bool RuntimeDyldMachO::
|
||
loadSegment32(const MachOObject *Obj,
|
||
const MachOObject::LoadCommandInfo *SegmentLCI,
|
||
@@ -210,6 +290,7 @@
|
||
|
||
// Process the relocations for each section we're loading.
|
||
Relocations.grow(Relocations.size() + SegmentLC->NumSections);
|
||
+ RelocationSources.grow(RelocationSources.size() + SegmentLC->NumSections);
|
||
for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
|
||
InMemoryStruct<macho::Section> Sect;
|
||
Obj->ReadSection(*SegmentLCI, SectNum, Sect);
|
||
@@ -218,51 +299,135 @@
|
||
for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
|
||
InMemoryStruct<macho::RelocationEntry> RE;
|
||
Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
|
||
- if (RE->Word0 & macho::RF_Scattered)
|
||
- return Error("NOT YET IMPLEMENTED: scattered relocations.");
|
||
- // Word0 of the relocation is the offset into the section where the
|
||
- // relocation should be applied. We need to translate that into an
|
||
- // offset into a function since that's our atom.
|
||
- uint32_t Offset = RE->Word0;
|
||
- bool isExtern = (RE->Word1 >> 27) & 1;
|
||
-
|
||
- // FIXME: Get the relocation addend from the target address.
|
||
- // FIXME: VERY imporant for internal relocations.
|
||
-
|
||
- // Figure out the source symbol of the relocation. If isExtern is true,
|
||
- // this relocation references the symbol table, otherwise it references
|
||
- // a section in the same object, numbered from 1 through NumSections
|
||
- // (SectionBases is [0, NumSections-1]).
|
||
- uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
|
||
- if (!isExtern) {
|
||
- assert(SourceNum > 0 && "Invalid relocation section number!");
|
||
- unsigned SectionID = SectionMap[SourceNum - 1];
|
||
+ if (RE->Word0 & macho::RF_Scattered) {
|
||
+ // The lower 24 bits of Word0 of the scattered relocation is the offset
|
||
+ // into the section where the relocation should be applied, i.e., the
|
||
+ // current section.
|
||
+ uint32_t OffsetInTarget = RE->Word0 & 0x00ffffff;
|
||
unsigned TargetID = SectionMap[SectNum];
|
||
- DEBUG(dbgs() << "Internal relocation at Section #"
|
||
- << TargetID << " + " << Offset
|
||
- << " from Section #"
|
||
- << SectionID << " (Word1: "
|
||
- << format("0x%x", RE->Word1) << ")\n");
|
||
-
|
||
- // Store the relocation information. It will get resolved when
|
||
- // the section addresses are assigned.
|
||
- Relocations[SectionID].push_back(RelocationEntry(TargetID,
|
||
- Offset,
|
||
- RE->Word1,
|
||
- 0 /*Addend*/));
|
||
+ // Word1 of the scattered relocation is a file offset which needs to
|
||
+ // be resolved into Section+Offset form. This gives the address of the
|
||
+ // source.
|
||
+ unsigned Source1ID;
|
||
+ uint64_t Source1Offset;
|
||
+ if (!ResolveSectionAndOffset(Obj,
|
||
+ SectionMap,
|
||
+ SegmentLCI,
|
||
+ SegmentLC,
|
||
+ RE->Word1,
|
||
+ Source1ID,
|
||
+ Source1Offset))
|
||
+ return Error("couldn't find scattered relocation value in sections");
|
||
+ // This relocation may have a paired relocation entry. If it does, set
|
||
+ // the source/offset information for it correctly.
|
||
+ unsigned Source2ID = SectionOffset::NoSectionID;
|
||
+ uint64_t Source2Offset = 0;
|
||
+ if (j + 1 < Sect->NumRelocationTableEntries) {
|
||
+ InMemoryStruct<macho::RelocationEntry> PairRE;
|
||
+ Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j+1, PairRE);
|
||
+ if ((PairRE->Word0 & macho::RF_Scattered) &&
|
||
+ ((PairRE->Word0 & 0x0f000000) >> 24) == macho::RIT_Pair) {
|
||
+ if (!ResolveSectionAndOffset(Obj,
|
||
+ SectionMap,
|
||
+ SegmentLCI,
|
||
+ SegmentLC,
|
||
+ PairRE->Word1,
|
||
+ Source2ID,
|
||
+ Source2Offset))
|
||
+ return Error("couldn't find scattered relocation value in sections");
|
||
+ ++j;
|
||
+ }
|
||
+ }
|
||
+ if (Source2ID == SectionOffset::NoSectionID)
|
||
+ DEBUG(dbgs() << "Scattered relocation at Section #"
|
||
+ << TargetID << " + " << OffsetInTarget
|
||
+ << " from Section #" << Source1ID
|
||
+ << "+" << Source1Offset
|
||
+ << " (Word0: "
|
||
+ << format("0x%x", RE->Word0) << ")\n");
|
||
+ else
|
||
+ DEBUG(dbgs() << "Scattered relocation at Section #"
|
||
+ << TargetID << " + " << OffsetInTarget
|
||
+ << " from Section #" << Source1ID
|
||
+ << "+" << Source1Offset
|
||
+ << " and Section #" << Source2ID
|
||
+ << "+" << Source2Offset
|
||
+ << " (Word0: "
|
||
+ << format("0x%x", RE->Word0) << ")\n");
|
||
+ uint32_t RelocationIndex = Relocations[TargetID].size();
|
||
+ // FIXME: Get the relocation addend from the target address.
|
||
+ // FIXME: VERY imporant for internal relocations.
|
||
+ RelocationEntry TranslatedRE(OffsetInTarget,
|
||
+ Source1ID,
|
||
+ Source1Offset,
|
||
+ Source2ID,
|
||
+ Source2Offset,
|
||
+ RE->Word1,
|
||
+ 0 /*Addend*/);
|
||
+ Relocations[TargetID].push_back(TranslatedRE);
|
||
+ RelocationSources[Source1ID].push_back(RelocationSource(TargetID,
|
||
+ RelocationIndex,
|
||
+ 0));
|
||
+ if (Source2ID != SectionOffset::NoSectionID)
|
||
+ RelocationSources[Source2ID].push_back(RelocationSource(TargetID,
|
||
+ RelocationIndex,
|
||
+ 1));
|
||
} else {
|
||
- StringRef SourceName = SymbolNames[SourceNum];
|
||
-
|
||
- // Now store the relocation information. Associate it with the source
|
||
- // symbol. Just add it to the unresolved list and let the general
|
||
- // path post-load resolve it if we know where the symbol is.
|
||
- UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
|
||
- Offset,
|
||
- RE->Word1,
|
||
- 0 /*Addend*/));
|
||
- DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
|
||
- << " from '" << SourceName << "(Word1: "
|
||
- << format("0x%x", RE->Word1) << ")\n");
|
||
+ // Word0 of the relocation is the offset into the section where the
|
||
+ // relocation should be applied, i.e., the current section. We need
|
||
+ // to translate that into an offset into a function since that's our atom.
|
||
+ uint32_t OffsetInTarget = RE->Word0;
|
||
+ bool isExtern = (RE->Word1 >> 27) & 1;
|
||
+
|
||
+ // FIXME: Get the relocation addend from the target address.
|
||
+ // FIXME: VERY imporant for internal relocations.
|
||
+
|
||
+ // Figure out the source symbol of the relocation. If isExtern is true,
|
||
+ // this relocation references the symbol table, otherwise it references
|
||
+ // a section in the same object, numbered from 1 through NumSections
|
||
+ // (SectionBases is [0, NumSections-1]).
|
||
+ uint32_t SourceNum_OneBased = RE->Word1 & 0xffffff; // 24-bit value
|
||
+ if (!isExtern) {
|
||
+ assert(SourceNum_OneBased > 0 && "Invalid relocation section number!");
|
||
+ unsigned SourceID = SectionMap[SourceNum_OneBased - 1];
|
||
+ unsigned TargetID = SectionMap[SectNum];
|
||
+ DEBUG(dbgs() << "Internal relocation at Section #"
|
||
+ << TargetID << " + " << OffsetInTarget
|
||
+ << " from Section #"
|
||
+ << SourceID << " (Word1: "
|
||
+ << format("0x%x", RE->Word1) << ")\n");
|
||
+
|
||
+ // Store the relocation information. It will get resolved when
|
||
+ // the section addresses are assigned.
|
||
+ uint32_t RelocationIndex = Relocations[TargetID].size();
|
||
+ Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
|
||
+ SourceID,
|
||
+ SectionOffset::NoSectionID,
|
||
+ RE->Word1,
|
||
+ 0 /*Addend*/));
|
||
+ RelocationSources[SourceID].push_back(RelocationSource(TargetID,
|
||
+ RelocationIndex,
|
||
+ 0));
|
||
+ } else {
|
||
+ StringRef SourceName = SymbolNames[SourceNum_OneBased];
|
||
+
|
||
+ // Now store the relocation information. Associate it with the source
|
||
+ // symbol. Just add it to the unresolved list and let the general
|
||
+ // path post-load resolve it if we know where the symbol is.
|
||
+ unsigned TargetID = SectionMap[SectNum];
|
||
+ uint32_t RelocationIndex = Relocations[TargetID].size();
|
||
+ Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
|
||
+ SectionOffset::UnresolvedSourceID,
|
||
+ SectionOffset::NoSectionID,
|
||
+ RE->Word1,
|
||
+ 0 /*Addend*/));
|
||
+ UnresolvedRelocations[SourceName].push_back(RelocationSource(TargetID,
|
||
+ RelocationIndex,
|
||
+ 0));
|
||
+ DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << OffsetInTarget
|
||
+ << " from '" << SourceName << "' (Word1: "
|
||
+ << format("0x%x", RE->Word1) << ")\n");
|
||
+ }
|
||
}
|
||
}
|
||
}
|
||
@@ -332,6 +497,7 @@
|
||
|
||
// Process the relocations for each section we're loading.
|
||
Relocations.grow(Relocations.size() + Segment64LC->NumSections);
|
||
+ RelocationSources.grow(RelocationSources.size() + Segment64LC->NumSections);
|
||
for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
|
||
InMemoryStruct<macho::Section64> Sect;
|
||
Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
|
||
@@ -341,11 +507,11 @@
|
||
InMemoryStruct<macho::RelocationEntry> RE;
|
||
Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
|
||
if (RE->Word0 & macho::RF_Scattered)
|
||
- return Error("NOT YET IMPLEMENTED: scattered relocations.");
|
||
+ return Error("scattered relocations don't exist on 64-bit platforms");
|
||
// Word0 of the relocation is the offset into the section where the
|
||
// relocation should be applied. We need to translate that into an
|
||
// offset into a function since that's our atom.
|
||
- uint32_t Offset = RE->Word0;
|
||
+ uint32_t OffsetInTarget = RE->Word0;
|
||
bool isExtern = (RE->Word1 >> 27) & 1;
|
||
|
||
// FIXME: Get the relocation addend from the target address.
|
||
@@ -355,34 +521,45 @@
|
||
// this relocation references the symbol table, otherwise it references
|
||
// a section in the same object, numbered from 1 through NumSections
|
||
// (SectionBases is [0, NumSections-1]).
|
||
- uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
|
||
+ uint32_t SourceNum_OneBased = RE->Word1 & 0xffffff; // 24-bit value
|
||
if (!isExtern) {
|
||
- assert(SourceNum > 0 && "Invalid relocation section number!");
|
||
- unsigned SectionID = SectionMap[SourceNum - 1];
|
||
+ assert(SourceNum_OneBased > 0 && "Invalid relocation section number!");
|
||
+ unsigned SourceID = SectionMap[SourceNum_OneBased - 1];
|
||
unsigned TargetID = SectionMap[SectNum];
|
||
DEBUG(dbgs() << "Internal relocation at Section #"
|
||
- << TargetID << " + " << Offset
|
||
+ << TargetID << " + " << OffsetInTarget
|
||
<< " from Section #"
|
||
- << SectionID << " (Word1: "
|
||
+ << SourceID << " (Word1: "
|
||
<< format("0x%x", RE->Word1) << ")\n");
|
||
|
||
// Store the relocation information. It will get resolved when
|
||
// the section addresses are assigned.
|
||
- Relocations[SectionID].push_back(RelocationEntry(TargetID,
|
||
- Offset,
|
||
- RE->Word1,
|
||
- 0 /*Addend*/));
|
||
+ uint32_t RelocationIndex = Relocations[TargetID].size();
|
||
+ Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
|
||
+ SourceID,
|
||
+ SectionOffset::NoSectionID,
|
||
+ RE->Word1,
|
||
+ 0 /*Addend*/));
|
||
+ RelocationSources[SourceID].push_back(RelocationSource(TargetID,
|
||
+ RelocationIndex,
|
||
+ 0));
|
||
} else {
|
||
- StringRef SourceName = SymbolNames[SourceNum];
|
||
+ StringRef SourceName = SymbolNames[SourceNum_OneBased];
|
||
|
||
// Now store the relocation information. Associate it with the source
|
||
// symbol. Just add it to the unresolved list and let the general
|
||
// path post-load resolve it if we know where the symbol is.
|
||
- UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
|
||
- Offset,
|
||
- RE->Word1,
|
||
- 0 /*Addend*/));
|
||
- DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
|
||
+ unsigned TargetID = SectionMap[SectNum];
|
||
+ uint32_t RelocationIndex = Relocations[TargetID].size();
|
||
+ Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
|
||
+ SectionOffset::UnresolvedSourceID,
|
||
+ SectionOffset::NoSectionID,
|
||
+ RE->Word1,
|
||
+ 0 /*Addend*/));
|
||
+ UnresolvedRelocations[SourceName].push_back(RelocationSource(TargetID,
|
||
+ RelocationIndex,
|
||
+ 0));
|
||
+ DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << OffsetInTarget
|
||
<< " from '" << SourceName << "(Word1: "
|
||
<< format("0x%x", RE->Word1) << ")\n");
|
||
}
|
||
@@ -468,18 +645,22 @@
|
||
if (Loc == SymbolTable.end())
|
||
return;
|
||
|
||
- RelocationList &Relocs = UnresolvedRelocations[Name];
|
||
+ RelocationSourceList &SourcesForSymbol = UnresolvedRelocations[Name];
|
||
DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
|
||
- for (int i = 0, e = Relocs.size(); i != e; ++i) {
|
||
- // Change the relocation to be section relative rather than symbol
|
||
- // relative and move it to the resolved relocation list.
|
||
- RelocationEntry Entry = Relocs[i];
|
||
- Entry.Addend += Loc->second.second;
|
||
- Relocations[Loc->second.first].push_back(Entry);
|
||
+ for (int i = 0, e = SourcesForSymbol.size(); i != e; ++i) {
|
||
+ // Find the relocation entry corresponding to this source and fill
|
||
+ // in its source information with the resolved information from this
|
||
+ // symbol.
|
||
+ RelocationSource &Source = SourcesForSymbol[i];
|
||
+ RelocationEntry &Entry = Relocations[Source.SectionID][Source.Index];
|
||
+ Entry.Sources[Source.SourceIdx].Offset = Loc->second.second;
|
||
+ Entry.Sources[Source.SourceIdx].ID = Loc->second.first;
|
||
+ // Now create a relocation source in the pointed-to section.
|
||
+ RelocationSources[Loc->second.first].push_back(Source);
|
||
}
|
||
// FIXME: Keep a worklist of the relocations we've added so that we can
|
||
// resolve more selectively later.
|
||
- Relocs.clear();
|
||
+ SourcesForSymbol.clear();
|
||
}
|
||
|
||
bool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) {
|
||
@@ -575,6 +756,56 @@
|
||
return false;
|
||
}
|
||
|
||
+bool RuntimeDyldMachO::resolveRelocationEntry(unsigned SectionID,
|
||
+ RelocationEntry &RE)
|
||
+{
|
||
+ uint8_t *Target = (uint8_t*)Sections[SectionID].base() + RE.Offset;
|
||
+ uint64_t FinalTarget = SectionLoadAddress[SectionID] + RE.Offset;
|
||
+
|
||
+ uint64_t FinalSource1 = 0;
|
||
+ uint64_t FinalSource2 = 0;
|
||
+
|
||
+ if (RE.Sources[0].ID == SectionOffset::UnresolvedSourceID ||
|
||
+ RE.Sources[1].ID == SectionOffset::UnresolvedSourceID)
|
||
+ return false;
|
||
+
|
||
+ FinalSource1 = SectionLoadAddress[RE.Sources[0].ID] + RE.Sources[0].Offset;
|
||
+ if (RE.Sources[1].ID != SectionOffset::NoSectionID)
|
||
+ FinalSource2 = SectionLoadAddress[RE.Sources[1].ID] + RE.Sources[1].Offset;
|
||
+
|
||
+ bool isPCRel = RE.isPCRel();
|
||
+ unsigned Type = RE.type();
|
||
+ unsigned Size = RE.length();
|
||
+
|
||
+ if (RE.Sources[1].ID == SectionOffset::NoSectionID)
|
||
+ DEBUG(dbgs() << "Resolving relocation at Section #" << SectionID
|
||
+ << " + " << RE.Offset << " (" << format("%p", Target) << ")"
|
||
+ << " from Section #" << RE.Sources[0].ID << "+" << RE.Sources[0].Offset
|
||
+ << " (" << format("0x%llx", FinalSource1) << ")"
|
||
+ << " (" << (isPCRel ? "pcrel" : "absolute")
|
||
+ << ", type: " << Type << ", Size: " << Size << ", Addend: "
|
||
+ << RE.Addend << ").\n");
|
||
+ else
|
||
+ DEBUG(dbgs() << "Resolving relocation at Section #" << SectionID
|
||
+ << " + " << RE.Offset << " (" << format("%p", Target) << ")"
|
||
+ << " from Section #" << RE.Sources[0].ID << "+" << RE.Sources[0].Offset
|
||
+ << " (" << format("0x%llx", FinalSource1) << ")"
|
||
+ << " and Section #" << RE.Sources[1].ID << "+" << RE.Sources[1].Offset
|
||
+ << " (" << format("0x%llx", FinalSource2) << ")"
|
||
+ << " (" << (isPCRel ? "pcrel" : "absolute")
|
||
+ << ", type: " << Type << ", Size: " << Size << ", Addend: "
|
||
+ << RE.Addend << ").\n");
|
||
+
|
||
+ return resolveRelocation(Target,
|
||
+ FinalTarget,
|
||
+ FinalSource1,
|
||
+ FinalSource2,
|
||
+ isPCRel,
|
||
+ Type,
|
||
+ Size,
|
||
+ RE.Addend);
|
||
+}
|
||
+
|
||
// Assign an address to a symbol name and resolve all the relocations
|
||
// associated with it.
|
||
void RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID,
|
||
@@ -590,30 +821,17 @@
|
||
|
||
SectionLoadAddress[SectionID] = Addr;
|
||
|
||
- RelocationList &Relocs = Relocations[SectionID];
|
||
- for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
|
||
- RelocationEntry &RE = Relocs[i];
|
||
- uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
|
||
- uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
|
||
- bool isPCRel = (RE.Data >> 24) & 1;
|
||
- unsigned Type = (RE.Data >> 28) & 0xf;
|
||
- unsigned Size = 1 << ((RE.Data >> 25) & 3);
|
||
-
|
||
- DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
|
||
- << " + " << RE.Offset << " (" << format("%p", Target) << ")"
|
||
- << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
|
||
- << "(" << (isPCRel ? "pcrel" : "absolute")
|
||
- << ", type: " << Type << ", Size: " << Size << ", Addend: "
|
||
- << RE.Addend << ").\n");
|
||
-
|
||
- resolveRelocation(Target,
|
||
- FinalTarget,
|
||
- Addr,
|
||
- isPCRel,
|
||
- Type,
|
||
- Size,
|
||
- RE.Addend);
|
||
+ RelocationList &RelocsForSection = Relocations[SectionID];
|
||
+ for (unsigned i = 0, e = RelocsForSection.size(); i != e; ++i) {
|
||
+ RelocationEntry &RE = RelocsForSection[i];
|
||
+ resolveRelocationEntry(SectionID, RE);
|
||
}
|
||
+ RelocationSourceList &SourcesForSection = RelocationSources[SectionID];
|
||
+ for (unsigned i = 0, e = SourcesForSection.size(); i != e; ++i) {
|
||
+ RelocationSource &R = SourcesForSection[i];
|
||
+ RelocationEntry &RE = Relocations[R.SectionID][R.Index];
|
||
+ resolveRelocationEntry(R.SectionID, RE);
|
||
+ }
|
||
}
|
||
|
||
bool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) {
|
||
Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
|
||
===================================================================
|
||
--- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (revision 152265)
|
||
+++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (working copy)
|
||
@@ -26,48 +26,183 @@
|
||
namespace llvm {
|
||
class RuntimeDyldMachO : public RuntimeDyldImpl {
|
||
|
||
- // For each symbol, keep a list of relocations based on it. Anytime
|
||
- // its address is reassigned (the JIT re-compiled the function, e.g.),
|
||
- // the relocations get re-resolved.
|
||
- // The symbol (or section) the relocation is sourced from is the Key
|
||
- // in the relocation list where it's stored.
|
||
+ // For each section, keep a list of relocatable pieces of data that
|
||
+ // reside in it. If the section moves, or the sections whose
|
||
+ // locations the data depends on move, re-resolve the relocations
|
||
+ // based on that movement.
|
||
+ //
|
||
+ // RelocationEntry structures correspond to one or two Mach-O
|
||
+ // relocation_info or scattered_relocation_info structures --
|
||
+ // usually one, but two iff the original has a paired structure
|
||
+ // following it.
|
||
+ //
|
||
+ // To facilitate updating a relocation when its sources move, we
|
||
+ // also keep RelocationSource structures associated with the sections
|
||
+ // whose location the data depends on.
|
||
+
|
||
+ // FIXME: Use SymbolLoc for this instead. Where should the enum live?
|
||
+ struct SectionOffset {
|
||
+ uint64_t Offset; // Offset of the location into its section.
|
||
+ unsigned ID; // The section the location is contained in.
|
||
+
|
||
+ enum {
|
||
+ NoSectionID = 0xffff0000,
|
||
+ UnresolvedSourceID = 0xffffffff
|
||
+ };
|
||
+ };
|
||
+
|
||
struct RelocationEntry {
|
||
- unsigned SectionID; // Section the relocation is contained in.
|
||
- uint64_t Offset; // Offset into the section for the relocation.
|
||
- uint32_t Data; // Second word of the raw macho relocation entry.
|
||
- int64_t Addend; // Addend encoded in the instruction itself, if any,
|
||
- // plus the offset into the source section for
|
||
- // the symbol once the relocation is resolvable.
|
||
+ SectionOffset Sources[2]; // The section/offset pairs this relocation
|
||
+ // refers to.
|
||
+ // If the original Mach-O relocation entries used
|
||
+ // relocation_info, this data is computed from
|
||
+ // r_symbolnum and the offsets are locked to 0.
|
||
+ // (The only offset is determined by the addend.)
|
||
+ // If the original Mach-O relocation entries used
|
||
+ // scattered_relocation_info, this data, including
|
||
+ // offsets, is computed by looking r_value up in
|
||
+ // the section table.
|
||
|
||
- RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
|
||
- : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
|
||
+ uint64_t Offset; // The offset of the data to be relocated.
|
||
+ // We don't use a SectionOffset because this
|
||
+ // RelocationEntry is already associated with the
|
||
+ // proper Section.
|
||
+
|
||
+ int64_t Addend; // Addend encoded in the instruction itself, if any,
|
||
+ // plus the offset into the source section for
|
||
+ // the symbol once the relocation is resolvable.
|
||
+
|
||
+ uint32_t Data; // If the original Mach-O relocation entry was a
|
||
+ // relocation_info, the bitfield { r_symbolnum,
|
||
+ // r_pcrel, r_length, r_extern, r_type }.
|
||
+ // If the original Mach-O relocation entry was a
|
||
+ // scattered_relocation_info, the bitfield
|
||
+ // { r_address, r_type, r_length, r_pcrel,
|
||
+ // r_scattered }.
|
||
+
|
||
+ bool Scattered; // True iff this relocation is scattered.
|
||
+
|
||
+ bool isPCRel()
|
||
+ {
|
||
+ if (Scattered)
|
||
+ return (Data & 0x40000000) >> 30;
|
||
+ else
|
||
+ return (Data & 0x01000000) >> 24;
|
||
+ }
|
||
+
|
||
+ uint8_t type()
|
||
+ {
|
||
+ if (Scattered)
|
||
+ return (Data & 0x0f000000) >> 24;
|
||
+ else
|
||
+ return (Data & 0xf0000000) >> 28;
|
||
+ }
|
||
+
|
||
+ // Returns the decoded version of the length field
|
||
+ uint8_t length()
|
||
+ {
|
||
+ if (Scattered)
|
||
+ return 1 << ((Data & 0x30000000) >> 28);
|
||
+ else
|
||
+ return 1 << ((Data & 0x0e000000) >> 25);
|
||
+ }
|
||
+
|
||
+ // Used with an ordinary relocation entry, where the source_offsets are not
|
||
+ // known yet.
|
||
+ RelocationEntry(uint64_t offset, // See the Offset field.
|
||
+ unsigned source_id0, // The section ID for the first source.
|
||
+ unsigned source_id1, // The section ID for the second source.
|
||
+ uint32_t data, // See the Data field.
|
||
+ int64_t addend) // See the Addend field.
|
||
+ : Offset(offset),
|
||
+ Addend(addend),
|
||
+ Data(data),
|
||
+ Scattered(false) {
|
||
+ Sources[0].ID = source_id0;
|
||
+ Sources[0].Offset = 0;
|
||
+ Sources[1].ID = source_id1;
|
||
+ Sources[1].Offset = 0;
|
||
+ }
|
||
+
|
||
+ // Used with a scattered relocation entry, where the source_offsets can be
|
||
+ // derived from the value.
|
||
+ RelocationEntry(uint64_t offset, // See the Offset field.
|
||
+ unsigned source_id0, // The section ID for the first source.
|
||
+ uint64_t source_off0, // The offset for the first source.
|
||
+ unsigned source_id1, // The section ID for the second source.
|
||
+ uint64_t source_off1, // The offset for the second source.
|
||
+ uint32_t data, // See the Data field.
|
||
+ int64_t addend) // See the Addend field.
|
||
+ : Offset(offset),
|
||
+ Addend(addend),
|
||
+ Data(data),
|
||
+ Scattered(true) {
|
||
+ Sources[0].ID = source_id0;
|
||
+ Sources[0].Offset = source_off0;
|
||
+ Sources[1].ID = source_id1;
|
||
+ Sources[1].Offset = source_off1;
|
||
+ }
|
||
};
|
||
typedef SmallVector<RelocationEntry, 4> RelocationList;
|
||
- // Relocations to sections already loaded. Indexed by SectionID which is the
|
||
- // source of the address. The target where the address will be writen is
|
||
- // SectionID/Offset in the relocation itself.
|
||
+
|
||
+ // For each section, keep a list of sources that are used by relocations in
|
||
+ // other sections. Whenever a relocation gets created, create one or two
|
||
+ // corresponding relocation sources. Whenever relocations are re-resolved
|
||
+ // for a section, also re-resolve the relocations corresponding to that
|
||
+ // section's relocation targets.
|
||
+ struct RelocationSource {
|
||
+ unsigned SectionID; // Section whose RelocationList contains the relocation.
|
||
+ uint32_t Index : 24; // Index of the RelocatonEntry in that RelocationList.
|
||
+ uint8_t SourceIdx : 1; // Index of this source in the RelocationEntry's Sources.
|
||
+
|
||
+ RelocationSource(unsigned id,
|
||
+ uint32_t index,
|
||
+ uint8_t source_idx)
|
||
+ : SectionID(id),
|
||
+ Index(index),
|
||
+ SourceIdx(source_idx) {}
|
||
+ };
|
||
+ typedef SmallVector<RelocationSource, 4> RelocationSourceList;
|
||
+
|
||
+ // Relocations which refer to already-loaded section. Indexed by SectionID
|
||
+ // which is the section containing the relocatable data.
|
||
IndexedMap<RelocationList> Relocations;
|
||
+ // Targets corresponding to Relocations.
|
||
+ IndexedMap<RelocationSourceList> RelocationSources;
|
||
// Relocations to symbols that are not yet resolved. Must be external
|
||
// relocations by definition. Indexed by symbol name.
|
||
- StringMap<RelocationList> UnresolvedRelocations;
|
||
+ StringMap<RelocationSourceList> UnresolvedRelocations;
|
||
|
||
+ bool resolveRelocationEntry(unsigned SectionID,
|
||
+ RelocationEntry &RE);
|
||
bool resolveRelocation(uint8_t *LocalAddress,
|
||
uint64_t FinalAddress,
|
||
- uint64_t Value,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
bool isPCRel,
|
||
unsigned Type,
|
||
unsigned Size,
|
||
int64_t Addend);
|
||
+ bool resolveI386Relocation(uint8_t *LocalAddress,
|
||
+ uint64_t FinalAddress,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
+ bool isPCRel,
|
||
+ unsigned Type,
|
||
+ unsigned Size,
|
||
+ int64_t Addend);
|
||
bool resolveX86_64Relocation(uint8_t *LocalAddress,
|
||
uint64_t FinalAddress,
|
||
- uint64_t Value,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
bool isPCRel,
|
||
unsigned Type,
|
||
unsigned Size,
|
||
int64_t Addend);
|
||
bool resolveARMRelocation(uint8_t *LocalAddress,
|
||
uint64_t FinalAddress,
|
||
- uint64_t Value,
|
||
+ uint64_t FinalSource1,
|
||
+ uint64_t FinalSource2,
|
||
bool isPCRel,
|
||
unsigned Type,
|
||
unsigned Size,
|
||
Index: lib/MC/MCDisassembler/Disassembler.cpp
|
||
===================================================================
|
||
--- lib/MC/MCDisassembler/Disassembler.cpp (revision 152265)
|
||
+++ lib/MC/MCDisassembler/Disassembler.cpp (working copy)
|
||
@@ -15,7 +15,9 @@
|
||
#include "llvm/MC/MCDisassembler.h"
|
||
#include "llvm/MC/MCInst.h"
|
||
#include "llvm/MC/MCInstPrinter.h"
|
||
+#include "llvm/MC/MCInstrInfo.h"
|
||
#include "llvm/MC/MCRegisterInfo.h"
|
||
+#include "llvm/MC/MCSubtargetInfo.h"
|
||
#include "llvm/Support/MemoryObject.h"
|
||
#include "llvm/Support/TargetRegistry.h"
|
||
#include "llvm/Support/TargetSelect.h"
|
||
@@ -86,7 +88,7 @@
|
||
LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType,
|
||
GetOpInfo, SymbolLookUp,
|
||
TheTarget, MAI, MRI,
|
||
- Ctx, DisAsm, IP);
|
||
+ STI, Ctx, DisAsm, IP);
|
||
assert(DC && "Allocation failure!");
|
||
|
||
return DC;
|
||
Index: lib/MC/MCDisassembler/Disassembler.h
|
||
===================================================================
|
||
--- lib/MC/MCDisassembler/Disassembler.h (revision 152265)
|
||
+++ lib/MC/MCDisassembler/Disassembler.h (working copy)
|
||
@@ -29,6 +29,7 @@
|
||
class MCDisassembler;
|
||
class MCInstPrinter;
|
||
class MCRegisterInfo;
|
||
+class MCSubtargetInfo;
|
||
class Target;
|
||
|
||
//
|
||
@@ -61,6 +62,8 @@
|
||
llvm::OwningPtr<const llvm::MCAsmInfo> MAI;
|
||
// The register information for the target architecture.
|
||
llvm::OwningPtr<const llvm::MCRegisterInfo> MRI;
|
||
+ // The subtarget information for the target architecture.
|
||
+ llvm::OwningPtr<const llvm::MCSubtargetInfo> MSI;
|
||
// The assembly context for creating symbols and MCExprs.
|
||
llvm::OwningPtr<const llvm::MCContext> Ctx;
|
||
// The disassembler for the target architecture.
|
||
@@ -78,6 +81,7 @@
|
||
LLVMSymbolLookupCallback symbolLookUp,
|
||
const Target *theTarget, const MCAsmInfo *mAI,
|
||
const MCRegisterInfo *mRI,
|
||
+ const MCSubtargetInfo *mSI,
|
||
llvm::MCContext *ctx, const MCDisassembler *disAsm,
|
||
MCInstPrinter *iP) : TripleName(tripleName),
|
||
DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo),
|
||
@@ -85,6 +89,7 @@
|
||
CommentStream(CommentsToEmit) {
|
||
MAI.reset(mAI);
|
||
MRI.reset(mRI);
|
||
+ MSI.reset(mSI);
|
||
Ctx.reset(ctx);
|
||
DisAsm.reset(disAsm);
|
||
IP.reset(iP);
|