aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <efriedma@codeaurora.org>2018-11-02 19:59:08 +0000
committerEli Friedman <efriedma@codeaurora.org>2018-11-02 19:59:08 +0000
commitd2941b43f40d24f083b7ed4151d6e882a86d32c3 (patch)
treed656fd5cb469c10774f40d06ed913500bcce5c34
parent66f7b435ed937e410d41626d0194bb5c0646106f (diff)
downloadllvm-d2941b43f40d24f083b7ed4151d6e882a86d32c3.zip
llvm-d2941b43f40d24f083b7ed4151d6e882a86d32c3.tar.gz
llvm-d2941b43f40d24f083b7ed4151d6e882a86d32c3.tar.bz2
[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
-rw-r--r--llvm/include/llvm/Support/ARMWinEH.h4
-rw-r--r--llvm/test/tools/llvm-readobj/arm64-win-error1.s5
-rw-r--r--llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp38
3 files changed, 24 insertions, 23 deletions
diff --git a/llvm/include/llvm/Support/ARMWinEH.h b/llvm/include/llvm/Support/ARMWinEH.h
index 4f05965..6017450 100644
--- a/llvm/include/llvm/Support/ARMWinEH.h
+++ b/llvm/include/llvm/Support/ARMWinEH.h
@@ -339,7 +339,7 @@ struct EpilogueScope {
return ((ES & 0xff000000) >> 24);
}
- uint8_t EpilogueStartIndexAArch64() const {
+ uint16_t EpilogueStartIndexAArch64() const {
return ((ES & 0xffc00000) >> 22);
}
};
@@ -428,7 +428,7 @@ struct ExceptionDataRecord {
inline size_t HeaderWords(const ExceptionDataRecord &XR) {
if (XR.isAArch64)
- return (XR.Data[0] & 0xffc0000) ? 1 : 2;
+ return (XR.Data[0] & 0xffc00000) ? 1 : 2;
return (XR.Data[0] & 0xff800000) ? 1 : 2;
}
}
diff --git a/llvm/test/tools/llvm-readobj/arm64-win-error1.s b/llvm/test/tools/llvm-readobj/arm64-win-error1.s
index ba59edf..cd449ef 100644
--- a/llvm/test/tools/llvm-readobj/arm64-win-error1.s
+++ b/llvm/test/tools/llvm-readobj/arm64-win-error1.s
@@ -7,6 +7,7 @@
// CHECK: Prologue [
// CHECK: 0xdf ; Bad opcode!
+// CHECK: 0xff ; Bad opcode!
// CHECK: 0xd600 ; stp x19, lr, [sp, #0]
// CHECK: 0x01 ; sub sp, #16
// CHECK: 0xe4 ; end
@@ -48,6 +49,6 @@
.long 0x10800012
.long 0x8
.long 0xe
- .long 0x100d6df
- .long 0xe3e3e3e4
+ .long 0x00d6ffdf
+ .long 0xe3e3e401
diff --git a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
index 56dd6c0..eb57589 100644
--- a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
+++ b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
@@ -788,7 +788,7 @@ void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
if ((isAArch64 && (DI >= array_lengthof(Ring64))) ||
(!isAArch64 && (DI >= array_lengthof(Ring)))) {
SW.startLine() << format("0x%02x ; Bad opcode!\n",
- Opcodes.data()[Offset]);
+ Opcodes.data()[OI]);
++OI;
break;
}
@@ -871,6 +871,8 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
SW.printNumber("EpilogueStartIndex",
isAArch64 ? ES.EpilogueStartIndexAArch64()
: ES.EpilogueStartIndexARM());
+ if (ES.ES & ~0xffc3ffff)
+ SW.printNumber("ReservedBits", (ES.ES >> 18) & 0xF);
ListScope Opcodes(SW, "Opcodes");
decodeOpcodes(XData.UnwindByteCode(),
@@ -887,10 +889,15 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
+ (XData.E() ? 0 : XData.EpilogueCount())
+ XData.CodeWords();
- ErrorOr<SymbolRef> Symbol =
- getRelocatedSymbol(COFF, Section, HandlerOffset * sizeof(uint32_t));
+ ErrorOr<SymbolRef> Symbol = getRelocatedSymbol(
+ COFF, Section, Offset + HandlerOffset * sizeof(uint32_t));
if (!Symbol)
Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true);
+ if (!Symbol) {
+ ListScope EHS(SW, "ExceptionHandler");
+ SW.printString("Routine", "(null)");
+ return true;
+ }
Expected<StringRef> Name = Symbol->getName();
if (!Name) {
@@ -950,10 +957,7 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
}
FunctionAddress = *FunctionAddressOrErr;
} else {
- const pe32_header *PEHeader;
- if (COFF.getPE32Header(PEHeader))
- return false;
- FunctionAddress = PEHeader->ImageBase + RF.BeginAddress;
+ FunctionAddress = COFF.getImageBase() + RF.BeginAddress;
}
SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
@@ -988,22 +992,18 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
}
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 {
- const pe32_header *PEHeader;
- if (COFF.getPE32Header(PEHeader))
- return false;
-
- uint64_t Address = PEHeader->ImageBase + RF.ExceptionInformationRVA();
+ uint64_t Address = COFF.getImageBase() + RF.ExceptionInformationRVA();
SW.printString("ExceptionRecord", formatSymbol("", Address));
- ErrorOr<SectionRef> Section =
- getSectionContaining(COFF, RF.ExceptionInformationRVA());
+ ErrorOr<SectionRef> Section = getSectionContaining(COFF, Address);
if (!Section)
return false;
- return dumpXDataRecord(COFF, *Section, FunctionAddress,
- RF.ExceptionInformationRVA());
+ return dumpXDataRecord(COFF, *Section, FunctionAddress, Address);
}
}
@@ -1073,8 +1073,8 @@ bool Decoder::dumpProcedureDataEntry(const COFFObjectFile &COFF,
if (Entry.Flag() == RuntimeFunctionFlag::RFF_Unpacked)
return dumpUnpackedEntry(COFF, Section, Offset, Index, Entry);
if (isAArch64) {
- llvm::errs() << "Packed unwind data not yet supported for ARM64\n";
- return false;
+ SW.startLine() << "Packed unwind data not yet supported for ARM64\n";
+ return true;
}
return dumpPackedEntry(COFF, Section, Offset, Index, Entry);
}