Skip to content

Commit 69c8fb1

Browse files
committed
[DWARF5] Added support for debug_macro section parsing and dumping in llvm-dwarfdump.
Summary: This patch adds parsing and dumping DWARFv5 .debug_macro section in llvm-dwarfdump, it does not introduce any new switch. Existing switch "--debug-macro" should be used to dump macinfo or macro section. Reviewed By: dblaikie, ikudrin, jhenderson Differential Revision: https://reviews.llvm.org/D73086
1 parent bd1d70b commit 69c8fb1

File tree

9 files changed

+344
-45
lines changed

9 files changed

+344
-45
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class DWARFContext : public DIContext {
6161
std::unique_ptr<DWARFDebugLine> Line;
6262
std::unique_ptr<DWARFDebugFrame> DebugFrame;
6363
std::unique_ptr<DWARFDebugFrame> EHFrame;
64+
std::unique_ptr<DWARFDebugMacro> Macro;
6465
std::unique_ptr<DWARFDebugMacro> Macinfo;
6566
std::unique_ptr<DWARFDebugNames> Names;
6667
std::unique_ptr<AppleAcceleratorTable> AppleNames;
@@ -104,6 +105,15 @@ class DWARFContext : public DIContext {
104105

105106
std::unique_ptr<const DWARFObject> DObj;
106107

108+
/// Helper enum to distinguish between macro[.dwo] and macinfo[.dwo]
109+
/// section.
110+
enum MacroSecType {
111+
MacinfoSection,
112+
MacinfoDwoSection,
113+
MacroSection
114+
// FIXME: Add support for.debug_macro.dwo section.
115+
};
116+
107117
public:
108118
DWARFContext(std::unique_ptr<const DWARFObject> DObj,
109119
std::string DWPName = "",
@@ -272,12 +282,15 @@ class DWARFContext : public DIContext {
272282
/// Get a pointer to the parsed eh frame information object.
273283
const DWARFDebugFrame *getEHFrame();
274284

275-
/// Get a pointer to the parsed DebugMacro object.
285+
/// Get a pointer to the parsed DebugMacinfo information object.
276286
const DWARFDebugMacro *getDebugMacinfo();
277287

278-
/// Get a pointer to the parsed dwo DebugMacro object.
288+
/// Get a pointer to the parsed DebugMacinfoDWO information object.
279289
const DWARFDebugMacro *getDebugMacinfoDWO();
280290

291+
/// Get a pointer to the parsed DebugMacro information object.
292+
const DWARFDebugMacro *getDebugMacro();
293+
281294
/// Get a reference to the parsed accelerator table object.
282295
const DWARFDebugNames &getDebugNames();
283296

@@ -382,6 +395,10 @@ class DWARFContext : public DIContext {
382395
}
383396

384397
private:
398+
/// Parse a macro[.dwo] or macinfo[.dwo] section.
399+
std::unique_ptr<DWARFDebugMacro>
400+
parseMacroOrMacinfo(MacroSecType SectionType);
401+
385402
/// Return the compile unit which contains instruction with provided
386403
/// address.
387404
/// TODO: change input parameter from "uint64_t Address"

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,56 @@
1010
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
1111

1212
#include "llvm/ADT/SmallVector.h"
13-
#include "llvm/Support/DataExtractor.h"
13+
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
14+
#include "llvm/Support/Errc.h"
15+
#include "llvm/Support/Error.h"
16+
#include "llvm/Support/WithColor.h"
1417
#include <cstdint>
1518

1619
namespace llvm {
1720

1821
class raw_ostream;
1922

2023
class DWARFDebugMacro {
24+
/// DWARFv5 section 6.3.1 Macro Information Header.
25+
enum HeaderFlagMask {
26+
#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_##NAME = ID,
27+
#include "llvm/BinaryFormat/Dwarf.def"
28+
};
29+
struct MacroHeader {
30+
/// Macro version information number.
31+
uint16_t Version = 0;
32+
33+
/// The bits of the flags field are interpreted as a set of flags, some of
34+
/// which may indicate that additional fields follow. The following flags,
35+
/// beginning with the least significant bit, are defined:
36+
/// offset_size_flag:
37+
/// If the offset_size_flag is zero, the header is for a 32-bit DWARF
38+
/// format macro section and all offsets are 4 bytes long; if it is one,
39+
/// the header is for a 64-bit DWARF format macro section and all offsets
40+
/// are 8 bytes long.
41+
/// debug_line_offset_flag:
42+
/// If the debug_line_offset_flag is one, the debug_line_offset field (see
43+
/// below) is present. If zero, that field is omitted.
44+
/// opcode_operands_table_flag:
45+
/// If the opcode_operands_table_flag is one, the opcode_operands_table
46+
/// field (see below) is present. If zero, that field is omitted.
47+
uint8_t Flags;
48+
49+
/// debug_line_offset
50+
/// An offset in the .debug_line section of the beginning of the line
51+
/// number information in the containing compilation unit, encoded as a
52+
/// 4-byte offset for a 32-bit DWARF format macro section and an 8-byte
53+
/// offset for a 64-bit DWARF format macro section.
54+
uint64_t DebugLineOffset;
55+
56+
/// Print the macro header from the debug_macro section.
57+
void dumpMacroHeader(raw_ostream &OS) const;
58+
59+
/// Parse the debug_macro header.
60+
Error parseMacroHeader(DWARFDataExtractor Data, uint64_t *Offset);
61+
};
62+
2163
/// A single macro entry within a macro list.
2264
struct Entry {
2365
/// The type of the macro entry.
@@ -40,6 +82,10 @@ class DWARFDebugMacro {
4082
};
4183

4284
struct MacroList {
85+
// A value 0 in the `Header.Version` field indicates that we're parsing
86+
// a macinfo[.dwo] section which doesn't have header itself, hence
87+
// for that case other fields in the `Header` are uninitialized.
88+
MacroHeader Header;
4389
SmallVector<Entry, 4> Macros;
4490
uint64_t Offset;
4591
};
@@ -50,11 +96,13 @@ class DWARFDebugMacro {
5096
public:
5197
DWARFDebugMacro() = default;
5298

53-
/// Print the macro list found within the debug_macinfo section.
99+
/// Print the macro list found within the debug_macinfo/debug_macro section.
54100
void dump(raw_ostream &OS) const;
55101

56-
/// Parse the debug_macinfo section accessible via the 'data' parameter.
57-
void parse(DataExtractor data);
102+
/// Parse the debug_macinfo/debug_macro section accessible via the 'Data'
103+
/// parameter.
104+
Error parse(DataExtractor StringExtractor, DWARFDataExtractor Data,
105+
bool IsMacro);
58106

59107
/// Return whether the section has any entries.
60108
bool empty() const { return MacroLists.empty(); }

llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class DWARFObject {
4747
virtual StringRef getStrSection() const { return ""; }
4848
virtual const DWARFSection &getRangesSection() const { return Dummy; }
4949
virtual const DWARFSection &getRnglistsSection() const { return Dummy; }
50+
virtual const DWARFSection &getMacroSection() const { return Dummy; }
5051
virtual StringRef getMacinfoSection() const { return ""; }
5152
virtual StringRef getMacinfoDWOSection() const { return ""; }
5253
virtual const DWARFSection &getPubnamesSection() const { return Dummy; }

llvm/lib/DebugInfo/DWARF/DWARFContext.cpp

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,36 @@ static void dumpRnglistsSection(
292292
}
293293
}
294294

295+
std::unique_ptr<DWARFDebugMacro>
296+
DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
297+
auto Macro = std::make_unique<DWARFDebugMacro>();
298+
auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
299+
if (Error Err = Macro->parse(getStringExtractor(), Data, IsMacro)) {
300+
RecoverableErrorHandler(std::move(Err));
301+
Macro = nullptr;
302+
}
303+
};
304+
switch (SectionType) {
305+
case MacinfoSection: {
306+
DWARFDataExtractor Data(DObj->getMacinfoSection(), isLittleEndian(), 0);
307+
ParseAndDump(Data, /*IsMacro=*/false);
308+
break;
309+
}
310+
case MacinfoDwoSection: {
311+
DWARFDataExtractor Data(DObj->getMacinfoDWOSection(), isLittleEndian(), 0);
312+
ParseAndDump(Data, /*IsMacro=*/false);
313+
break;
314+
}
315+
case MacroSection: {
316+
DWARFDataExtractor Data(*DObj, DObj->getMacroSection(), isLittleEndian(),
317+
0);
318+
ParseAndDump(Data, /*IsMacro=*/true);
319+
break;
320+
}
321+
}
322+
return std::move(Macro);
323+
}
324+
295325
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
296326
DWARFDataExtractor Data,
297327
const MCRegisterInfo *MRI,
@@ -444,14 +474,22 @@ void DWARFContext::dump(
444474
DObj->getEHFrameSection().Data))
445475
getEHFrame()->dump(OS, getRegisterInfo(), *Off);
446476

477+
if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
478+
DObj->getMacroSection().Data)) {
479+
if (auto Macro = getDebugMacro())
480+
Macro->dump(OS);
481+
}
482+
447483
if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
448484
DObj->getMacinfoSection())) {
449-
getDebugMacinfo()->dump(OS);
485+
if (auto Macinfo = getDebugMacinfo())
486+
Macinfo->dump(OS);
450487
}
451488

452489
if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
453490
DObj->getMacinfoDWOSection())) {
454-
getDebugMacinfoDWO()->dump(OS);
491+
if (auto MacinfoDWO = getDebugMacinfoDWO())
492+
MacinfoDWO->dump(OS);
455493
}
456494

457495
if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
@@ -815,27 +853,24 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
815853
return DebugFrame.get();
816854
}
817855

818-
const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
819-
if (MacinfoDWO)
820-
return MacinfoDWO.get();
821-
822-
DataExtractor MacinfoDWOData(DObj->getMacinfoDWOSection(), isLittleEndian(),
823-
0);
824-
MacinfoDWO.reset(new DWARFDebugMacro());
825-
MacinfoDWO->parse(MacinfoDWOData);
826-
return MacinfoDWO.get();
856+
const DWARFDebugMacro *DWARFContext::getDebugMacro() {
857+
if (!Macro)
858+
Macro = parseMacroOrMacinfo(MacroSection);
859+
return Macro.get();
827860
}
828861

829862
const DWARFDebugMacro *DWARFContext::getDebugMacinfo() {
830-
if (Macinfo)
831-
return Macinfo.get();
832-
833-
DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
834-
Macinfo.reset(new DWARFDebugMacro());
835-
Macinfo->parse(MacinfoData);
863+
if (!Macinfo)
864+
Macinfo = parseMacroOrMacinfo(MacinfoSection);
836865
return Macinfo.get();
837866
}
838867

868+
const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
869+
if (!MacinfoDWO)
870+
MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
871+
return MacinfoDWO.get();
872+
}
873+
839874
template <typename T>
840875
static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
841876
const DWARFSection &Section, StringRef StringSection,
@@ -1476,6 +1511,7 @@ class DWARFObjInMemory final : public DWARFObject {
14761511
DWARFSectionMap PubtypesSection;
14771512
DWARFSectionMap GnuPubnamesSection;
14781513
DWARFSectionMap GnuPubtypesSection;
1514+
DWARFSectionMap MacroSection;
14791515

14801516
DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
14811517
return StringSwitch<DWARFSectionMap *>(Name)
@@ -1503,6 +1539,7 @@ class DWARFObjInMemory final : public DWARFObject {
15031539
.Case("apple_namespaces", &AppleNamespacesSection)
15041540
.Case("apple_namespac", &AppleNamespacesSection)
15051541
.Case("apple_objc", &AppleObjCSection)
1542+
.Case("debug_macro", &MacroSection)
15061543
.Default(nullptr);
15071544
}
15081545

@@ -1847,6 +1884,7 @@ class DWARFObjInMemory final : public DWARFObject {
18471884
const DWARFSection &getRnglistsSection() const override {
18481885
return RnglistsSection;
18491886
}
1887+
const DWARFSection &getMacroSection() const override { return MacroSection; }
18501888
StringRef getMacinfoSection() const override { return MacinfoSection; }
18511889
StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
18521890
const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }

0 commit comments

Comments
 (0)