Skip to content

Commit f163755

Browse files
committed
[Dsymutil][Debuginfo][NFC] #3 Refactor dsymutil to separate DWARF optimizing part.
Summary: This is the next portion of patches for dsymutil. Create DwarfEmitter interface to generate all debug info tables. Put DwarfEmitter into DwarfLinker library and make tools/dsymutil/DwarfStreamer to be child of DwarfEmitter. It passes check-all testing. MD5 checksum for clang .dSYM bundle matches for the dsymutil with/without that patch. Reviewers: JDevlieghere, friss, dblaikie, aprantl Reviewed By: JDevlieghere Subscribers: merge_guards_bot, hiraditya, thegameg, probinson, llvm-commits Tags: #llvm, #debug-info Differential Revision: https://reviews.llvm.org/D72476
1 parent d0aad9f commit f163755

File tree

6 files changed

+215
-54
lines changed

6 files changed

+215
-54
lines changed

llvm/include/llvm/DWARFLinker/DWARFLinker.h

+112
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
#ifndef LLVM_DWARFLINKER_DWARFLINKER_H
1010
#define LLVM_DWARFLINKER_DWARFLINKER_H
1111

12+
#include "llvm/CodeGen/AccelTable.h"
1213
#include "llvm/CodeGen/NonRelocatableStringpool.h"
1314
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
1415
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
1516
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
17+
#include "llvm/MC/MCDwarf.h"
1618
#include <map>
1719

1820
namespace llvm {
@@ -81,6 +83,116 @@ class AddressesMap {
8183
virtual void clear() = 0;
8284
};
8385

86+
/// DwarfEmitter presents interface to generate all debug info tables.
87+
class DwarfEmitter {
88+
public:
89+
virtual ~DwarfEmitter();
90+
91+
/// Emit DIE containing warnings.
92+
virtual void emitPaperTrailWarningsDie(const Triple &Triple, DIE &Die) = 0;
93+
94+
/// Emit section named SecName with content equals to
95+
/// corresponding section in Obj.
96+
virtual void emitSectionContents(const object::ObjectFile &Obj,
97+
StringRef SecName) = 0;
98+
99+
/// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
100+
virtual void
101+
emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
102+
unsigned DwarfVersion) = 0;
103+
104+
/// Emit the string table described by \p Pool.
105+
virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0;
106+
107+
/// Emit DWARF debug names.
108+
virtual void
109+
emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) = 0;
110+
111+
/// Emit Apple namespaces accelerator table.
112+
virtual void
113+
emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
114+
115+
/// Emit Apple names accelerator table.
116+
virtual void
117+
emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
118+
119+
/// Emit Apple Objective-C accelerator table.
120+
virtual void
121+
emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
122+
123+
/// Emit Apple type accelerator table.
124+
virtual void
125+
emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
126+
127+
/// Emit debug_ranges for \p FuncRange by translating the
128+
/// original \p Entries.
129+
virtual void emitRangesEntries(
130+
int64_t UnitPcOffset, uint64_t OrigLowPc,
131+
const FunctionIntervals::const_iterator &FuncRange,
132+
const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
133+
unsigned AddressSize) = 0;
134+
135+
/// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
136+
/// also emit the debug_ranges entries for the DW_TAG_compile_unit's
137+
/// DW_AT_ranges attribute.
138+
virtual void emitUnitRangesEntries(CompileUnit &Unit,
139+
bool DoRangesSection) = 0;
140+
141+
/// Copy the debug_line over to the updated binary while unobfuscating the
142+
/// file names and directories.
143+
virtual void translateLineTable(DataExtractor LineData, uint64_t Offset) = 0;
144+
145+
/// Emit the line table described in \p Rows into the debug_line section.
146+
virtual void emitLineTableForUnit(MCDwarfLineTableParams Params,
147+
StringRef PrologueBytes,
148+
unsigned MinInstLength,
149+
std::vector<DWARFDebugLine::Row> &Rows,
150+
unsigned AdddressSize) = 0;
151+
152+
/// Emit the .debug_pubnames contribution for \p Unit.
153+
virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
154+
155+
/// Emit the .debug_pubtypes contribution for \p Unit.
156+
virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0;
157+
158+
/// Emit a CIE.
159+
virtual void emitCIE(StringRef CIEBytes) = 0;
160+
161+
/// Emit an FDE with data \p Bytes.
162+
virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
163+
StringRef Bytes) = 0;
164+
165+
/// Emit the debug_loc contribution for \p Unit by copying the entries from
166+
/// \p Dwarf and offsetting them. Update the location attributes to point to
167+
/// the new entries.
168+
virtual void emitLocationsForUnit(
169+
const CompileUnit &Unit, DWARFContext &Dwarf,
170+
std::function<void(StringRef, SmallVectorImpl<uint8_t> &)>
171+
ProcessExpr) = 0;
172+
173+
/// Emit the compilation unit header for \p Unit in the
174+
/// debug_info section.
175+
///
176+
/// As a side effect, this also switches the current Dwarf version
177+
/// of the MC layer to the one of U.getOrigUnit().
178+
virtual void emitCompileUnitHeader(CompileUnit &Unit) = 0;
179+
180+
/// Recursively emit the DIE tree rooted at \p Die.
181+
virtual void emitDIE(DIE &Die) = 0;
182+
183+
/// Returns size of generated .debug_line section.
184+
virtual uint64_t getLineSectionSize() const = 0;
185+
186+
/// Returns size of generated .debug_frame section.
187+
virtual uint64_t getFrameSectionSize() const = 0;
188+
189+
/// Returns size of generated .debug_ranges section.
190+
virtual uint64_t getRangesSectionSize() const = 0;
191+
192+
/// Returns size of generated .debug_info section.
193+
virtual uint64_t getDebugInfoSectionSize() const = 0;
194+
};
195+
84196
} // end namespace llvm
85197

86198
#endif // LLVM_DWARFLINKER_DWARFLINKER_H

llvm/lib/DWARFLinker/DWARFLinker.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ namespace llvm {
1212

1313
AddressesMap::~AddressesMap() {}
1414

15+
DwarfEmitter::~DwarfEmitter() {}
16+
1517
} // namespace llvm

llvm/tools/dsymutil/DwarfLinkerForBinary.cpp

+11-12
Original file line numberDiff line numberDiff line change
@@ -2464,11 +2464,12 @@ void DwarfLinkerForBinary::DIECloner::cloneAllCompileUnits(
24642464
if (!Linker.Streamer)
24652465
return;
24662466

2467+
uint64_t OutputDebugInfoSize = Linker.Streamer->getDebugInfoSectionSize();
24672468
for (auto &CurrentUnit : CompileUnits) {
24682469
auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE();
2469-
CurrentUnit->setStartOffset(Linker.OutputDebugInfoSize);
2470+
CurrentUnit->setStartOffset(OutputDebugInfoSize);
24702471
if (!InputDIE) {
2471-
Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
2472+
OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
24722473
continue;
24732474
}
24742475
if (CurrentUnit->getInfo(0).Keep) {
@@ -2480,7 +2481,7 @@ void DwarfLinkerForBinary::DIECloner::cloneAllCompileUnits(
24802481
CurrentUnit->getOutputUnitDIE());
24812482
}
24822483

2483-
Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
2484+
OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
24842485

24852486
if (Linker.Options.NoOutput)
24862487
continue;
@@ -2522,8 +2523,12 @@ void DwarfLinkerForBinary::DIECloner::cloneAllCompileUnits(
25222523
if (!CurrentUnit->getOutputUnitDIE())
25232524
continue;
25242525

2526+
assert(Linker.Streamer->getDebugInfoSectionSize() ==
2527+
CurrentUnit->getStartOffset());
25252528
Linker.Streamer->emitCompileUnitHeader(*CurrentUnit);
25262529
Linker.Streamer->emitDIE(*CurrentUnit->getOutputUnitDIE());
2530+
assert(Linker.Streamer->getDebugInfoSectionSize() ==
2531+
CurrentUnit->computeNextUnitOffset());
25272532
}
25282533
}
25292534

@@ -2593,13 +2598,7 @@ bool DwarfLinkerForBinary::emitPaperTrailWarnings(
25932598
Size += getULEB128Size(Abbrev.getNumber());
25942599
}
25952600
CUDie->setSize(Size);
2596-
auto &Asm = Streamer->getAsmPrinter();
2597-
Asm.emitInt32(11 + CUDie->getSize() - 4);
2598-
Asm.emitInt16(2);
2599-
Asm.emitInt32(0);
2600-
Asm.emitInt8(Map.getTriple().isArch64Bit() ? 8 : 4);
2601-
Streamer->emitDIE(*CUDie);
2602-
OutputDebugInfoSize += 11 /* Header */ + Size;
2601+
Streamer->emitPaperTrailWarningsDie(Map.getTriple(), *CUDie);
26032602

26042603
return true;
26052604
}
@@ -2680,7 +2679,6 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
26802679
return false;
26812680

26822681
// Size of the DIEs (and headers) generated for the linked output.
2683-
OutputDebugInfoSize = 0;
26842682
// A unique ID that identifies each compile unit.
26852683
unsigned UnitID = 0;
26862684
DebugMap ModuleMap(Map.getTriple(), Map.getBinaryPath());
@@ -2819,7 +2817,8 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
28192817
// is already emitted, without being affected by canonical die offsets set
28202818
// later. This prevents undeterminism when analyze and clone execute
28212819
// concurrently, as clone set the canonical DIE offset and analyze reads it.
2822-
const uint64_t ModulesEndOffset = OutputDebugInfoSize;
2820+
const uint64_t ModulesEndOffset =
2821+
Options.NoOutput ? 0 : Streamer->getDebugInfoSectionSize();
28232822

28242823
// These variables manage the list of processed object files.
28252824
// The mutex and condition variable are to ensure that this is thread safe.

llvm/tools/dsymutil/DwarfLinkerForBinary.h

-1
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,6 @@ class DwarfLinkerForBinary {
499499
BinaryHolder &BinHolder;
500500
LinkOptions Options;
501501
std::unique_ptr<DwarfStreamer> Streamer;
502-
uint64_t OutputDebugInfoSize;
503502

504503
unsigned MaxDwarfVersion = 0;
505504
unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max();

llvm/tools/dsymutil/DwarfStreamer.cpp

+46-15
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ bool DwarfStreamer::init(Triple TheTriple) {
123123
LocSectionSize = 0;
124124
LineSectionSize = 0;
125125
FrameSectionSize = 0;
126+
DebugInfoSectionSize = 0;
126127

127128
return true;
128129
}
@@ -169,6 +170,7 @@ void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) {
169170
// start of the section.
170171
Asm->emitInt32(0);
171172
Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
173+
DebugInfoSectionSize += 11;
172174

173175
// Remember this CU.
174176
EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
@@ -188,6 +190,45 @@ void DwarfStreamer::emitAbbrevs(
188190
void DwarfStreamer::emitDIE(DIE &Die) {
189191
MS->SwitchSection(MOFI->getDwarfInfoSection());
190192
Asm->emitDwarfDIE(Die);
193+
DebugInfoSectionSize += Die.getSize();
194+
}
195+
196+
/// Emit contents of section SecName From Obj.
197+
void DwarfStreamer::emitSectionContents(const object::ObjectFile &Obj,
198+
StringRef SecName) {
199+
MCSection *Section =
200+
StringSwitch<MCSection *>(SecName)
201+
.Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
202+
.Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
203+
.Case("debug_ranges",
204+
MC->getObjectFileInfo()->getDwarfRangesSection())
205+
.Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
206+
.Case("debug_aranges",
207+
MC->getObjectFileInfo()->getDwarfARangesSection())
208+
.Default(nullptr);
209+
210+
if (Section) {
211+
MS->SwitchSection(Section);
212+
213+
if (auto Sec = getSectionByName(Obj, SecName)) {
214+
if (Expected<StringRef> E = Sec->getContents())
215+
MS->EmitBytes(*E);
216+
else
217+
consumeError(E.takeError());
218+
}
219+
}
220+
}
221+
222+
/// Emit DIE containing warnings.
223+
void DwarfStreamer::emitPaperTrailWarningsDie(const Triple &Triple, DIE &Die) {
224+
switchToDebugInfoSection(/* Version */ 2);
225+
auto &Asm = getAsmPrinter();
226+
Asm.emitInt32(11 + Die.getSize() - 4);
227+
Asm.emitInt16(2);
228+
Asm.emitInt32(0);
229+
Asm.emitInt8(Triple.isArch64Bit() ? 8 : 4);
230+
DebugInfoSectionSize += 11;
231+
emitDIE(Die);
191232
}
192233

193234
/// Emit the debug_str section stored in \p Pool.
@@ -680,33 +721,23 @@ void DwarfStreamer::translateLineTable(DataExtractor Data, uint64_t Offset) {
680721
Offset = UnitEnd;
681722
}
682723

683-
static void emitSectionContents(const object::ObjectFile &Obj,
684-
StringRef SecName, MCStreamer *MS) {
685-
if (auto Sec = getSectionByName(Obj, SecName)) {
686-
if (Expected<StringRef> E = Sec->getContents())
687-
MS->EmitBytes(*E);
688-
else
689-
consumeError(E.takeError());
690-
}
691-
}
692-
693724
void DwarfStreamer::copyInvariantDebugSection(const object::ObjectFile &Obj) {
694725
if (!Options.Translator) {
695726
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());
696-
emitSectionContents(Obj, "debug_line", MS);
727+
emitSectionContents(Obj, "debug_line");
697728
}
698729

699730
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
700-
emitSectionContents(Obj, "debug_loc", MS);
731+
emitSectionContents(Obj, "debug_loc");
701732

702733
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
703-
emitSectionContents(Obj, "debug_ranges", MS);
734+
emitSectionContents(Obj, "debug_ranges");
704735

705736
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
706-
emitSectionContents(Obj, "debug_frame", MS);
737+
emitSectionContents(Obj, "debug_frame");
707738

708739
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
709-
emitSectionContents(Obj, "debug_aranges", MS);
740+
emitSectionContents(Obj, "debug_aranges");
710741
}
711742

712743
/// Emit the pubnames or pubtypes section contribution for \p

0 commit comments

Comments
 (0)