diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-02-27 00:43:58 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-02-27 00:43:58 +0000 |
| commit | f50d0a5ecf0929c17e2689491377159d5d7631a5 (patch) | |
| tree | e0989aa6d0acda35a276b72921a6e906c5b19399 /llvm/tools/llvm-vtabledump/llvm-vtabledump.cpp | |
| parent | 0b88437ebd4239386971cfac8bd1f020742305f4 (diff) | |
| download | bcm5719-llvm-f50d0a5ecf0929c17e2689491377159d5d7631a5.tar.gz bcm5719-llvm-f50d0a5ecf0929c17e2689491377159d5d7631a5.zip | |
llvm-vtabledump: Dump catch/throw exception structures for MS ABI
llvm-svn: 230713
Diffstat (limited to 'llvm/tools/llvm-vtabledump/llvm-vtabledump.cpp')
| -rw-r--r-- | llvm/tools/llvm-vtabledump/llvm-vtabledump.cpp | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/llvm/tools/llvm-vtabledump/llvm-vtabledump.cpp b/llvm/tools/llvm-vtabledump/llvm-vtabledump.cpp index a21acae02c3..044798297d8 100644 --- a/llvm/tools/llvm-vtabledump/llvm-vtabledump.cpp +++ b/llvm/tools/llvm-vtabledump/llvm-vtabledump.cpp @@ -7,8 +7,7 @@ // //===----------------------------------------------------------------------===// // -// Dumps VTables resident in object files and archives. Note, it currently only -// supports MS-ABI style object files. +// Dumps VTables resident in object files and archives. // //===----------------------------------------------------------------------===// @@ -153,13 +152,32 @@ static void dumpVTables(const ObjectFile *Obj) { uint64_t AlwaysZero; StringRef MangledName; }; + struct ThrowInfo { + uint32_t Flags; + }; + struct CatchableTypeArray { + uint32_t NumEntries; + }; + struct CatchableType { + uint32_t Flags; + uint32_t NonVirtualBaseAdjustmentOffset; + int32_t VirtualBasePointerOffset; + uint32_t VirtualBaseAdjustmentOffset; + uint32_t SizeOrOffset; + StringRef Symbols[2]; + }; std::map<std::pair<StringRef, uint64_t>, StringRef> VFTableEntries; + std::map<std::pair<StringRef, uint64_t>, StringRef> TIEntries; + std::map<std::pair<StringRef, uint64_t>, StringRef> CTAEntries; std::map<StringRef, ArrayRef<little32_t>> VBTables; std::map<StringRef, CompleteObjectLocator> COLs; std::map<StringRef, ClassHierarchyDescriptor> CHDs; std::map<std::pair<StringRef, uint64_t>, StringRef> BCAEntries; std::map<StringRef, BaseClassDescriptor> BCDs; std::map<StringRef, TypeDescriptor> TDs; + std::map<StringRef, ThrowInfo> TIs; + std::map<StringRef, CatchableTypeArray> CTAs; + std::map<StringRef, CatchableType> CTs; std::map<std::pair<StringRef, uint64_t>, StringRef> VTableSymEntries; std::map<std::pair<StringRef, uint64_t>, int64_t> VTableDataEntries; @@ -265,6 +283,39 @@ static void dumpVTables(const ObjectFile *Obj) { return; TDs[SymName] = TD; } + // Throw descriptors in the MS-ABI start with '_TI' + else if (SymName.startswith("_TI") || SymName.startswith("__TI")) { + ThrowInfo TI; + TI.Flags = *reinterpret_cast<const little32_t *>(SymContents.data()); + collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize, + SymName, TIEntries); + TIs[SymName] = TI; + } + // Catchable type arrays in the MS-ABI start with _CTA or __CTA. + else if (SymName.startswith("_CTA") || SymName.startswith("__CTA")) { + CatchableTypeArray CTA; + CTA.NumEntries = + *reinterpret_cast<const little32_t *>(SymContents.data()); + collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize, + SymName, CTAEntries); + CTAs[SymName] = CTA; + } + // Catchable types in the MS-ABI start with _CT or __CT. + else if (SymName.startswith("_CT") || SymName.startswith("__CT")) { + const little32_t *DataPtr = + reinterpret_cast<const little32_t *>(SymContents.data()); + CatchableType CT; + CT.Flags = DataPtr[0]; + CT.NonVirtualBaseAdjustmentOffset = DataPtr[2]; + CT.VirtualBasePointerOffset = DataPtr[3]; + CT.VirtualBaseAdjustmentOffset = DataPtr[4]; + CT.SizeOrOffset = DataPtr[5]; + StringRef *I = std::begin(CT.Symbols), *E = std::end(CT.Symbols); + if (collectRelocatedSymbols(Obj, Sec, SecAddress, SymAddress, SymSize, I, + E)) + return; + CTs[SymName] = CT; + } // Construction vtables in the Itanium ABI start with '_ZTT' or '__ZTT'. else if (SymName.startswith("_ZTT") || SymName.startswith("__ZTT")) { collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize, @@ -356,6 +407,60 @@ static void dumpVTables(const ObjectFile *Obj) { /*UseHexEscapes=*/true) << '\n'; } + for (const std::pair<StringRef, ThrowInfo> &TIPair : TIs) { + StringRef TIName = TIPair.first; + const ThrowInfo &TI = TIPair.second; + auto dumpThrowInfoFlag = [&](const char *Name, uint32_t Flag) { + outs() << TIName << "[Flags." << Name + << "]: " << (TI.Flags & Flag ? "true" : "false") << '\n'; + }; + auto dumpThrowInfoSymbol = [&](const char *Name, int Offset) { + outs() << TIName << '[' << Name << "]: "; + auto Entry = TIEntries.find(std::make_pair(TIName, Offset)); + outs() << (Entry == TIEntries.end() ? "null" : Entry->second) << '\n'; + }; + outs() << TIName << "[Flags]: " << TI.Flags << '\n'; + dumpThrowInfoFlag("Const", 1); + dumpThrowInfoFlag("Volatile", 2); + dumpThrowInfoSymbol("CleanupFn", 4); + dumpThrowInfoSymbol("ForwardCompat", 8); + dumpThrowInfoSymbol("CatchableTypeArray", 12); + } + for (const std::pair<StringRef, CatchableTypeArray> &CTAPair : CTAs) { + StringRef CTAName = CTAPair.first; + const CatchableTypeArray &CTA = CTAPair.second; + + outs() << CTAName << "[NumEntries]: " << CTA.NumEntries << '\n'; + + unsigned Idx = 0; + for (auto I = CTAEntries.lower_bound(std::make_pair(CTAName, 0)), + E = CTAEntries.upper_bound(std::make_pair(CTAName, UINT64_MAX)); + I != E; ++I) + outs() << CTAName << '[' << Idx++ << "]: " << I->second << '\n'; + } + for (const std::pair<StringRef, CatchableType> &CTPair : CTs) { + StringRef CTName = CTPair.first; + const CatchableType &CT = CTPair.second; + auto dumpCatchableTypeFlag = [&](const char *Name, uint32_t Flag) { + outs() << CTName << "[Flags." << Name + << "]: " << (CT.Flags & Flag ? "true" : "false") << '\n'; + }; + outs() << CTName << "[Flags]: " << CT.Flags << '\n'; + dumpCatchableTypeFlag("ScalarType", 1); + dumpCatchableTypeFlag("VirtualInheritance", 4); + outs() << CTName << "[TypeDescriptor]: " << CT.Symbols[0] << '\n'; + outs() << CTName << "[NonVirtualBaseAdjustmentOffset]: " + << CT.NonVirtualBaseAdjustmentOffset << '\n'; + outs() << CTName + << "[VirtualBasePointerOffset]: " << CT.VirtualBasePointerOffset + << '\n'; + outs() << CTName << "[VirtualBaseAdjustmentOffset]: " + << CT.VirtualBaseAdjustmentOffset << '\n'; + outs() << CTName << "[SizeOrOffset]: " << CT.SizeOrOffset << '\n'; + outs() << CTName + << "[CopyCtor]: " << (CT.Symbols[1].empty() ? "null" : CT.Symbols[1]) + << '\n'; + } for (const std::pair<std::pair<StringRef, uint64_t>, StringRef> &VTTPair : VTTEntries) { StringRef VTTName = VTTPair.first.first; |

