mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-21 04:25:45 -04:00
[AArch64] [Windows] Misc fixes for llvm-readobj -unwind.
Use getImageBase() helper to compute the image base. Fix various offsets/addresses/masks so they're actually correct. This allows decoding unwind info from DLLs, and unwind info from object files containing multiple functions. Differential Revision: https://reviews.llvm.org/D54015 llvm-svn: 346036
This commit is contained in:
parent
66f7b435ed
commit
d2941b43f4
@ -339,7 +339,7 @@ struct EpilogueScope {
|
|||||||
return ((ES & 0xff000000) >> 24);
|
return ((ES & 0xff000000) >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EpilogueStartIndexAArch64() const {
|
uint16_t EpilogueStartIndexAArch64() const {
|
||||||
return ((ES & 0xffc00000) >> 22);
|
return ((ES & 0xffc00000) >> 22);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -428,7 +428,7 @@ struct ExceptionDataRecord {
|
|||||||
|
|
||||||
inline size_t HeaderWords(const ExceptionDataRecord &XR) {
|
inline size_t HeaderWords(const ExceptionDataRecord &XR) {
|
||||||
if (XR.isAArch64)
|
if (XR.isAArch64)
|
||||||
return (XR.Data[0] & 0xffc0000) ? 1 : 2;
|
return (XR.Data[0] & 0xffc00000) ? 1 : 2;
|
||||||
return (XR.Data[0] & 0xff800000) ? 1 : 2;
|
return (XR.Data[0] & 0xff800000) ? 1 : 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
// CHECK: Prologue [
|
// CHECK: Prologue [
|
||||||
// CHECK: 0xdf ; Bad opcode!
|
// CHECK: 0xdf ; Bad opcode!
|
||||||
|
// CHECK: 0xff ; Bad opcode!
|
||||||
// CHECK: 0xd600 ; stp x19, lr, [sp, #0]
|
// CHECK: 0xd600 ; stp x19, lr, [sp, #0]
|
||||||
// CHECK: 0x01 ; sub sp, #16
|
// CHECK: 0x01 ; sub sp, #16
|
||||||
// CHECK: 0xe4 ; end
|
// CHECK: 0xe4 ; end
|
||||||
@ -48,6 +49,6 @@
|
|||||||
.long 0x10800012
|
.long 0x10800012
|
||||||
.long 0x8
|
.long 0x8
|
||||||
.long 0xe
|
.long 0xe
|
||||||
.long 0x100d6df
|
.long 0x00d6ffdf
|
||||||
.long 0xe3e3e3e4
|
.long 0xe3e3e401
|
||||||
|
|
||||||
|
@ -788,7 +788,7 @@ void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
|
|||||||
if ((isAArch64 && (DI >= array_lengthof(Ring64))) ||
|
if ((isAArch64 && (DI >= array_lengthof(Ring64))) ||
|
||||||
(!isAArch64 && (DI >= array_lengthof(Ring)))) {
|
(!isAArch64 && (DI >= array_lengthof(Ring)))) {
|
||||||
SW.startLine() << format("0x%02x ; Bad opcode!\n",
|
SW.startLine() << format("0x%02x ; Bad opcode!\n",
|
||||||
Opcodes.data()[Offset]);
|
Opcodes.data()[OI]);
|
||||||
++OI;
|
++OI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -871,6 +871,8 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
|
|||||||
SW.printNumber("EpilogueStartIndex",
|
SW.printNumber("EpilogueStartIndex",
|
||||||
isAArch64 ? ES.EpilogueStartIndexAArch64()
|
isAArch64 ? ES.EpilogueStartIndexAArch64()
|
||||||
: ES.EpilogueStartIndexARM());
|
: ES.EpilogueStartIndexARM());
|
||||||
|
if (ES.ES & ~0xffc3ffff)
|
||||||
|
SW.printNumber("ReservedBits", (ES.ES >> 18) & 0xF);
|
||||||
|
|
||||||
ListScope Opcodes(SW, "Opcodes");
|
ListScope Opcodes(SW, "Opcodes");
|
||||||
decodeOpcodes(XData.UnwindByteCode(),
|
decodeOpcodes(XData.UnwindByteCode(),
|
||||||
@ -887,10 +889,15 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
|
|||||||
+ (XData.E() ? 0 : XData.EpilogueCount())
|
+ (XData.E() ? 0 : XData.EpilogueCount())
|
||||||
+ XData.CodeWords();
|
+ XData.CodeWords();
|
||||||
|
|
||||||
ErrorOr<SymbolRef> Symbol =
|
ErrorOr<SymbolRef> Symbol = getRelocatedSymbol(
|
||||||
getRelocatedSymbol(COFF, Section, HandlerOffset * sizeof(uint32_t));
|
COFF, Section, Offset + HandlerOffset * sizeof(uint32_t));
|
||||||
if (!Symbol)
|
if (!Symbol)
|
||||||
Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true);
|
Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true);
|
||||||
|
if (!Symbol) {
|
||||||
|
ListScope EHS(SW, "ExceptionHandler");
|
||||||
|
SW.printString("Routine", "(null)");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Expected<StringRef> Name = Symbol->getName();
|
Expected<StringRef> Name = Symbol->getName();
|
||||||
if (!Name) {
|
if (!Name) {
|
||||||
@ -950,10 +957,7 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
|
|||||||
}
|
}
|
||||||
FunctionAddress = *FunctionAddressOrErr;
|
FunctionAddress = *FunctionAddressOrErr;
|
||||||
} else {
|
} else {
|
||||||
const pe32_header *PEHeader;
|
FunctionAddress = COFF.getImageBase() + RF.BeginAddress;
|
||||||
if (COFF.getPE32Header(PEHeader))
|
|
||||||
return false;
|
|
||||||
FunctionAddress = PEHeader->ImageBase + RF.BeginAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
|
SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
|
||||||
@ -988,22 +992,18 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
|
|||||||
}
|
}
|
||||||
section_iterator SI = *SIOrErr;
|
section_iterator SI = *SIOrErr;
|
||||||
|
|
||||||
return dumpXDataRecord(COFF, *SI, FunctionAddress, Address);
|
// FIXME: Do we need to add an offset from the relocation?
|
||||||
|
return dumpXDataRecord(COFF, *SI, FunctionAddress,
|
||||||
|
RF.ExceptionInformationRVA());
|
||||||
} else {
|
} else {
|
||||||
const pe32_header *PEHeader;
|
uint64_t Address = COFF.getImageBase() + RF.ExceptionInformationRVA();
|
||||||
if (COFF.getPE32Header(PEHeader))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint64_t Address = PEHeader->ImageBase + RF.ExceptionInformationRVA();
|
|
||||||
SW.printString("ExceptionRecord", formatSymbol("", Address));
|
SW.printString("ExceptionRecord", formatSymbol("", Address));
|
||||||
|
|
||||||
ErrorOr<SectionRef> Section =
|
ErrorOr<SectionRef> Section = getSectionContaining(COFF, Address);
|
||||||
getSectionContaining(COFF, RF.ExceptionInformationRVA());
|
|
||||||
if (!Section)
|
if (!Section)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return dumpXDataRecord(COFF, *Section, FunctionAddress,
|
return dumpXDataRecord(COFF, *Section, FunctionAddress, Address);
|
||||||
RF.ExceptionInformationRVA());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,8 +1073,8 @@ bool Decoder::dumpProcedureDataEntry(const COFFObjectFile &COFF,
|
|||||||
if (Entry.Flag() == RuntimeFunctionFlag::RFF_Unpacked)
|
if (Entry.Flag() == RuntimeFunctionFlag::RFF_Unpacked)
|
||||||
return dumpUnpackedEntry(COFF, Section, Offset, Index, Entry);
|
return dumpUnpackedEntry(COFF, Section, Offset, Index, Entry);
|
||||||
if (isAArch64) {
|
if (isAArch64) {
|
||||||
llvm::errs() << "Packed unwind data not yet supported for ARM64\n";
|
SW.startLine() << "Packed unwind data not yet supported for ARM64\n";
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
return dumpPackedEntry(COFF, Section, Offset, Index, Entry);
|
return dumpPackedEntry(COFF, Section, Offset, Index, Entry);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user