diff options
| author | Amjad Aboud <amjad.aboud@intel.com> | 2015-11-12 09:38:54 +0000 |
|---|---|---|
| committer | Amjad Aboud <amjad.aboud@intel.com> | 2015-11-12 09:38:54 +0000 |
| commit | e59cc3e540ee7b9840f4bdbe334179340feca6da (patch) | |
| tree | 9b04b20373ce51ae419b23446f3f133be8d0940f | |
| parent | c498ba3a3e39eb94b79e3127eeda8aee2fcfbe68 (diff) | |
| download | bcm5719-llvm-e59cc3e540ee7b9840f4bdbe334179340feca6da.tar.gz bcm5719-llvm-e59cc3e540ee7b9840f4bdbe334179340feca6da.zip | |
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
llvm-svn: 252866
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DIContext.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h | 8 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h | 59 | ||||
| -rw-r--r-- | llvm/include/llvm/Support/Dwarf.h | 1 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp | 103 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Support/Dwarf.cpp | 1 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/dwarfdump-macro-cmd.h | 1 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/dwarfdump-macro.cc | 11 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/dwarfdump-macro.h | 5 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/dwarfdump-macro.o | bin | 0 -> 5616 bytes | |||
| -rw-r--r-- | llvm/test/DebugInfo/debugmacinfo.test | 27 | ||||
| -rw-r--r-- | llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 1 |
16 files changed, 237 insertions, 1 deletions
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h index eff0e3e6786..6659a97a042 100644 --- a/llvm/include/llvm/DebugInfo/DIContext.h +++ b/llvm/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/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h index 66204d7443e..32beeea45d6 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/llvm/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<DWARFDebugAranges> Aranges; std::unique_ptr<DWARFDebugLine> Line; std::unique_ptr<DWARFDebugFrame> DebugFrame; + std::unique_ptr<DWARFDebugMacro> Macro; DWARFUnitSection<DWARFCompileUnit> DWOCUs; std::vector<DWARFUnitSection<DWARFTypeUnit>> 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/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h new file mode 100644 index 00000000000..f7910962a03 --- /dev/null +++ b/llvm/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<Entry, 4> 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/llvm/include/llvm/Support/Dwarf.h b/llvm/include/llvm/Support/Dwarf.h index b30aa80bbe3..8d71353b167 100644 --- a/llvm/include/llvm/Support/Dwarf.h +++ b/llvm/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/llvm/lib/DebugInfo/DWARF/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt index b3df0422acf..7104c5f1039 100644 --- a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt +++ b/llvm/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/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index ac92a632b58..f4624851737 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/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/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp new file mode 100644 index 00000000000..b6555fa6272 --- /dev/null +++ b/llvm/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/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp b/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp index a6b4c6549ca..4f561d062b1 100644 --- a/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.cpp +++ b/llvm/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/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h b/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h index 946a31308aa..16e68351d5e 100644 --- a/llvm/lib/DebugInfo/DWARF/SyntaxHighlighting.h +++ b/llvm/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/llvm/lib/Support/Dwarf.cpp b/llvm/lib/Support/Dwarf.cpp index 5764e458f2b..dd740384de3 100644 --- a/llvm/lib/Support/Dwarf.cpp +++ b/llvm/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/llvm/test/DebugInfo/Inputs/dwarfdump-macro-cmd.h b/llvm/test/DebugInfo/Inputs/dwarfdump-macro-cmd.h new file mode 100644 index 00000000000..1209f66d5fe --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/dwarfdump-macro-cmd.h @@ -0,0 +1 @@ +#define M4 Value4
diff --git a/llvm/test/DebugInfo/Inputs/dwarfdump-macro.cc b/llvm/test/DebugInfo/Inputs/dwarfdump-macro.cc new file mode 100644 index 00000000000..42b2c6ab54a --- /dev/null +++ b/llvm/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 <output>
diff --git a/llvm/test/DebugInfo/Inputs/dwarfdump-macro.h b/llvm/test/DebugInfo/Inputs/dwarfdump-macro.h new file mode 100644 index 00000000000..75b35f0e4c2 --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/dwarfdump-macro.h @@ -0,0 +1,5 @@ +
+
+
+#undef M1
+#define M1 NewValue1
diff --git a/llvm/test/DebugInfo/Inputs/dwarfdump-macro.o b/llvm/test/DebugInfo/Inputs/dwarfdump-macro.o Binary files differnew file mode 100644 index 00000000000..5f1cb5e2707 --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/dwarfdump-macro.o diff --git a/llvm/test/DebugInfo/debugmacinfo.test b/llvm/test/DebugInfo/debugmacinfo.test new file mode 100644 index 00000000000..3f95169a7a4 --- /dev/null +++ b/llvm/test/DebugInfo/debugmacinfo.test @@ -0,0 +1,27 @@ +RUN: llvm-dwarfdump -debug-dump=macro %p/Inputs/dwarfdump-macro.o \
+RUN: | FileCheck %s -check-prefix TEST_MACINFO
+RUN: llvm-dwarfdump -debug-dump=line %p/Inputs/dwarfdump-macro.o \
+RUN: | FileCheck %s -check-prefix TEST_LINE
+
+
+; This test verifies that llvm-dwarfdump tools know how to read .debug_macinfo
+; section. It also checks that the file numbers fits with those in the
+; .debug_line section.
+TEST_MACINFO: .debug_macinfo contents:
+TEST_MACINFO: DW_MACINFO_define - lineno: 0 macro: M3 Value3
+TEST_MACINFO: DW_MACINFO_start_file - lineno: 0 filenum: 1
+TEST_MACINFO: DW_MACINFO_start_file - lineno: 0 filenum: 2
+TEST_MACINFO: DW_MACINFO_define - lineno: 1 macro: M4 Value4
+TEST_MACINFO: DW_MACINFO_end_file
+TEST_MACINFO: DW_MACINFO_define - lineno: 1 macro: M1 Value1
+TEST_MACINFO: DW_MACINFO_start_file - lineno: 2 filenum: 3
+TEST_MACINFO: DW_MACINFO_undef - lineno: 4 macro: M1
+TEST_MACINFO: DW_MACINFO_define - lineno: 5 macro: M1 NewValue1
+TEST_MACINFO: DW_MACINFO_end_file
+TEST_MACINFO: DW_MACINFO_define - lineno: 3 macro: M2(x,y) ((x)+(y)* Value2)
+TEST_MACINFO: DW_MACINFO_end_file
+
+TEST_LINE: .debug_line contents:
+TEST_LINE: file_names[ 1] 0 0x00000000 0x00000000 dwarfdump-macro.cc
+TEST_LINE: file_names[ 2] 1 0x00000000 0x00000000 dwarfdump-macro-cmd.h
+TEST_LINE: file_names[ 3] 0 0x00000000 0x00000000 dwarfdump-macro.h
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 4352c15f336..d742eb3ec34 100644 --- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -60,6 +60,7 @@ static cl::opt<DIDumpType> 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"), |

