[DWARFYAML] Refactor range list table to hold more data structure.

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
This commit is contained in:
Xing GUO 2020-07-23 10:25:01 +08:00
parent 6b55a95898
commit c4cf250c5b
3 changed files with 63 additions and 46 deletions

View File

@ -190,11 +190,11 @@ 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;
@ -202,7 +202,7 @@ struct RnglistTable {
yaml::Hex8 SegSelectorSize;
Optional<uint32_t> OffsetEntryCount;
Optional<std::vector<yaml::Hex64>> Offsets;
std::vector<Rnglist> Lists;
std::vector<ListEntries<EntryType>> Lists;
};
struct Data {
@ -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;
@ -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 {
@ -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> {

View File

@ -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"
@ -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);
@ -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;
@ -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;
@ -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));
}
};
@ -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

View File

@ -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(