Skip to content

Commit

Permalink
[BOLT] Separate DebugRangesSectionsWriter into Ranges and ARanges
Browse files Browse the repository at this point in the history
Summary: The `.debug_aranges` section is already deterministic and is logically separate from the `.debug_ranges` section so separate them into separate classes so that it will be easier to make DebugRangesSectionsWriter deterministic

(cherry picked from FBD18153057)
  • Loading branch information
Xin-Xin Wang authored and maksfb committed Oct 25, 2019
1 parent 8e2d3f7 commit 112c425
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 53 deletions.
24 changes: 13 additions & 11 deletions bolt/src/DWARFRewriter.cpp
Expand Up @@ -75,7 +75,8 @@ void DWARFRewriter::updateDebugInfo() {
static_cast<DebugAbbrevPatcher *>(SectionPatchers[".debug_abbrev"].get());
assert(DebugInfoPatcher && AbbrevPatcher && "Patchers not initialized.");

RangesSectionsWriter = llvm::make_unique<DebugRangesSectionsWriter>(&BC);
ARangesSectionWriter = llvm::make_unique<DebugARangesSectionWriter>();
RangesSectionWriter = llvm::make_unique<DebugRangesSectionWriter>(&BC);
LocationListWriter = llvm::make_unique<DebugLocWriter>(&BC);

auto processUnitDIE = [&](const DWARFDie DIE) {
Expand Down Expand Up @@ -115,7 +116,8 @@ void DWARFRewriter::updateUnitDebugInfo(
const auto ModuleRanges = DIE.getAddressRanges();
auto OutputRanges = BC.translateModuleAddressRanges(ModuleRanges);
const auto RangesSectionOffset =
RangesSectionsWriter->addCURanges(DIE.getDwarfUnit()->getOffset(),
RangesSectionWriter->addRanges(OutputRanges);
ARangesSectionWriter->addCURanges(DIE.getDwarfUnit()->getOffset(),
std::move(OutputRanges));
updateDWARFObjectAddressRanges(DIE, RangesSectionOffset);
}
Expand Down Expand Up @@ -150,7 +152,7 @@ void DWARFRewriter::updateUnitDebugInfo(
// Update ranges.
if (UsesRanges) {
updateDWARFObjectAddressRanges(DIE,
RangesSectionsWriter->addRanges(FunctionRanges));
RangesSectionWriter->addRanges(FunctionRanges));
} else {
// Delay conversion of [LowPC, HighPC) into DW_AT_ranges if possible.
const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
Expand Down Expand Up @@ -186,7 +188,7 @@ void DWARFRewriter::updateUnitDebugInfo(
case dwarf::DW_TAG_catch_block:
{
auto RangesSectionOffset =
RangesSectionsWriter->getEmptyRangesOffset();
RangesSectionWriter->getEmptyRangesOffset();
const BinaryFunction *Function =
FunctionStack.empty() ? nullptr : FunctionStack.back();
if (Function) {
Expand All @@ -199,7 +201,7 @@ void DWARFRewriter::updateUnitDebugInfo(
<< Twine::utohexstr(DIE.getDwarfUnit()->getOffset()) << '\n';
}
);
RangesSectionOffset = RangesSectionsWriter->addRanges(
RangesSectionOffset = RangesSectionWriter->addRanges(
Function, std::move(OutputRanges), CachedFunction, CachedRanges);
}
updateDWARFObjectAddressRanges(DIE, RangesSectionOffset);
Expand Down Expand Up @@ -484,15 +486,15 @@ void DWARFRewriter::finalizeDebugSections() {
*BC.STI, *BC.MRI, MCTargetOptions()));
auto Writer = std::unique_ptr<MCObjectWriter>(MAB->createObjectWriter(OS));

RangesSectionsWriter->writeArangesSection(Writer.get());
ARangesSectionWriter->writeARangesSection(Writer.get());
const auto &ARangesContents = OS.str();

BC.registerOrUpdateNoteSection(".debug_aranges",
copyByteArray(ARangesContents),
ARangesContents.size());
}

auto RangesSectionContents = RangesSectionsWriter->finalize();
auto RangesSectionContents = RangesSectionWriter->finalize();
BC.registerOrUpdateNoteSection(".debug_ranges",
copyByteArray(*RangesSectionContents),
RangesSectionContents->size());
Expand Down Expand Up @@ -557,7 +559,7 @@ void DWARFRewriter::updateGdbIndexSection() {

// Calculate the size of the new address table.
uint32_t NewAddressTableSize = 0;
for (const auto &CURangesPair : RangesSectionsWriter->getCUAddressRanges()) {
for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) {
const auto &Ranges = CURangesPair.second;
NewAddressTableSize += Ranges.size() * 20;
}
Expand Down Expand Up @@ -586,7 +588,7 @@ void DWARFRewriter::updateGdbIndexSection() {
Buffer += AddressTableOffset - CUListOffset;

// Generate new address table.
for (const auto &CURangesPair : RangesSectionsWriter->getCUAddressRanges()) {
for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) {
const auto CUIndex = OffsetToIndexMap[CURangesPair.first];
const auto &Ranges = CURangesPair.second;
for (const auto &Range : Ranges) {
Expand Down Expand Up @@ -641,9 +643,9 @@ void DWARFRewriter::convertToRanges(DWARFDie DIE,
const DebugAddressRangesVector &Ranges) {
uint64_t RangesSectionOffset;
if (Ranges.empty()) {
RangesSectionOffset = RangesSectionsWriter->getEmptyRangesOffset();
RangesSectionOffset = RangesSectionWriter->getEmptyRangesOffset();
} else {
RangesSectionOffset = RangesSectionsWriter->addRanges(Ranges);
RangesSectionOffset = RangesSectionWriter->addRanges(Ranges);
}

convertToRanges(DIE, RangesSectionOffset);
Expand Down
10 changes: 7 additions & 3 deletions bolt/src/DWARFRewriter.h
Expand Up @@ -40,9 +40,13 @@ class DWARFRewriter {

std::mutex AbbrevPatcherMutex;

/// Stores and serializes information that will be put into the .debug_ranges
/// and .debug_aranges DWARF sections.
std::unique_ptr<DebugRangesSectionsWriter> RangesSectionsWriter;
/// Stores and serializes information that will be put into the
/// .debug_ranges DWARF section.
std::unique_ptr<DebugRangesSectionWriter> RangesSectionWriter;

/// Stores and serializes information that will be put into the
/// .debug_aranges DWARF section.
std::unique_ptr<DebugARangesSectionWriter> ARangesSectionWriter;

std::unique_ptr<DebugLocWriter> LocationListWriter;

Expand Down
25 changes: 11 additions & 14 deletions bolt/src/DebugData.cpp
Expand Up @@ -55,7 +55,7 @@ uint64_t writeAddressRanges(

} // namespace

DebugRangesSectionsWriter::DebugRangesSectionsWriter(BinaryContext *BC) {
DebugRangesSectionWriter::DebugRangesSectionWriter(BinaryContext *BC) {
RangesBuffer = llvm::make_unique<RangesBufferVector>();
RangesStream = llvm::make_unique<raw_svector_ostream>(*RangesBuffer);
Writer =
Expand All @@ -65,17 +65,7 @@ DebugRangesSectionsWriter::DebugRangesSectionsWriter(BinaryContext *BC) {
SectionOffset += writeAddressRanges(Writer.get(), DebugAddressRangesVector{});
}

uint64_t
DebugRangesSectionsWriter::addCURanges(uint64_t CUOffset,
DebugAddressRangesVector &&Ranges) {
const auto RangesOffset = addRanges(Ranges);

std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
CUAddressRanges.emplace(CUOffset, std::move(Ranges));
return RangesOffset;
}

uint64_t DebugRangesSectionsWriter::addRanges(
uint64_t DebugRangesSectionWriter::addRanges(
const BinaryFunction *Function, DebugAddressRangesVector &&Ranges,
const BinaryFunction *&CachedFunction,
std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
Expand All @@ -98,7 +88,7 @@ uint64_t DebugRangesSectionsWriter::addRanges(
}

uint64_t
DebugRangesSectionsWriter::addRanges(const DebugAddressRangesVector &Ranges) {
DebugRangesSectionWriter::addRanges(const DebugAddressRangesVector &Ranges) {
if (Ranges.empty())
return getEmptyRangesOffset();

Expand All @@ -112,7 +102,14 @@ DebugRangesSectionsWriter::addRanges(const DebugAddressRangesVector &Ranges) {
}

void
DebugRangesSectionsWriter::writeArangesSection(MCObjectWriter *Writer) const {
DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
DebugAddressRangesVector &&Ranges) {
std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
CUAddressRanges.emplace(CUOffset, std::move(Ranges));
}

void
DebugARangesSectionWriter::writeARangesSection(MCObjectWriter *Writer) const {
// For reference on the format of the .debug_aranges section, see the DWARF4
// specification, section 6.1.4 Lookup by Address
// http://www.dwarfstd.org/doc/DWARF4.pdf
Expand Down
55 changes: 30 additions & 25 deletions bolt/src/DebugData.h
Expand Up @@ -96,13 +96,10 @@ struct DebugLineTableRowRef {

using RangesBufferVector = SmallVector<char, 16>;

/// Serializes the .debug_ranges and .debug_aranges DWARF sections.
class DebugRangesSectionsWriter {
/// Serializes the .debug_ranges DWARF section.
class DebugRangesSectionWriter {
public:
DebugRangesSectionsWriter(BinaryContext *BC);

/// Add ranges for CU matching \p CUOffset and return offset into section.
uint64_t addCURanges(uint64_t CUOffset, DebugAddressRangesVector &&Ranges);
DebugRangesSectionWriter(BinaryContext *BC);

/// Add ranges with caching for \p Function.
uint64_t
Expand All @@ -113,26 +110,10 @@ class DebugRangesSectionsWriter {
/// Add ranges and return offset into section.
uint64_t addRanges(const DebugAddressRangesVector &Ranges);

/// Writes .debug_aranges with the added ranges to the MCObjectWriter.
void writeArangesSection(MCObjectWriter *Writer) const;

/// Resets the writer to a clear state.
void reset() {
CUAddressRanges.clear();
}

/// Returns an offset of an empty address ranges list that is always written
/// to .debug_ranges
uint64_t getEmptyRangesOffset() const { return EmptyRangesOffset; }

/// Map DWARFCompileUnit index to ranges.
using CUAddressRangesType = std::map<uint64_t, DebugAddressRangesVector>;

/// Return ranges for a given CU.
const CUAddressRangesType &getCUAddressRanges() const {
return CUAddressRanges;
}

std::unique_ptr<RangesBufferVector> finalize() {
return std::move(RangesBuffer);
}
Expand All @@ -150,15 +131,39 @@ class DebugRangesSectionsWriter {
/// Starts with 16 since the first 16 bytes are reserved for an empty range.
uint32_t SectionOffset{0};

/// Offset of an empty address ranges list.
static constexpr uint64_t EmptyRangesOffset{0};
};

/// Serializes the .debug_aranges DWARF section.
class DebugARangesSectionWriter {
public:
/// Add ranges for CU matching \p CUOffset.
void addCURanges(uint64_t CUOffset, DebugAddressRangesVector &&Ranges);

/// Writes .debug_aranges with the added ranges to the MCObjectWriter.
void writeARangesSection(MCObjectWriter *Writer) const;

/// Resets the writer to a clear state.
void reset() {
CUAddressRanges.clear();
}

/// Map DWARFCompileUnit index to ranges.
using CUAddressRangesType = std::map<uint64_t, DebugAddressRangesVector>;

/// Return ranges for a given CU.
const CUAddressRangesType &getCUAddressRanges() const {
return CUAddressRanges;
}

private:
/// Map from compile unit offset to the list of address intervals that belong
/// to that compile unit. Each interval is a pair
/// (first address, interval size).
CUAddressRangesType CUAddressRanges;

std::mutex CUAddressRangesMutex;

/// Offset of an empty address ranges list.
static constexpr uint64_t EmptyRangesOffset{0};
};

using LocBufferVector = SmallVector<char, 16>;
Expand Down

0 comments on commit 112c425

Please sign in to comment.