Skip to content

Commit

Permalink
[DWARFYAML] Refactor range list table to hold more data structure.
Browse files Browse the repository at this point in the history
This patch refactors the range list table to hold both the range list
table and the location list table.

Reviewed By: jhenderson, labath

Differential Revision: https://reviews.llvm.org/D84239
  • Loading branch information
higuoxing committed Jul 23, 2020
1 parent 6b55a95 commit c4cf250
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 46 deletions.
26 changes: 15 additions & 11 deletions llvm/include/llvm/ObjectYAML/DWARFYAML.h
Expand Up @@ -190,19 +190,19 @@ struct RnglistEntry {
std::vector<yaml::Hex64> Values;
};

struct Rnglist {
std::vector<RnglistEntry> Entries;
template <typename EntryType> struct ListEntries {
std::vector<EntryType> Entries;
};

struct RnglistTable {
template <typename EntryType> struct ListTable {
dwarf::DwarfFormat Format;
Optional<yaml::Hex64> Length;
yaml::Hex16 Version;
Optional<yaml::Hex8> AddrSize;
yaml::Hex8 SegSelectorSize;
Optional<uint32_t> OffsetEntryCount;
Optional<std::vector<yaml::Hex64>> Offsets;
std::vector<Rnglist> Lists;
std::vector<ListEntries<EntryType>> Lists;
};

struct Data {
Expand All @@ -223,7 +223,7 @@ struct Data {
std::vector<Unit> CompileUnits;

std::vector<LineTable> DebugLines;
Optional<std::vector<RnglistTable>> DebugRnglists;
Optional<std::vector<ListTable<RnglistEntry>>> DebugRnglists;

bool isEmpty() const;

Expand All @@ -249,8 +249,10 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::SegAddrPair)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AddrTableEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::StringOffsetsTable)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistTable)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Rnglist)
LLVM_YAML_IS_SEQUENCE_VECTOR(
llvm::DWARFYAML::ListTable<DWARFYAML::RnglistEntry>)
LLVM_YAML_IS_SEQUENCE_VECTOR(
llvm::DWARFYAML::ListEntries<DWARFYAML::RnglistEntry>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistEntry)

namespace llvm {
Expand Down Expand Up @@ -320,12 +322,14 @@ template <> struct MappingTraits<DWARFYAML::SegAddrPair> {
static void mapping(IO &IO, DWARFYAML::SegAddrPair &SegAddrPair);
};

template <> struct MappingTraits<DWARFYAML::RnglistTable> {
static void mapping(IO &IO, DWARFYAML::RnglistTable &RnglistTable);
template <typename EntryType>
struct MappingTraits<DWARFYAML::ListTable<EntryType>> {
static void mapping(IO &IO, DWARFYAML::ListTable<EntryType> &ListTable);
};

template <> struct MappingTraits<DWARFYAML::Rnglist> {
static void mapping(IO &IO, DWARFYAML::Rnglist &Rnglist);
template <typename EntryType>
struct MappingTraits<DWARFYAML::ListEntries<EntryType>> {
static void mapping(IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries);
};

template <> struct MappingTraits<DWARFYAML::RnglistEntry> {
Expand Down
55 changes: 33 additions & 22 deletions llvm/lib/ObjectYAML/DWARFEmitter.cpp
Expand Up @@ -13,6 +13,7 @@

#include "llvm/ObjectYAML/DWARFEmitter.h"
#include "DWARFVisitor.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
Expand Down Expand Up @@ -441,9 +442,10 @@ Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, const Data &DI) {
return Error::success();
}

static Expected<uint64_t>
writeRnglistEntry(raw_ostream &OS, const DWARFYAML::RnglistEntry &Entry,
uint8_t AddrSize, bool IsLittleEndian) {
static Expected<uint64_t> writeListEntry(raw_ostream &OS,
const DWARFYAML::RnglistEntry &Entry,
uint8_t AddrSize,
bool IsLittleEndian) {
uint64_t BeginOffset = OS.tell();
writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);

Expand Down Expand Up @@ -515,9 +517,11 @@ writeRnglistEntry(raw_ostream &OS, const DWARFYAML::RnglistEntry &Entry,
return OS.tell() - BeginOffset;
}

Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call");
for (const DWARFYAML::RnglistTable &Table : *DI.DebugRnglists) {
template <typename EntryType>
Error writeDWARFLists(raw_ostream &OS,
ArrayRef<DWARFYAML::ListTable<EntryType>> Tables,
bool IsLittleEndian, bool Is64BitAddrSize) {
for (const DWARFYAML::ListTable<EntryType> &Table : Tables) {
// sizeof(version) + sizeof(address_size) + sizeof(segment_selector_size) +
// sizeof(offset_entry_count) = 8
uint64_t Length = 8;
Expand All @@ -526,24 +530,25 @@ Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
if (Table.AddrSize)
AddrSize = *Table.AddrSize;
else
AddrSize = DI.Is64BitAddrSize ? 8 : 4;
AddrSize = Is64BitAddrSize ? 8 : 4;

// Since the length of the current range lists entry is undetermined yet, we
// firstly write the content of the range lists to a buffer to calculate the
// length and then serialize the buffer content to the actual output stream.
// Since the length of the current range/location lists entry is
// undetermined yet, we firstly write the content of the range/location
// lists to a buffer to calculate the length and then serialize the buffer
// content to the actual output stream.
std::string ListBuffer;
raw_string_ostream ListBufferOS(ListBuffer);

// Offsets holds offsets for each range list. The i-th element is the offset
// from the beginning of the first range list to the location of the i-th
// range list.
// Offsets holds offsets for each range/location list. The i-th element is
// the offset from the beginning of the first range/location list to the
// location of the i-th range list.
std::vector<uint64_t> Offsets;

for (const DWARFYAML::Rnglist &List : Table.Lists) {
for (const DWARFYAML::ListEntries<EntryType> &List : Table.Lists) {
Offsets.push_back(ListBufferOS.tell());
for (const DWARFYAML::RnglistEntry &Entry : List.Entries) {
for (const EntryType &Entry : List.Entries) {
Expected<uint64_t> EntrySize =
writeRnglistEntry(ListBufferOS, Entry, AddrSize, DI.IsLittleEndian);
writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
if (!EntrySize)
return EntrySize.takeError();
Length += *EntrySize;
Expand All @@ -568,17 +573,17 @@ Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
if (Table.Length)
Length = *Table.Length;

writeInitialLength(Table.Format, Length, OS, DI.IsLittleEndian);
writeInteger((uint16_t)Table.Version, OS, DI.IsLittleEndian);
writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
writeInteger((uint8_t)Table.SegSelectorSize, OS, DI.IsLittleEndian);
writeInteger((uint32_t)OffsetEntryCount, OS, DI.IsLittleEndian);
writeInitialLength(Table.Format, Length, OS, IsLittleEndian);
writeInteger((uint16_t)Table.Version, OS, IsLittleEndian);
writeInteger((uint8_t)AddrSize, OS, IsLittleEndian);
writeInteger((uint8_t)Table.SegSelectorSize, OS, IsLittleEndian);
writeInteger((uint32_t)OffsetEntryCount, OS, IsLittleEndian);

auto EmitOffsets = [&](ArrayRef<uint64_t> Offsets, uint64_t OffsetsSize) {
for (uint64_t Offset : Offsets) {
cantFail(writeVariableSizedInteger(
OffsetsSize + Offset, Table.Format == dwarf::DWARF64 ? 8 : 4, OS,
DI.IsLittleEndian));
IsLittleEndian));
}
};

Expand All @@ -595,6 +600,12 @@ Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
return Error::success();
}

Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call");
return writeDWARFLists<DWARFYAML::RnglistEntry>(
OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize);
}

using EmitFuncType = Error (*)(raw_ostream &, const DWARFYAML::Data &);

static Error
Expand Down
28 changes: 15 additions & 13 deletions llvm/lib/ObjectYAML/DWARFYAML.cpp
Expand Up @@ -242,21 +242,23 @@ void MappingTraits<DWARFYAML::RnglistEntry>::mapping(
IO.mapOptional("Values", RnglistEntry.Values);
}

void MappingTraits<DWARFYAML::Rnglist>::mapping(IO &IO,
DWARFYAML::Rnglist &Rnglist) {
IO.mapOptional("Entries", Rnglist.Entries);
template <typename EntryType>
void MappingTraits<DWARFYAML::ListEntries<EntryType>>::mapping(
IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries) {
IO.mapOptional("Entries", ListEntries.Entries);
}

void MappingTraits<DWARFYAML::RnglistTable>::mapping(
IO &IO, DWARFYAML::RnglistTable &RnglistTable) {
IO.mapOptional("Format", RnglistTable.Format, dwarf::DWARF32);
IO.mapOptional("Length", RnglistTable.Length);
IO.mapOptional("Version", RnglistTable.Version, 5);
IO.mapOptional("AddressSize", RnglistTable.AddrSize);
IO.mapOptional("SegmentSelectorSize", RnglistTable.SegSelectorSize, 0);
IO.mapOptional("OffsetEntryCount", RnglistTable.OffsetEntryCount);
IO.mapOptional("Offsets", RnglistTable.Offsets);
IO.mapOptional("Lists", RnglistTable.Lists);
template <typename EntryType>
void MappingTraits<DWARFYAML::ListTable<EntryType>>::mapping(
IO &IO, DWARFYAML::ListTable<EntryType> &ListTable) {
IO.mapOptional("Format", ListTable.Format, dwarf::DWARF32);
IO.mapOptional("Length", ListTable.Length);
IO.mapOptional("Version", ListTable.Version, 5);
IO.mapOptional("AddressSize", ListTable.AddrSize);
IO.mapOptional("SegmentSelectorSize", ListTable.SegSelectorSize, 0);
IO.mapOptional("OffsetEntryCount", ListTable.OffsetEntryCount);
IO.mapOptional("Offsets", ListTable.Offsets);
IO.mapOptional("Lists", ListTable.Lists);
}

void MappingTraits<DWARFYAML::InitialLength>::mapping(
Expand Down

0 comments on commit c4cf250

Please sign in to comment.