Skip to content

[llvm-dwarfdump] Make --verify for .debug_names multithreaded. #127281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 3, 2025
11 changes: 11 additions & 0 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,7 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
}

public:
using size_type = size_t;
using iterator_category = std::input_iterator_tag;
using value_type = NameTableEntry;
using difference_type = uint32_t;
Expand All @@ -793,6 +794,16 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
next();
return I;
}
/// Accesses entry at specific index (1-based internally, 0-based
/// externally). For example how this is used in parallelForEach.
reference operator[](size_type idx) {
return CurrentIndex->getNameTableEntry(idx + 1);
}
/// Computes difference between iterators (used in parallelForEach).
difference_type operator-(const NameIterator &other) const {
assert(CurrentIndex == other.CurrentIndex);
return this->CurrentName - other.CurrentName;
}

friend bool operator==(const NameIterator &A, const NameIterator &B) {
return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
Expand Down
43 changes: 26 additions & 17 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
#ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
#define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H

#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include <cstdint>
#include <map>
#include <mutex>
#include <set>

namespace llvm {
Expand All @@ -37,7 +39,9 @@ struct AggregationData {

class OutputCategoryAggregator {
private:
std::mutex WriteMutex;
std::map<std::string, AggregationData, std::less<>> Aggregation;
uint64_t NumErrors = 0;
bool IncludeDetail;

public:
Expand All @@ -52,6 +56,8 @@ class OutputCategoryAggregator {
void EnumerateDetailedResultsFor(
StringRef category,
std::function<void(StringRef, unsigned)> handleCounts);
/// Return the number of errors that have been reported.
uint64_t GetNumErrors() const { return NumErrors; }
};

/// A class that verifies DWARF debug information given a DWARF Context.
Expand Down Expand Up @@ -114,6 +120,7 @@ class DWARFVerifier {
bool IsObjectFile;
bool IsMachOObject;
using ReferenceMap = std::map<uint64_t, std::set<uint64_t>>;
std::mutex AccessMutex;

raw_ostream &error() const;
raw_ostream &warn() const;
Expand Down Expand Up @@ -274,21 +281,23 @@ class DWARFVerifier {
/// \param SectionName the name of the table we're verifying
///
/// \returns The number of errors occurred during verification
unsigned verifyAppleAccelTable(const DWARFSection *AccelSection,
DataExtractor *StrData,
const char *SectionName);

unsigned verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
unsigned verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
const DataExtractor &StrData);
unsigned verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI);
unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
const DWARFDebugNames::Abbrev &Abbr,
DWARFDebugNames::AttributeEncoding AttrEnc);
unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
const DWARFDebugNames::NameTableEntry &NTE);
unsigned verifyNameIndexCompleteness(const DWARFDie &Die,
const DWARFDebugNames::NameIndex &NI);
void verifyAppleAccelTable(const DWARFSection *AccelSection,
DataExtractor *StrData, const char *SectionName);

void verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
void verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
const DataExtractor &StrData);
void verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI);
void verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
const DWARFDebugNames::Abbrev &Abbr,
DWARFDebugNames::AttributeEncoding AttrEnc);
void verifyNameIndexEntries(
const DWARFDebugNames::NameIndex &NI,
const DWARFDebugNames::NameTableEntry &NTE,
const DenseMap<uint64_t, DWARFUnit *> &CUOffsetsToDUMap);
void verifyNameIndexCompleteness(
const DWARFDie &Die, const DWARFDebugNames::NameIndex &NI,
const StringMap<DenseSet<uint64_t>> &NamesToDieOffsets);

/// Verify that the DWARF v5 accelerator table is valid.
///
Expand All @@ -307,8 +316,8 @@ class DWARFVerifier {
/// \param StrData string section
///
/// \returns The number of errors occurred during verification
unsigned verifyDebugNames(const DWARFSection &AccelSection,
const DataExtractor &StrData);
void verifyDebugNames(const DWARFSection &AccelSection,
const DataExtractor &StrData);

public:
DWARFVerifier(raw_ostream &S, DWARFContext &D,
Expand Down
Loading