From 65d7d51529323933ff89df088ea20e0c33043b71 Mon Sep 17 00:00:00 2001 From: Amjad Aboud Date: Thu, 12 Nov 2015 09:38:54 +0000 Subject: [PATCH] dwarfdump: Added macro support to llvm-dwarfdump tool. Added "macro" option to "-debug-dump" flag, which trigger parsing and dumping of the ".debug_macinfo" section. Differential Revision: http://reviews.llvm.org/D14294 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252866 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DIContext.h | 1 + include/llvm/DebugInfo/DWARF/DWARFContext.h | 8 ++ include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h | 59 ++++++++++++++ include/llvm/Support/Dwarf.h | 1 + lib/DebugInfo/DWARF/CMakeLists.txt | 1 + lib/DebugInfo/DWARF/DWARFContext.cpp | 16 ++++ lib/DebugInfo/DWARF/DWARFDebugMacro.cpp | 103 +++++++++++++++++++++++++ lib/DebugInfo/DWARF/SyntaxHighlighting.cpp | 1 + lib/DebugInfo/DWARF/SyntaxHighlighting.h | 2 +- lib/Support/Dwarf.cpp | 1 + test/DebugInfo/Inputs/dwarfdump-macro-cmd.h | 1 + test/DebugInfo/Inputs/dwarfdump-macro.cc | 11 +++ test/DebugInfo/Inputs/dwarfdump-macro.h | 5 ++ test/DebugInfo/Inputs/dwarfdump-macro.o | Bin 0 -> 5616 bytes test/DebugInfo/debugmacinfo.test | 27 +++++++ tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 1 + 16 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h create mode 100644 lib/DebugInfo/DWARF/DWARFDebugMacro.cpp create mode 100644 test/DebugInfo/Inputs/dwarfdump-macro-cmd.h create mode 100644 test/DebugInfo/Inputs/dwarfdump-macro.cc create mode 100644 test/DebugInfo/Inputs/dwarfdump-macro.h create mode 100644 test/DebugInfo/Inputs/dwarfdump-macro.o create mode 100644 test/DebugInfo/debugmacinfo.test diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index eff0e3e6786..6659a97a042 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -112,6 +112,7 @@ enum DIDumpType { DIDT_LineDwo, DIDT_Loc, DIDT_LocDwo, + DIDT_Macro, DIDT_Ranges, DIDT_Pubnames, DIDT_Pubtypes, diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index 66204d7443e..32beeea45d6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -18,6 +18,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" @@ -45,6 +46,7 @@ class DWARFContext : public DIContext { std::unique_ptr Aranges; std::unique_ptr Line; std::unique_ptr DebugFrame; + std::unique_ptr Macro; DWARFUnitSection DWOCUs; std::vector> DWOTUs; @@ -161,6 +163,9 @@ public: /// Get a pointer to the parsed frame information object. const DWARFDebugFrame *getDebugFrame(); + /// Get a pointer to the parsed DebugMacro object. + const DWARFDebugMacro *getDebugMacro(); + /// Get a pointer to a parsed line table corresponding to a compile unit. const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu); @@ -184,6 +189,7 @@ public: virtual const DWARFSection &getLineSection() = 0; virtual StringRef getStringSection() = 0; virtual StringRef getRangeSection() = 0; + virtual StringRef getMacinfoSection() = 0; virtual StringRef getPubNamesSection() = 0; virtual StringRef getPubTypesSection() = 0; virtual StringRef getGnuPubNamesSection() = 0; @@ -234,6 +240,7 @@ class DWARFContextInMemory : public DWARFContext { DWARFSection LineSection; StringRef StringSection; StringRef RangeSection; + StringRef MacinfoSection; StringRef PubNamesSection; StringRef PubTypesSection; StringRef GnuPubNamesSection; @@ -272,6 +279,7 @@ public: const DWARFSection &getLineSection() override { return LineSection; } StringRef getStringSection() override { return StringSection; } StringRef getRangeSection() override { return RangeSection; } + StringRef getMacinfoSection() override { return MacinfoSection; } StringRef getPubNamesSection() override { return PubNamesSection; } StringRef getPubTypesSection() override { return PubTypesSection; } StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h new file mode 100644 index 00000000000..f7910962a03 --- /dev/null +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h @@ -0,0 +1,59 @@ +//===-- DWARFDebugMacro.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Dwarf.h" + +namespace llvm { + +class raw_ostream; + +class DWARFDebugMacro { + /// A single macro entry within a macro list. + struct Entry { + /// The type of the macro entry. + uint32_t Type; + union { + /// The source line where the macro is defined. + uint64_t Line; + /// Vendor extension constant value. + uint64_t ExtConstant; + }; + + union { + /// The string (name, value) of the macro entry. + const char *MacroStr; + // An unsigned integer indicating the identity of the source file. + uint64_t File; + /// Vendor extension string. + const char *ExtStr; + }; + }; + + typedef SmallVector MacroList; + + /// A list of all the macro entries in the debug_macinfo section. + MacroList Macros; + +public: + DWARFDebugMacro() {} + /// Print the macro list found within the debug_macinfo section. + void dump(raw_ostream &OS) const; + /// Parse the debug_macinfo section accessible via the 'data' parameter. + void parse(DataExtractor data); +}; + +} + +#endif diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index b30aa80bbe3..8d71353b167 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -40,6 +40,7 @@ enum LLVMConstants : uint32_t { // LLVM mock tags (see also llvm/Support/Dwarf.def). DW_TAG_invalid = ~0U, // Tag for invalid results. DW_VIRTUALITY_invalid = ~0U, // Virtuality for invalid results. + DW_MACINFO_invalid = ~0U, // Macinfo type for invalid results. // Other constants. DWARF_VERSION = 4, // Default dwarf version we output. diff --git a/lib/DebugInfo/DWARF/CMakeLists.txt b/lib/DebugInfo/DWARF/CMakeLists.txt index b3df0422acf..7104c5f1039 100644 --- a/lib/DebugInfo/DWARF/CMakeLists.txt +++ b/lib/DebugInfo/DWARF/CMakeLists.txt @@ -10,6 +10,7 @@ add_llvm_library(LLVMDebugInfoDWARF DWARFDebugInfoEntry.cpp DWARFDebugLine.cpp DWARFDebugLoc.cpp + DWARFDebugMacro.cpp DWARFDebugRangeList.cpp DWARFFormValue.cpp DWARFTypeUnit.cpp diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index ac92a632b58..f4624851737 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -127,6 +127,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { getDebugFrame()->dump(OS); } + if (DumpType == DIDT_All || DumpType == DIDT_Macro) { + OS << "\n.debug_macinfo contents:\n"; + getDebugMacro()->dump(OS); + } + uint32_t offset = 0; if (DumpType == DIDT_All || DumpType == DIDT_Aranges) { OS << "\n.debug_aranges contents:\n"; @@ -341,6 +346,16 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() { return DebugFrame.get(); } +const DWARFDebugMacro *DWARFContext::getDebugMacro() { + if (Macro) + return Macro.get(); + + DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0); + Macro.reset(new DWARFDebugMacro()); + Macro->parse(MacinfoData); + return Macro.get(); +} + const DWARFLineTable * DWARFContext::getLineTableForUnit(DWARFUnit *U) { if (!Line) @@ -611,6 +626,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, .Case("debug_frame", &DebugFrameSection) .Case("debug_str", &StringSection) .Case("debug_ranges", &RangeSection) + .Case("debug_macinfo", &MacinfoSection) .Case("debug_pubnames", &PubNamesSection) .Case("debug_pubtypes", &PubTypesSection) .Case("debug_gnu_pubnames", &GnuPubNamesSection) diff --git a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp new file mode 100644 index 00000000000..b6555fa6272 --- /dev/null +++ b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp @@ -0,0 +1,103 @@ +//===-- DWARFDebugMacro.cpp -----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SyntaxHighlighting.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace dwarf; +using namespace syntax; + +void DWARFDebugMacro::dump(raw_ostream &OS) const { + unsigned IndLevel = 0; + for (const Entry &E : Macros) { + // There should not be DW_MACINFO_end_file when IndLevel is Zero. However, + // this check handles the case of corrupted ".debug_macinfo" section. + if (IndLevel > 0) + IndLevel -= (E.Type == DW_MACINFO_end_file); + // Print indentation. + for (unsigned I = 0; I < IndLevel; I++) + OS << " "; + IndLevel += (E.Type == DW_MACINFO_start_file); + + WithColor(OS, syntax::Macro).get() << MacinfoString(E.Type); + switch (E.Type) { + default: + // Got a corrupted ".debug_macinfo" section (invalid macinfo type). + break; + case DW_MACINFO_define: + case DW_MACINFO_undef: + OS << " - lineno: " << E.Line; + OS << " macro: " << E.MacroStr; + break; + case DW_MACINFO_start_file: + OS << " - lineno: " << E.Line; + OS << " filenum: " << E.File; + break; + case DW_MACINFO_end_file: + break; + case DW_MACINFO_vendor_ext: + OS << " - constant: " << E.ExtConstant; + OS << " string: " << E.ExtStr; + break; + } + OS << "\n"; + } +} + +void DWARFDebugMacro::parse(DataExtractor data) { + uint32_t Offset = 0; + while (data.isValidOffset(Offset)) { + // A macro list entry consists of: + Entry E; + // 1. Macinfo type + E.Type = data.getULEB128(&Offset); + + if (E.Type == 0) { + // Reached end of ".debug_macinfo" section. + return; + } + + switch (E.Type) { + default: + // Got a corrupted ".debug_macinfo" section (invalid macinfo type). + // Push the corrupted entry to the list and halt parsing. + E.Type = DW_MACINFO_invalid; + Macros.push_back(E); + return; + case DW_MACINFO_define: + case DW_MACINFO_undef: + // 2. Source line + E.Line = data.getULEB128(&Offset); + // 3. Macro string + E.MacroStr = data.getCStr(&Offset); + break; + case DW_MACINFO_start_file: + // 2. Source line + E.Line = data.getULEB128(&Offset); + // 3. Source file id + E.File = data.getULEB128(&Offset); + break; + case DW_MACINFO_end_file: + break; + case DW_MACINFO_vendor_ext: + // 2. Vendor extension constant + E.ExtConstant = data.getULEB128(&Offset); + // 3. Vendor extension string + E.ExtStr = data.getCStr(&Offset); + break; + } + + Macros.push_back(E); + } +} diff --git a/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp b/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp index a6b4c6549ca..4f561d062b1 100644 --- a/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp +++ b/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp @@ -27,6 +27,7 @@ WithColor::WithColor(llvm::raw_ostream &OS, enum HighlightColor Type) : OS(OS) { case Tag: OS.changeColor(llvm::raw_ostream::BLUE); break; case Attribute: OS.changeColor(llvm::raw_ostream::CYAN); break; case Enumerator: OS.changeColor(llvm::raw_ostream::MAGENTA); break; + case Macro: OS.changeColor(llvm::raw_ostream::RED); break; } } } diff --git a/lib/DebugInfo/DWARF/SyntaxHighlighting.h b/lib/DebugInfo/DWARF/SyntaxHighlighting.h index 946a31308aa..16e68351d5e 100644 --- a/lib/DebugInfo/DWARF/SyntaxHighlighting.h +++ b/lib/DebugInfo/DWARF/SyntaxHighlighting.h @@ -17,7 +17,7 @@ namespace dwarf { namespace syntax { // Symbolic names for various syntax elements. -enum HighlightColor { Address, String, Tag, Attribute, Enumerator }; +enum HighlightColor { Address, String, Tag, Attribute, Enumerator, Macro }; /// An RAII object that temporarily switches an output stream to a /// specific color. diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp index 5764e458f2b..dd740384de3 100644 --- a/lib/Support/Dwarf.cpp +++ b/lib/Support/Dwarf.cpp @@ -468,6 +468,7 @@ const char *llvm::dwarf::MacinfoString(unsigned Encoding) { case DW_MACINFO_start_file: return "DW_MACINFO_start_file"; case DW_MACINFO_end_file: return "DW_MACINFO_end_file"; case DW_MACINFO_vendor_ext: return "DW_MACINFO_vendor_ext"; + case DW_MACINFO_invalid: return "DW_MACINFO_invalid"; } return nullptr; } diff --git a/test/DebugInfo/Inputs/dwarfdump-macro-cmd.h b/test/DebugInfo/Inputs/dwarfdump-macro-cmd.h new file mode 100644 index 00000000000..1209f66d5fe --- /dev/null +++ b/test/DebugInfo/Inputs/dwarfdump-macro-cmd.h @@ -0,0 +1 @@ +#define M4 Value4 diff --git a/test/DebugInfo/Inputs/dwarfdump-macro.cc b/test/DebugInfo/Inputs/dwarfdump-macro.cc new file mode 100644 index 00000000000..42b2c6ab54a --- /dev/null +++ b/test/DebugInfo/Inputs/dwarfdump-macro.cc @@ -0,0 +1,11 @@ +#define M1 Value1 +#include "dwarfdump-macro.h" +#define M2(x, y) ((x)+(y)* Value2) + +// Built with GCC +// $ mkdir -p /tmp/dbginfo +// $ cp dwarfdump-macro.cc /tmp/dbginfo +// $ cp dwarfdump-macro.h /tmp/dbginfo +// $ cp dwarfdump-macro-cmd.h /tmp/dbginfo +// $ cd /tmp/dbginfo +// $ g++ -c -g3 -O0 -DM3=Value3 -include dwarfdump-macro-cmd.h dwarfdump-macro.cc -o diff --git a/test/DebugInfo/Inputs/dwarfdump-macro.h b/test/DebugInfo/Inputs/dwarfdump-macro.h new file mode 100644 index 00000000000..75b35f0e4c2 --- /dev/null +++ b/test/DebugInfo/Inputs/dwarfdump-macro.h @@ -0,0 +1,5 @@ + + + +#undef M1 +#define M1 NewValue1 diff --git a/test/DebugInfo/Inputs/dwarfdump-macro.o b/test/DebugInfo/Inputs/dwarfdump-macro.o new file mode 100644 index 0000000000000000000000000000000000000000..5f1cb5e2707fff49506985eed40b65d91767e739 GIT binary patch literal 5616 zcmbtYTW{mW6{ajFO`F8YHf@n0FG_%-avd=wXLt*W#I#6BM5s$e`m%i?WLxVs)|R)n z+<5bn#{l^){So~=ed}9*JhbP`O+!i>7wrJz%zWQDXXczUGaTx>BR1NK%U7wrJaq=|+Kr9WT zEb}7nmSxLkowJu$_jmXceMSz(d6C3QrawAF1! zi~`e9A+a@Uzzw4lNwX29-r)vrO&|R!s$x)P*!=xCDag|z3J5IVaoJR!Zr%{|@L{`W!0{`O_*Qdi5Hp+3p zWA?BQ>%2@(CLq-A*p9nfA#6)=#MdZ@J=d`v?iaHJs8S$R9JYco!jjukqgHShQ<^*DiTI%Hm;47F@045&BnP-;dInXM``gCN2m~gK1`FM97Sww#>5AZkX1}wzPSyKiv3cm20bo>+ z+8ttvuyW%ntd_`_gp~@hcwi-gPWz$ng~TQ_@El^h7+_rrMuZh$I*x1kBya<$9LuH< zXiaJrXq2=l^(-2K2AH+y9h+L;C5ANpv3nW?8bBmn^bHu zzI>D+OpG0bKCx-&64!^!_?~My^F1^m&KTwx%MUS$=hzT#N^Bd}IdLt|!DU<(UZu%4 zt$;ePwtR;Mt_v9>u=pWWp=P_1EMh{Q>=0&S2Y~|zqGvfS!695*)7g+S=G4ZdDP}!u z5FU6xXd8x~y#m&f6jHH0gn~>$SXY3MCY{iY`No#^@z4v+kd-9#Dy$Z+q*JBx!vj1y z@Q`H*uuKa}Z3K_%9>{HwbP?BFAc3QNU@FoF*l+w$P%6v`5|B973HCCRUT|OFnZPQn z$W{EY-3s>_hnQEwv&yh=bnCtmzTP3KjL@9(Y`XG}Yf1NjQvOLb<{%Ix=8H;N-0Y(A zRW%aOrB&UE+oWdrF~3y+R0DFX&2O6YQ@9IGOSqr(*ejGJ<}e2+iw@wjS0%)K1XkUr z)TE~0g2NQ<4>oDFr*Nek%$6;NcgXIi%o4j!!UNtlSvtZ?AUi6uiATjd2b&TuN8_4c z$=*;2B&!&d<57n1Dt;g6ce`+w9wlY|bkr@o$5&aPu2!i*ZR7Z$r$8eeM#f9>vOdjSQ{Ar zK6wbdQc=94xEC_kF9L-PhwNI+7GBQ2LAV`gJ4y%%wwmN9jIAISi~I8Ga&iBllvq#9 zN@sNZesTFAM6fAzH59%=l|eWd*!%M!jmsV$#TY+6+k>>xyz1_!+8Rp%q>*eee>g6r3pUc*A{;)L6^VxD{n5TDl(43#%UzD@c)7$yq4D)t= zH4_jUSF|BVb14d+);a}-4fE{g`g#uEqUPdeIX7XJoxA1i>;?Ot{{J2yvoCVPz<&$$ zvaffvcKsiOPk_U}7WlsmE5ZF$v(l>T{{h&y;P=1ke+IfZe!c7q;CD5mF8dYmbqrOG zgq|&GS=D8~0HW>_%38nW8vo#x@h;SFzz==J@*%H`uc5BnMCyCNvwv7b8>_nP@dga# z{)rDL*$%Jev#$RP2*fNYAZqVD-bib>)R*;Nf#0P6ozTaBp!6d3Wc@9WvaQSgUFho= zw(GJ_0IRPZl#}{DU`H!;ee7>(ylnpX0dKX00*3J&_|^0GOTadb|DnkLZ@3xttdFmV zS_9>_jeq^S2D2_4rJG=w$0kp3ew${9_@Ylt){{7(Y^NYof DumpType( clEnumValN(DIDT_Loc, "loc", ".debug_loc"), clEnumValN(DIDT_LocDwo, "loc.dwo", ".debug_loc.dwo"), clEnumValN(DIDT_Frames, "frames", ".debug_frame"), + clEnumValN(DIDT_Macro, "macro", ".debug_macinfo"), clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"), clEnumValN(DIDT_Pubnames, "pubnames", ".debug_pubnames"), clEnumValN(DIDT_Pubtypes, "pubtypes", ".debug_pubtypes"), -- 2.11.0