Skip to content
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
25 changes: 18 additions & 7 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,11 @@ class LLVM_ABI AppleAcceleratorTable : public DWARFAcceleratorTable {
uint64_t getHashBase() const { return getBucketBase() + getNumBuckets() * 4; }

/// Return the offset into the section where the I-th hash is.
uint64_t getIthHashBase(uint32_t I) const { return getHashBase() + I * 4; }
std::optional<uint64_t> getIthHashBase(uint32_t I) const {
if (I < Hdr.HashCount)
return getHashBase() + I * 4;
return std::nullopt;
}

/// Return the offset into the section where the offset list begins.
uint64_t getOffsetBase() const { return getHashBase() + getNumHashes() * 4; }
Expand All @@ -164,8 +168,10 @@ class LLVM_ABI AppleAcceleratorTable : public DWARFAcceleratorTable {
}

/// Return the offset into the section where the I-th offset is.
uint64_t getIthOffsetBase(uint32_t I) const {
return getOffsetBase() + I * 4;
std::optional<uint64_t> getIthOffsetBase(uint32_t I) const {
if (I < Hdr.HashCount)
return getOffsetBase() + I * 4;
return std::nullopt;
}

/// Returns the index of the bucket where a hypothetical Hash would be.
Expand All @@ -188,14 +194,18 @@ class LLVM_ABI AppleAcceleratorTable : public DWARFAcceleratorTable {

/// Reads the I-th hash in the hash list.
std::optional<uint32_t> readIthHash(uint32_t I) const {
uint64_t Offset = getIthHashBase(I);
return readU32FromAccel(Offset);
std::optional<uint64_t> OptOffset = getIthHashBase(I);
if (OptOffset)
return readU32FromAccel(*OptOffset);
return std::nullopt;
}

/// Reads the I-th offset in the offset list.
std::optional<uint32_t> readIthOffset(uint32_t I) const {
uint64_t Offset = getIthOffsetBase(I);
return readU32FromAccel(Offset);
std::optional<uint64_t> OptOffset = getIthOffsetBase(I);
if (OptOffset)
return readU32FromAccel(*OptOffset);
return std::nullopt;
}

/// Reads a string offset from the accelerator table at Offset, which is
Expand Down Expand Up @@ -282,6 +292,7 @@ class LLVM_ABI AppleAcceleratorTable : public DWARFAcceleratorTable {
constexpr static auto EndMarker = std::numeric_limits<uint64_t>::max();

EntryWithName Current;
uint32_t OffsetIdx = 0;
uint64_t Offset = EndMarker;
uint32_t NumEntriesToCome = 0;

Expand Down
24 changes: 18 additions & 6 deletions llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,25 +321,37 @@ void AppleAcceleratorTable::Iterator::prepareNextEntryOrEnd() {
}

void AppleAcceleratorTable::Iterator::prepareNextStringOrEnd() {
std::optional<uint32_t> StrOffset = getTable().readStringOffsetAt(Offset);
const AppleAcceleratorTable &Table = getTable();
if (Offset == 0) {
// Always start looking for strings using a valid offset from the Offsets
// table. Entries are not always consecutive.
std::optional<uint64_t> OptOffset = Table.readIthOffset(OffsetIdx++);
if (!OptOffset)
return setToEnd();
Offset = *OptOffset;
}
std::optional<uint32_t> StrOffset = Table.readStringOffsetAt(Offset);
if (!StrOffset)
return setToEnd();

// A zero denotes the end of the collision list. Read the next string
// again.
if (*StrOffset == 0)
// A zero denotes the end of the collision list. Skip to the next offset
// in the offsets table by setting the Offset to zero so we will grab the
// next offset from the offsets table.
if (*StrOffset == 0) {
Offset = 0;
return prepareNextStringOrEnd();
}
Current.StrOffset = *StrOffset;

std::optional<uint32_t> MaybeNumEntries = getTable().readU32FromAccel(Offset);
std::optional<uint32_t> MaybeNumEntries = Table.readU32FromAccel(Offset);
if (!MaybeNumEntries || *MaybeNumEntries == 0)
return setToEnd();
NumEntriesToCome = *MaybeNumEntries;
}

AppleAcceleratorTable::Iterator::Iterator(const AppleAcceleratorTable &Table,
bool SetEnd)
: Current(Table), Offset(Table.getEntriesBase()), NumEntriesToCome(0) {
: Current(Table), Offset(0), NumEntriesToCome(0) {
if (SetEnd)
setToEnd();
else
Expand Down
Loading