DIDT_LineDwo,
DIDT_Loc,
DIDT_LocDwo,
+ DIDT_Macro,
DIDT_Ranges,
DIDT_Pubnames,
DIDT_Pubtypes,
#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"
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;
/// 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);
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;
DWARFSection LineSection;
StringRef StringSection;
StringRef RangeSection;
+ StringRef MacinfoSection;
StringRef PubNamesSection;
StringRef PubTypesSection;
StringRef GnuPubNamesSection;
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; }
--- /dev/null
+//===-- DWARFDebugMacro.h ---------------------------------------*- C++ -*-===//\r
+//\r
+// The LLVM Compiler Infrastructure\r
+//\r
+// This file is distributed under the University of Illinois Open Source\r
+// License. See LICENSE.TXT for details.\r
+//\r
+//===----------------------------------------------------------------------===//\r
+\r
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H\r
+#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H\r
+\r
+#include "llvm/ADT/SmallVector.h"\r
+#include "llvm/ADT/StringRef.h"\r
+#include "llvm/Support/DataExtractor.h"\r
+#include "llvm/Support/Dwarf.h"\r
+\r
+namespace llvm {\r
+\r
+class raw_ostream;\r
+\r
+class DWARFDebugMacro {\r
+ /// A single macro entry within a macro list.\r
+ struct Entry {\r
+ /// The type of the macro entry.\r
+ uint32_t Type;\r
+ union {\r
+ /// The source line where the macro is defined.\r
+ uint64_t Line;\r
+ /// Vendor extension constant value.\r
+ uint64_t ExtConstant;\r
+ };\r
+\r
+ union {\r
+ /// The string (name, value) of the macro entry.\r
+ const char *MacroStr;\r
+ // An unsigned integer indicating the identity of the source file.\r
+ uint64_t File;\r
+ /// Vendor extension string.\r
+ const char *ExtStr;\r
+ };\r
+ };\r
+\r
+ typedef SmallVector<Entry, 4> MacroList;\r
+\r
+ /// A list of all the macro entries in the debug_macinfo section.\r
+ MacroList Macros;\r
+\r
+public:\r
+ DWARFDebugMacro() {}\r
+ /// Print the macro list found within the debug_macinfo section.\r
+ void dump(raw_ostream &OS) const;\r
+ /// Parse the debug_macinfo section accessible via the 'data' parameter.\r
+ void parse(DataExtractor data);\r
+};\r
+\r
+}\r
+\r
+#endif\r
// 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.
DWARFDebugInfoEntry.cpp
DWARFDebugLine.cpp
DWARFDebugLoc.cpp
+ DWARFDebugMacro.cpp
DWARFDebugRangeList.cpp
DWARFFormValue.cpp
DWARFTypeUnit.cpp
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";
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)
.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)
--- /dev/null
+//===-- DWARFDebugMacro.cpp -----------------------------------------------===//\r
+//\r
+// The LLVM Compiler Infrastructure\r
+//\r
+// This file is distributed under the University of Illinois Open Source\r
+// License. See LICENSE.TXT for details.\r
+//\r
+//===----------------------------------------------------------------------===//\r
+\r
+#include "SyntaxHighlighting.h"\r
+#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"\r
+#include "llvm/Support/Compiler.h"\r
+#include "llvm/Support/Dwarf.h"\r
+#include "llvm/Support/Format.h"\r
+#include "llvm/Support/raw_ostream.h"\r
+\r
+using namespace llvm;\r
+using namespace dwarf;\r
+using namespace syntax;\r
+\r
+void DWARFDebugMacro::dump(raw_ostream &OS) const {\r
+ unsigned IndLevel = 0;\r
+ for (const Entry &E : Macros) {\r
+ // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,\r
+ // this check handles the case of corrupted ".debug_macinfo" section.\r
+ if (IndLevel > 0)\r
+ IndLevel -= (E.Type == DW_MACINFO_end_file);\r
+ // Print indentation.\r
+ for (unsigned I = 0; I < IndLevel; I++)\r
+ OS << " ";\r
+ IndLevel += (E.Type == DW_MACINFO_start_file);\r
+\r
+ WithColor(OS, syntax::Macro).get() << MacinfoString(E.Type);\r
+ switch (E.Type) {\r
+ default:\r
+ // Got a corrupted ".debug_macinfo" section (invalid macinfo type).\r
+ break;\r
+ case DW_MACINFO_define:\r
+ case DW_MACINFO_undef:\r
+ OS << " - lineno: " << E.Line;\r
+ OS << " macro: " << E.MacroStr;\r
+ break;\r
+ case DW_MACINFO_start_file:\r
+ OS << " - lineno: " << E.Line;\r
+ OS << " filenum: " << E.File;\r
+ break;\r
+ case DW_MACINFO_end_file:\r
+ break;\r
+ case DW_MACINFO_vendor_ext:\r
+ OS << " - constant: " << E.ExtConstant;\r
+ OS << " string: " << E.ExtStr;\r
+ break;\r
+ }\r
+ OS << "\n";\r
+ }\r
+}\r
+\r
+void DWARFDebugMacro::parse(DataExtractor data) {\r
+ uint32_t Offset = 0;\r
+ while (data.isValidOffset(Offset)) {\r
+ // A macro list entry consists of:\r
+ Entry E;\r
+ // 1. Macinfo type\r
+ E.Type = data.getULEB128(&Offset);\r
+\r
+ if (E.Type == 0) {\r
+ // Reached end of ".debug_macinfo" section.\r
+ return;\r
+ }\r
+\r
+ switch (E.Type) {\r
+ default:\r
+ // Got a corrupted ".debug_macinfo" section (invalid macinfo type).\r
+ // Push the corrupted entry to the list and halt parsing.\r
+ E.Type = DW_MACINFO_invalid;\r
+ Macros.push_back(E);\r
+ return;\r
+ case DW_MACINFO_define:\r
+ case DW_MACINFO_undef:\r
+ // 2. Source line\r
+ E.Line = data.getULEB128(&Offset);\r
+ // 3. Macro string\r
+ E.MacroStr = data.getCStr(&Offset);\r
+ break;\r
+ case DW_MACINFO_start_file:\r
+ // 2. Source line\r
+ E.Line = data.getULEB128(&Offset);\r
+ // 3. Source file id\r
+ E.File = data.getULEB128(&Offset);\r
+ break;\r
+ case DW_MACINFO_end_file:\r
+ break;\r
+ case DW_MACINFO_vendor_ext:\r
+ // 2. Vendor extension constant\r
+ E.ExtConstant = data.getULEB128(&Offset);\r
+ // 3. Vendor extension string\r
+ E.ExtStr = data.getCStr(&Offset);\r
+ break;\r
+ }\r
+\r
+ Macros.push_back(E);\r
+ }\r
+}\r
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;
}
}
}
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.
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;
}
--- /dev/null
+#define M4 Value4\r
--- /dev/null
+#define M1 Value1\r
+#include "dwarfdump-macro.h"\r
+#define M2(x, y) ((x)+(y)* Value2)\r
+\r
+// Built with GCC\r
+// $ mkdir -p /tmp/dbginfo\r
+// $ cp dwarfdump-macro.cc /tmp/dbginfo\r
+// $ cp dwarfdump-macro.h /tmp/dbginfo\r
+// $ cp dwarfdump-macro-cmd.h /tmp/dbginfo\r
+// $ cd /tmp/dbginfo\r
+// $ g++ -c -g3 -O0 -DM3=Value3 -include dwarfdump-macro-cmd.h dwarfdump-macro.cc -o <output>\r
--- /dev/null
+\r
+\r
+\r
+#undef M1\r
+#define M1 NewValue1\r
--- /dev/null
+RUN: llvm-dwarfdump -debug-dump=macro %p/Inputs/dwarfdump-macro.o \\r
+RUN: | FileCheck %s -check-prefix TEST_MACINFO\r
+RUN: llvm-dwarfdump -debug-dump=line %p/Inputs/dwarfdump-macro.o \\r
+RUN: | FileCheck %s -check-prefix TEST_LINE\r
+\r
+\r
+; This test verifies that llvm-dwarfdump tools know how to read .debug_macinfo\r
+; section. It also checks that the file numbers fits with those in the\r
+; .debug_line section.\r
+TEST_MACINFO: .debug_macinfo contents:\r
+TEST_MACINFO: DW_MACINFO_define - lineno: 0 macro: M3 Value3\r
+TEST_MACINFO: DW_MACINFO_start_file - lineno: 0 filenum: 1\r
+TEST_MACINFO: DW_MACINFO_start_file - lineno: 0 filenum: 2\r
+TEST_MACINFO: DW_MACINFO_define - lineno: 1 macro: M4 Value4\r
+TEST_MACINFO: DW_MACINFO_end_file\r
+TEST_MACINFO: DW_MACINFO_define - lineno: 1 macro: M1 Value1\r
+TEST_MACINFO: DW_MACINFO_start_file - lineno: 2 filenum: 3\r
+TEST_MACINFO: DW_MACINFO_undef - lineno: 4 macro: M1\r
+TEST_MACINFO: DW_MACINFO_define - lineno: 5 macro: M1 NewValue1\r
+TEST_MACINFO: DW_MACINFO_end_file\r
+TEST_MACINFO: DW_MACINFO_define - lineno: 3 macro: M2(x,y) ((x)+(y)* Value2)\r
+TEST_MACINFO: DW_MACINFO_end_file\r
+\r
+TEST_LINE: .debug_line contents:\r
+TEST_LINE: file_names[ 1] 0 0x00000000 0x00000000 dwarfdump-macro.cc\r
+TEST_LINE: file_names[ 2] 1 0x00000000 0x00000000 dwarfdump-macro-cmd.h\r
+TEST_LINE: file_names[ 3] 0 0x00000000 0x00000000 dwarfdump-macro.h\r
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"),