From a72314cd80bdea6a35cb021304073b4f39c609db Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 27 Feb 2015 00:43:58 +0000 Subject: [PATCH] llvm-vtabledump: Dump catch/throw exception structures for MS ABI git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230713 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm-vtabledump/Inputs/eh.obj.coff-i386 | Bin 0 -> 7388 bytes test/tools/llvm-vtabledump/eh.test | 258 ++++++++++++++++++ tools/llvm-vtabledump/llvm-vtabledump.cpp | 109 +++++++- 3 files changed, 365 insertions(+), 2 deletions(-) create mode 100644 test/tools/llvm-vtabledump/Inputs/eh.obj.coff-i386 create mode 100644 test/tools/llvm-vtabledump/eh.test diff --git a/test/tools/llvm-vtabledump/Inputs/eh.obj.coff-i386 b/test/tools/llvm-vtabledump/Inputs/eh.obj.coff-i386 new file mode 100644 index 0000000000000000000000000000000000000000..f34a079bdb888d6ddd4b867fd6476ca5c5556f05 GIT binary patch literal 7388 zcmb7|ZEPIX6^3WM!6cyt)4Gth&@9GD1BA^67UGsxp7qAyv^F@&COD|7lh_V+K5Qr5 z64O#-iKL}fBoc{_NKiLH`GF{+NLaKgt(sH;fkf5($PX$Z2pXLe@0GlhWd(Ju$VlcpC0`N2Iy1J!$m#0*xT^YDe%lJA90 z;D)yT^zPR6i8IO!gQkvrb!ej6x@%OONEo@GcXNJXa7%Sd>x4bkgw9FiJuSI2u*0T8 znB?Zee+JCiBxl0yvEhPC(fb6<1r(r3yyMAuSKwR|nB|(Q$;dbiOz?`2$ zy!i`J7aVMH{Zir;z=WDhUAJy9!I=-`D z=3T_u&OF~HFgeYo##;`iOLH~*p6gKoGpM=Lc;jFWXfCyWhrv8G2W}e7$vJSRz?_)_ zcMiI_-+e6$~~19?YyIV_3fpe&h;%hPE9q=dohki9GnXqujM5; z=(8=~Ub?f`8HUDQicg%hJbj;|@tayUez)N8W6;mWoXc_W9P4ZwH82fTJ;3gipqHRb#ADA{KzSQELx6+3&^S zBH$SjG0L;VU{-3`_`MN_AA^22*03K3&siSbxY5Ul(P$6tFg=GQN|zx;Ea z#B_OX5(o1ob)3&H%{h+n*QQ7QA=AT$H130*8TNs#HKVXG?gKddI?-=Ao@e8C+MesE zlZ$*>j05l|bHQcm`G}nJ>&ZCLZsLgbzJkLv*5Pp+jBD44x})O5mudOlwYX%vOn)gp zeV$G`UcWX|h6@MAc8%vp2AAx88x&V3+%~kOnlBU%WrE4buiIR>i|PY zM~(II-!kXHoz3vh6(ds9Ah<$YWVDL+uxy6Ag~(L!^lK&|`ay7wsK`L&J&|zNWix#D zCGziUkN(!FR*8y?&c#>hY=%#GM0##}@lmI`Ra9iStAgMz@vyJsaJ2Pix=U1Kw2Hr) z*$l5U#{b>aE$3{eAo!W6$mp5!b;Ql|e}}hYLqy{Xf(J!KM(5(gb-kHBCMq&I7sr;( z@WGA9&SzhK!R7kBsG{-v>rTF2t`|f_Mvw4fqq4i@(4paHU9Oi!MMkSGQL2F@M}Fm0 zr$t3ZtC+>D*T>VZT;o*lh>DC>ad$;3TW_cONK|CB>MOB|_Z^+uW}3D_=OVV~JCJUsPmtF5Va2DmUEw z3p~~d9Q;r^WOS~}RjwBoY{gHlRc(KRc* ztLg8JD^;%VefCJ7Q~ga;WOS}?sa%Wqy|T`!{vj$ddR~iFu0P)N1bz|(4&Idx8J#O< zRQA3)_3Gd6bgGX;MMkTxGAdg`eFwOZ7Y`a4t!jbCUCRUN4$v$rGFo-DQt7MmDp8Tq zs#c|ffhN-lR)~s>R^f7z5fah4ZV?q3sJuG>pQYTq9=!jrV=h;hsL1GC-!>{+`Ne-Y zdfcftii(U@EmNxAKVSTqQ;mp7KuP`c`Yy11#j=5YXL`6pDDj1br<%V_5C!Fe^q9W4}yaTJfy?`h5wWZFm)Ulxu zhIhfU5}pn4^ugE`hMP)#=1&ryyW5!ZuLT{$k)tCfMj}T!c5IIvt7FFw8o*#|uvbDz|d$qO4ja`cMyCXZ+?=d#t&=~zE#^S`Pw%6ZZo|vc%?-|?M zIWaIaUL6@54cpA#S!w?r0#Yf(R(pH@x`LcCWVxbUMbxl=RrTKSq5hH4Z5Z&)9iiQf zrV20+5L+{{jM~, StringRef> VFTableEntries; + std::map, StringRef> TIEntries; + std::map, StringRef> CTAEntries; std::map> VBTables; std::map COLs; std::map CHDs; std::map, StringRef> BCAEntries; std::map BCDs; std::map TDs; + std::map TIs; + std::map CTAs; + std::map CTs; std::map, StringRef> VTableSymEntries; std::map, 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(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(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(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 &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 &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 &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, StringRef> &VTTPair : VTTEntries) { StringRef VTTName = VTTPair.first.first;