Skip to content

[llvm-debuginfo-analyzer] Fix crash with WebAssembly dead code #141616

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,17 @@ using LVTypes = SmallVector<LVType *, 8>;

using LVOffsets = SmallVector<LVOffset, 8>;

// The following DWARF documents detail the 'tombstone' concept:
// https://dwarfstd.org/issues/231013.1.html
// https://dwarfstd.org/issues/200609.1.html
//
// The value of the largest representable address offset (for example,
// 0xffffffff when the size of an address is 32 bits).
//
// -1 (0xffffffff) => Valid tombstone
// -2 (0xfffffffe) => Undefined tomstone
const LVAddress MaxAddress = std::numeric_limits<uint64_t>::max();
const LVAddress InvalidTombstone = MaxAddress - 1;

enum class LVBinaryType { NONE, ELF, COFF };
enum class LVComparePass { Missing, Added };
Expand Down
9 changes: 6 additions & 3 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,14 @@ class LVRange final : public LVObject {
LVAllocator Allocator;
LVRangesTree RangesTree;
LVRangeEntries RangeEntries;
LVAddress Lower = MaxAddress;
LVAddress TombstoneAddress;
LVAddress Lower;
LVAddress Upper = 0;

public:
LVRange() : LVObject(), RangesTree(Allocator) {}
LVRange(LVAddress Address = InvalidTombstone)
: LVObject(), RangesTree(Allocator), TombstoneAddress(Address),
Lower(Address) {}
LVRange(const LVRange &) = delete;
LVRange &operator=(const LVRange &) = delete;
~LVRange() = default;
Expand All @@ -75,7 +78,7 @@ class LVRange final : public LVObject {

void clear() {
RangeEntries.clear();
Lower = MaxAddress;
Lower = TombstoneAddress;
Upper = 0;
}
bool empty() const { return RangeEntries.empty(); }
Expand Down
9 changes: 9 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ class LVReader {
// Only for ELF format. The CodeView is handled in a different way.
LVSectionIndex DotTextSectionIndex = UndefinedSectionIndex;

// The value is updated for each Compile Unit that is processed.
LVAddress TombstoneAddress = InvalidTombstone;

// Record Compilation Unit entry.
void addCompileUnitOffset(LVOffset Offset, LVScopeCompileUnit *CompileUnit) {
CompileUnits.emplace(Offset, CompileUnit);
Expand Down Expand Up @@ -257,6 +260,12 @@ class LVReader {
return CompileUnit->getCPUType();
}

void setTombstoneAddress(LVAddress Address) { TombstoneAddress = Address; }
LVAddress getTombstoneAddress() const {
assert(TombstoneAddress != InvalidTombstone && "Invalid tombstone value");
return TombstoneAddress;
}

// Access to the scopes root.
LVScopeRoot *getScopesRoot() const { return Root; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,17 @@ class LVCodeViewReader final : public LVBinaryReader {
llvm::object::COFFObjectFile &Obj, ScopedPrinter &W,
StringRef ExePath)
: LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::COFF),
Input(&Obj), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
Input(&Obj), ExePath(ExePath), LogicalVisitor(this, W, Input) {
// CodeView does not have the concept of 'tombstone' address.
setTombstoneAddress(MaxAddress);
}
LVCodeViewReader(StringRef Filename, StringRef FileFormatName,
llvm::pdb::PDBFile &Pdb, ScopedPrinter &W, StringRef ExePath)
: LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::COFF),
Input(&Pdb), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
Input(&Pdb), ExePath(ExePath), LogicalVisitor(this, W, Input) {
// CodeView does not have the concept of 'tombstone' address.
setTombstoneAddress(MaxAddress);
}
LVCodeViewReader(const LVCodeViewReader &) = delete;
LVCodeViewReader &operator=(const LVCodeViewReader &) = delete;
~LVCodeViewReader() = default;
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,10 @@ LVRange *LVBinaryReader::getSectionRanges(LVSectionIndex SectionIndex) {
// Check if we already have a mapping for this section index.
LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex);
if (IterSection == SectionRanges.end())
IterSection =
SectionRanges.emplace(SectionIndex, std::make_unique<LVRange>()).first;
IterSection = SectionRanges
.emplace(SectionIndex,
std::make_unique<LVRange>(getTombstoneAddress()))
.first;
LVRange *Range = IterSection->second.get();
assert(Range && "Range is null.");
return Range;
Expand Down
15 changes: 11 additions & 4 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,11 @@ void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
}
}
if (FoundLowPC) {
if (CurrentLowPC == MaxAddress)
if (CurrentLowPC == getTombstoneAddress())
CurrentElement->setIsDiscarded();
// Consider the case of WebAssembly.
CurrentLowPC += WasmCodeSectionOffset;
else
// Consider the case of WebAssembly.
CurrentLowPC += WasmCodeSectionOffset;
if (CurrentElement->isCompileUnit())
setCUBaseAddress(CurrentLowPC);
}
Expand Down Expand Up @@ -483,7 +484,8 @@ void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
DWARFAddressRangesVector Ranges = RangesOrError.get();
for (DWARFAddressRange &Range : Ranges) {
// This seems to be a tombstone for empty ranges.
if (Range.LowPC == Range.HighPC)
if ((Range.LowPC == Range.HighPC) ||
(Range.LowPC = getTombstoneAddress()))
continue;
// Store the real upper limit for the address range.
if (UpdateHighAddress && Range.HighPC > 0)
Expand Down Expand Up @@ -841,6 +843,11 @@ Error LVDWARFReader::createScopes() {
: DwarfContext->dwo_compile_units();
for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits) {

// Take into account the address byte size for a correct 'tombstone'
// value identification.
setTombstoneAddress(
dwarf::computeTombstoneAddress(CU->getAddressByteSize()));

// Deduction of index used for the line records.
//
// For the following test case: test.cpp
Expand Down
Loading
Loading