llvm-objdump: Split printCOFFUnwindInfo into small functions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202772 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rui Ueyama 2014-03-04 00:31:48 +00:00
parent 839b3c76d3
commit d1a0a58701

View File

@ -378,27 +378,20 @@ static void printExportTable(const COFFObjectFile *Obj) {
} }
} }
void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { // Given the COFF object file, this function returns the relocations for .pdata
const coff_file_header *Header; // and the pointer to "runtime function" structs.
if (error(Obj->getCOFFHeader(Header))) return; static bool getPDataSection(const COFFObjectFile *Obj,
std::vector<RelocationRef> &Rels,
if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) { const RuntimeFunction *&RFStart, int &NumRFs) {
errs() << "Unsupported image machine type "
"(currently only AMD64 is supported).\n";
return;
}
const coff_section *Pdata = 0;
for (section_iterator SI = Obj->section_begin(), SE = Obj->section_end(); for (section_iterator SI = Obj->section_begin(), SE = Obj->section_end();
SI != SE; ++SI) { SI != SE; ++SI) {
StringRef Name; StringRef Name;
if (error(SI->getName(Name))) continue; if (error(SI->getName(Name)))
continue;
if (Name != ".pdata")
continue;
if (Name != ".pdata") continue; const coff_section *Pdata = Obj->getCOFFSection(SI);
Pdata = Obj->getCOFFSection(SI);
std::vector<RelocationRef> Rels;
for (relocation_iterator RI = SI->relocation_begin(), for (relocation_iterator RI = SI->relocation_begin(),
RE = SI->relocation_end(); RE = SI->relocation_end();
RI != RE; ++RI) RI != RE; ++RI)
@ -408,98 +401,123 @@ void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
std::sort(Rels.begin(), Rels.end(), RelocAddressLess); std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
ArrayRef<uint8_t> Contents; ArrayRef<uint8_t> Contents;
if (error(Obj->getSectionContents(Pdata, Contents))) continue; if (error(Obj->getSectionContents(Pdata, Contents)))
if (Contents.empty()) continue; continue;
if (Contents.empty())
continue;
ArrayRef<RuntimeFunction> RFs( RFStart = reinterpret_cast<const RuntimeFunction *>(Contents.data());
reinterpret_cast<const RuntimeFunction *>(Contents.data()), NumRFs = Contents.size() / sizeof(RuntimeFunction);
Contents.size() / sizeof(RuntimeFunction)); return true;
for (const RuntimeFunction &RF : RFs) { }
const uint64_t SectionOffset = return false;
std::distance(RFs.begin(), &RF) * sizeof(RuntimeFunction); }
outs() << "Function Table:\n"; static void printRuntimeFunction(const COFFObjectFile *Obj,
const RuntimeFunction &RF,
uint64_t SectionOffset,
const std::vector<RelocationRef> &Rels) {
outs() << "Function Table:\n";
outs() << " Start Address: "; outs() << " Start Address: ";
printCOFFSymbolAddress(outs(), Rels, printCOFFSymbolAddress(outs(), Rels,
SectionOffset + SectionOffset +
/*offsetof(RuntimeFunction, StartAddress)*/ 0, /*offsetof(RuntimeFunction, StartAddress)*/ 0,
RF.StartAddress); RF.StartAddress);
outs() << "\n"; outs() << "\n";
outs() << " End Address: "; outs() << " End Address: ";
printCOFFSymbolAddress(outs(), Rels, printCOFFSymbolAddress(outs(), Rels,
SectionOffset + SectionOffset +
/*offsetof(RuntimeFunction, EndAddress)*/ 4, /*offsetof(RuntimeFunction, EndAddress)*/ 4,
RF.EndAddress); RF.EndAddress);
outs() << "\n"; outs() << "\n";
outs() << " Unwind Info Address: "; outs() << " Unwind Info Address: ";
printCOFFSymbolAddress( printCOFFSymbolAddress(outs(), Rels,
outs(), Rels, SectionOffset + SectionOffset +
/*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8, /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
RF.UnwindInfoOffset); RF.UnwindInfoOffset);
outs() << "\n"; outs() << "\n";
ArrayRef<uint8_t> XContents; ArrayRef<uint8_t> XContents;
uint64_t UnwindInfoOffset = 0; uint64_t UnwindInfoOffset = 0;
if (error(getSectionContents(Obj, Rels, SectionOffset + if (error(getSectionContents(
/*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8, Obj, Rels, SectionOffset +
XContents, UnwindInfoOffset))) continue; /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
if (XContents.empty()) continue; XContents, UnwindInfoOffset)))
return;
if (XContents.empty())
return;
UnwindInfoOffset += RF.UnwindInfoOffset; UnwindInfoOffset += RF.UnwindInfoOffset;
if (UnwindInfoOffset > XContents.size()) if (UnwindInfoOffset > XContents.size())
continue; return;
const Win64EH::UnwindInfo *UI = const Win64EH::UnwindInfo *UI = reinterpret_cast<const Win64EH::UnwindInfo *>(
reinterpret_cast<const Win64EH::UnwindInfo *> XContents.data() + UnwindInfoOffset);
(XContents.data() + UnwindInfoOffset);
// The casts to int are required in order to output the value as number. // The casts to int are required in order to output the value as number.
// Without the casts the value would be interpreted as char data (which // Without the casts the value would be interpreted as char data (which
// results in garbage output). // results in garbage output).
outs() << " Version: " << static_cast<int>(UI->getVersion()) << "\n"; outs() << " Version: " << static_cast<int>(UI->getVersion()) << "\n";
outs() << " Flags: " << static_cast<int>(UI->getFlags()); outs() << " Flags: " << static_cast<int>(UI->getFlags());
if (UI->getFlags()) { if (UI->getFlags()) {
if (UI->getFlags() & UNW_ExceptionHandler) if (UI->getFlags() & UNW_ExceptionHandler)
outs() << " UNW_ExceptionHandler"; outs() << " UNW_ExceptionHandler";
if (UI->getFlags() & UNW_TerminateHandler) if (UI->getFlags() & UNW_TerminateHandler)
outs() << " UNW_TerminateHandler"; outs() << " UNW_TerminateHandler";
if (UI->getFlags() & UNW_ChainInfo) if (UI->getFlags() & UNW_ChainInfo)
outs() << " UNW_ChainInfo"; outs() << " UNW_ChainInfo";
} }
outs() << "\n"; outs() << "\n";
outs() << " Size of prolog: " outs() << " Size of prolog: " << static_cast<int>(UI->PrologSize) << "\n";
<< static_cast<int>(UI->PrologSize) << "\n"; outs() << " Number of Codes: " << static_cast<int>(UI->NumCodes) << "\n";
outs() << " Number of Codes: " // Maybe this should move to output of UOP_SetFPReg?
<< static_cast<int>(UI->NumCodes) << "\n"; if (UI->getFrameRegister()) {
// Maybe this should move to output of UOP_SetFPReg? outs() << " Frame register: "
if (UI->getFrameRegister()) { << getUnwindRegisterName(UI->getFrameRegister()) << "\n";
outs() << " Frame register: " outs() << " Frame offset: " << 16 * UI->getFrameOffset() << "\n";
<< getUnwindRegisterName(UI->getFrameRegister()) } else {
<< "\n"; outs() << " No frame pointer used\n";
outs() << " Frame offset: " }
<< 16 * UI->getFrameOffset() if (UI->getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
<< "\n"; // FIXME: Output exception handler data
} else { } else if (UI->getFlags() & UNW_ChainInfo) {
outs() << " No frame pointer used\n"; // FIXME: Output chained unwind info
} }
if (UI->getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
// FIXME: Output exception handler data
} else if (UI->getFlags() & UNW_ChainInfo) {
// FIXME: Output chained unwind info
}
if (UI->NumCodes) if (UI->NumCodes)
outs() << " Unwind Codes:\n"; outs() << " Unwind Codes:\n";
printAllUnwindCodes(ArrayRef<UnwindCode>(&UI->UnwindCodes[0], printAllUnwindCodes(ArrayRef<UnwindCode>(&UI->UnwindCodes[0], UI->NumCodes));
UI->NumCodes));
outs() << "\n\n"; outs() << "\n\n";
outs().flush(); outs().flush();
} }
void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
const coff_file_header *Header;
if (error(Obj->getCOFFHeader(Header)))
return;
if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
errs() << "Unsupported image machine type "
"(currently only AMD64 is supported).\n";
return;
}
std::vector<RelocationRef> Rels;
const RuntimeFunction *RFStart;
int NumRFs;
if (!getPDataSection(Obj, Rels, RFStart, NumRFs))
return;
ArrayRef<RuntimeFunction> RFs(RFStart, NumRFs);
for (const RuntimeFunction &RF : RFs) {
uint64_t SectionOffset =
std::distance(RFs.begin(), &RF) * sizeof(RuntimeFunction);
printRuntimeFunction(Obj, RF, SectionOffset, Rels);
} }
} }