mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
[llvm-dwarfdump] - Add the support of parsing .debug_loclists.
This teaches llvm-dwarfdump to dump the content of .debug_loclists sections. It converts the DWARFDebugLocDWO class to DWARFDebugLoclists, teaches llvm-dwarfdump about .debug_loclists section and adds the implementation for parsing the DW_LLE_offset_pair entries. Differential revision: https://reviews.llvm.org/D53364 llvm-svn: 344895
This commit is contained in:
parent
12522d8b68
commit
4392ace2e7
@ -873,6 +873,7 @@ HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types")
|
|||||||
HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line")
|
HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line")
|
||||||
HANDLE_DWARF_SECTION(DebugLineStr, ".debug_line_str", "debug-line-str")
|
HANDLE_DWARF_SECTION(DebugLineStr, ".debug_line_str", "debug-line-str")
|
||||||
HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc")
|
HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc")
|
||||||
|
HANDLE_DWARF_SECTION(DebugLoclists, ".debug_loclists", "debug-loclists")
|
||||||
HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame")
|
HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame")
|
||||||
HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro")
|
HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro")
|
||||||
HANDLE_DWARF_SECTION(DebugNames, ".debug_names", "debug-names")
|
HANDLE_DWARF_SECTION(DebugNames, ".debug_names", "debug-names")
|
||||||
|
@ -76,7 +76,7 @@ class DWARFContext : public DIContext {
|
|||||||
|
|
||||||
DWARFUnitVector DWOUnits;
|
DWARFUnitVector DWOUnits;
|
||||||
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
|
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
|
||||||
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
|
std::unique_ptr<DWARFDebugLoclists> LocDWO;
|
||||||
|
|
||||||
/// The maximum DWARF version of all units.
|
/// The maximum DWARF version of all units.
|
||||||
unsigned MaxVersion = 0;
|
unsigned MaxVersion = 0;
|
||||||
@ -262,7 +262,7 @@ public:
|
|||||||
const DWARFDebugAbbrev *getDebugAbbrevDWO();
|
const DWARFDebugAbbrev *getDebugAbbrevDWO();
|
||||||
|
|
||||||
/// Get a pointer to the parsed DebugLoc object.
|
/// Get a pointer to the parsed DebugLoc object.
|
||||||
const DWARFDebugLocDWO *getDebugLocDWO();
|
const DWARFDebugLoclists *getDebugLocDWO();
|
||||||
|
|
||||||
/// Get a pointer to the parsed DebugAranges object.
|
/// Get a pointer to the parsed DebugAranges object.
|
||||||
const DWARFDebugAranges *getDebugAranges();
|
const DWARFDebugAranges *getDebugAranges();
|
||||||
|
@ -73,19 +73,21 @@ public:
|
|||||||
uint32_t *Offset);
|
uint32_t *Offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DWARFDebugLocDWO {
|
class DWARFDebugLoclists {
|
||||||
public:
|
public:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
uint64_t Start;
|
uint8_t Kind;
|
||||||
uint32_t Length;
|
uint64_t Value0;
|
||||||
|
uint64_t Value1;
|
||||||
SmallVector<char, 4> Loc;
|
SmallVector<char, 4> Loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LocationList {
|
struct LocationList {
|
||||||
unsigned Offset;
|
unsigned Offset;
|
||||||
SmallVector<Entry, 2> Entries;
|
SmallVector<Entry, 2> Entries;
|
||||||
void dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize,
|
void dump(raw_ostream &OS, uint64_t BaseAddr, bool IsLittleEndian,
|
||||||
const MCRegisterInfo *RegInfo, unsigned Indent) const;
|
unsigned AddressSize, const MCRegisterInfo *RegInfo,
|
||||||
|
unsigned Indent) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -99,7 +101,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void parse(DataExtractor data);
|
void parse(DataExtractor data);
|
||||||
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo,
|
void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo,
|
||||||
Optional<uint64_t> Offset) const;
|
Optional<uint64_t> Offset) const;
|
||||||
|
|
||||||
/// Return the location list at the given offset or nullptr.
|
/// Return the location list at the given offset or nullptr.
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
forEachTypesSections(function_ref<void(const DWARFSection &)> F) const {}
|
forEachTypesSections(function_ref<void(const DWARFSection &)> F) const {}
|
||||||
virtual StringRef getAbbrevSection() const { return ""; }
|
virtual StringRef getAbbrevSection() const { return ""; }
|
||||||
virtual const DWARFSection &getLocSection() const { return Dummy; }
|
virtual const DWARFSection &getLocSection() const { return Dummy; }
|
||||||
|
virtual const DWARFSection &getLoclistsSection() const { return Dummy; }
|
||||||
virtual StringRef getARangeSection() const { return ""; }
|
virtual StringRef getARangeSection() const { return ""; }
|
||||||
virtual StringRef getDebugFrameSection() const { return ""; }
|
virtual StringRef getDebugFrameSection() const { return ""; }
|
||||||
virtual StringRef getEHFrameSection() const { return ""; }
|
virtual StringRef getEHFrameSection() const { return ""; }
|
||||||
|
@ -292,6 +292,27 @@ dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
|
DWARFDataExtractor Data,
|
||||||
|
const MCRegisterInfo *MRI,
|
||||||
|
Optional<uint64_t> DumpOffset) {
|
||||||
|
uint32_t Offset = 0;
|
||||||
|
DWARFDebugLoclists Loclists;
|
||||||
|
|
||||||
|
DWARFListTableHeader Header(".debug_loclists", "locations");
|
||||||
|
if (Error E = Header.extract(Data, &Offset)) {
|
||||||
|
WithColor::error() << toString(std::move(E)) << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Header.dump(OS, DumpOpts);
|
||||||
|
DataExtractor LocData(Data.getData().drop_front(Offset),
|
||||||
|
Data.isLittleEndian(), Header.getAddrSize());
|
||||||
|
|
||||||
|
Loclists.parse(LocData);
|
||||||
|
Loclists.dump(OS, 0, MRI, DumpOffset);
|
||||||
|
}
|
||||||
|
|
||||||
void DWARFContext::dump(
|
void DWARFContext::dump(
|
||||||
raw_ostream &OS, DIDumpOptions DumpOpts,
|
raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
|
std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
|
||||||
@ -366,9 +387,15 @@ void DWARFContext::dump(
|
|||||||
DObj->getLocSection().Data)) {
|
DObj->getLocSection().Data)) {
|
||||||
getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset);
|
getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset);
|
||||||
}
|
}
|
||||||
|
if (shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
|
||||||
|
DObj->getLoclistsSection().Data)) {
|
||||||
|
DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
|
||||||
|
0);
|
||||||
|
dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), DumpOffset);
|
||||||
|
}
|
||||||
if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
|
if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
|
||||||
DObj->getLocDWOSection().Data)) {
|
DObj->getLocDWOSection().Data)) {
|
||||||
getDebugLocDWO()->dump(OS, getRegisterInfo(), DumpOffset);
|
getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), DumpOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
|
if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
|
||||||
@ -696,11 +723,11 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
|
|||||||
return Loc.get();
|
return Loc.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
|
const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() {
|
||||||
if (LocDWO)
|
if (LocDWO)
|
||||||
return LocDWO.get();
|
return LocDWO.get();
|
||||||
|
|
||||||
LocDWO.reset(new DWARFDebugLocDWO());
|
LocDWO.reset(new DWARFDebugLoclists());
|
||||||
// Assume all compile units have the same address byte size.
|
// Assume all compile units have the same address byte size.
|
||||||
// FIXME: We don't need AddressSize for split DWARF since relocatable
|
// FIXME: We don't need AddressSize for split DWARF since relocatable
|
||||||
// addresses cannot appear there. At the moment DWARFExpression requires it.
|
// addresses cannot appear there. At the moment DWARFExpression requires it.
|
||||||
@ -1213,6 +1240,7 @@ class DWARFObjInMemory final : public DWARFObject {
|
|||||||
|
|
||||||
DWARFSectionMap InfoSection;
|
DWARFSectionMap InfoSection;
|
||||||
DWARFSectionMap LocSection;
|
DWARFSectionMap LocSection;
|
||||||
|
DWARFSectionMap LocListsSection;
|
||||||
DWARFSectionMap LineSection;
|
DWARFSectionMap LineSection;
|
||||||
DWARFSectionMap RangeSection;
|
DWARFSectionMap RangeSection;
|
||||||
DWARFSectionMap RnglistsSection;
|
DWARFSectionMap RnglistsSection;
|
||||||
@ -1234,6 +1262,7 @@ class DWARFObjInMemory final : public DWARFObject {
|
|||||||
return StringSwitch<DWARFSectionMap *>(Name)
|
return StringSwitch<DWARFSectionMap *>(Name)
|
||||||
.Case("debug_info", &InfoSection)
|
.Case("debug_info", &InfoSection)
|
||||||
.Case("debug_loc", &LocSection)
|
.Case("debug_loc", &LocSection)
|
||||||
|
.Case("debug_loclists", &LocListsSection)
|
||||||
.Case("debug_line", &LineSection)
|
.Case("debug_line", &LineSection)
|
||||||
.Case("debug_str_offsets", &StringOffsetSection)
|
.Case("debug_str_offsets", &StringOffsetSection)
|
||||||
.Case("debug_ranges", &RangeSection)
|
.Case("debug_ranges", &RangeSection)
|
||||||
@ -1529,6 +1558,7 @@ public:
|
|||||||
|
|
||||||
StringRef getAbbrevSection() const override { return AbbrevSection; }
|
StringRef getAbbrevSection() const override { return AbbrevSection; }
|
||||||
const DWARFSection &getLocSection() const override { return LocSection; }
|
const DWARFSection &getLocSection() const override { return LocSection; }
|
||||||
|
const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
|
||||||
StringRef getARangeSection() const override { return ARangeSection; }
|
StringRef getARangeSection() const override { return ARangeSection; }
|
||||||
StringRef getDebugFrameSection() const override { return DebugFrameSection; }
|
StringRef getDebugFrameSection() const override { return DebugFrameSection; }
|
||||||
StringRef getEHFrameSection() const override { return EHFrameSection; }
|
StringRef getEHFrameSection() const override { return EHFrameSection; }
|
||||||
|
@ -144,24 +144,39 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
|
|||||||
WithColor::error() << "failed to consume entire .debug_loc section\n";
|
WithColor::error() << "failed to consume entire .debug_loc section\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<DWARFDebugLocDWO::LocationList>
|
Optional<DWARFDebugLoclists::LocationList>
|
||||||
DWARFDebugLocDWO::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
|
DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
|
||||||
LocationList LL;
|
LocationList LL;
|
||||||
LL.Offset = *Offset;
|
LL.Offset = *Offset;
|
||||||
|
|
||||||
// dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
|
// dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
|
||||||
while (auto Kind =
|
while (auto Kind =
|
||||||
static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) {
|
static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) {
|
||||||
if (Kind != dwarf::DW_LLE_startx_length) {
|
|
||||||
|
Entry E;
|
||||||
|
E.Kind = Kind;
|
||||||
|
switch (Kind) {
|
||||||
|
case dwarf::DW_LLE_startx_length:
|
||||||
|
E.Value0 = Data.getULEB128(Offset);
|
||||||
|
E.Value1 = Data.getU32(Offset);
|
||||||
|
break;
|
||||||
|
case dwarf::DW_LLE_start_length:
|
||||||
|
E.Value0 = Data.getAddress(Offset);
|
||||||
|
E.Value1 = Data.getULEB128(Offset);
|
||||||
|
break;
|
||||||
|
case dwarf::DW_LLE_offset_pair:
|
||||||
|
E.Value0 = Data.getULEB128(Offset);
|
||||||
|
E.Value1 = Data.getULEB128(Offset);
|
||||||
|
break;
|
||||||
|
case dwarf::DW_LLE_base_address:
|
||||||
|
E.Value0 = Data.getAddress(Offset);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
WithColor::error() << "dumping support for LLE of kind " << (int)Kind
|
WithColor::error() << "dumping support for LLE of kind " << (int)Kind
|
||||||
<< " not implemented\n";
|
<< " not implemented\n";
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry E;
|
|
||||||
E.Start = Data.getULEB128(Offset);
|
|
||||||
E.Length = Data.getU32(Offset);
|
|
||||||
|
|
||||||
unsigned Bytes = Data.getU16(Offset);
|
unsigned Bytes = Data.getU16(Offset);
|
||||||
// A single location description describing the location of the object...
|
// A single location description describing the location of the object...
|
||||||
StringRef str = Data.getData().substr(*Offset, Bytes);
|
StringRef str = Data.getData().substr(*Offset, Bytes);
|
||||||
@ -174,7 +189,7 @@ DWARFDebugLocDWO::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
|
|||||||
return LL;
|
return LL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DWARFDebugLocDWO::parse(DataExtractor data) {
|
void DWARFDebugLoclists::parse(DataExtractor data) {
|
||||||
IsLittleEndian = data.isLittleEndian();
|
IsLittleEndian = data.isLittleEndian();
|
||||||
AddressSize = data.getAddressSize();
|
AddressSize = data.getAddressSize();
|
||||||
|
|
||||||
@ -187,8 +202,8 @@ void DWARFDebugLocDWO::parse(DataExtractor data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWARFDebugLocDWO::LocationList const *
|
DWARFDebugLoclists::LocationList const *
|
||||||
DWARFDebugLocDWO::getLocationListAtOffset(uint64_t Offset) const {
|
DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const {
|
||||||
auto It = std::lower_bound(
|
auto It = std::lower_bound(
|
||||||
Locations.begin(), Locations.end(), Offset,
|
Locations.begin(), Locations.end(), Offset,
|
||||||
[](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; });
|
[](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; });
|
||||||
@ -197,23 +212,46 @@ DWARFDebugLocDWO::getLocationListAtOffset(uint64_t Offset) const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DWARFDebugLocDWO::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
|
void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr,
|
||||||
|
bool IsLittleEndian,
|
||||||
unsigned AddressSize,
|
unsigned AddressSize,
|
||||||
const MCRegisterInfo *MRI,
|
const MCRegisterInfo *MRI,
|
||||||
unsigned Indent) const {
|
unsigned Indent) const {
|
||||||
for (const Entry &E : Entries) {
|
for (const Entry &E : Entries) {
|
||||||
|
switch (E.Kind) {
|
||||||
|
case dwarf::DW_LLE_startx_length:
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
OS.indent(Indent);
|
OS.indent(Indent);
|
||||||
OS << "Addr idx " << E.Start << " (w/ length " << E.Length << "): ";
|
OS << "Addr idx " << E.Value0 << " (w/ length " << E.Value1 << "): ";
|
||||||
|
break;
|
||||||
|
case dwarf::DW_LLE_start_length:
|
||||||
|
OS << '\n';
|
||||||
|
OS.indent(Indent);
|
||||||
|
OS << format("[0x%8.8x, 0x%8.8x): ", E.Value0, E.Value0 + E.Value1);
|
||||||
|
break;
|
||||||
|
case dwarf::DW_LLE_offset_pair:
|
||||||
|
OS << '\n';
|
||||||
|
OS.indent(Indent);
|
||||||
|
OS << format("[0x%8.8x, 0x%8.8x): ", BaseAddr + E.Value0,
|
||||||
|
BaseAddr + E.Value1);
|
||||||
|
break;
|
||||||
|
case dwarf::DW_LLE_base_address:
|
||||||
|
BaseAddr = E.Value0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("unreachable locations list kind");
|
||||||
|
}
|
||||||
|
|
||||||
dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI);
|
dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DWARFDebugLocDWO::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr,
|
||||||
|
const MCRegisterInfo *MRI,
|
||||||
Optional<uint64_t> Offset) const {
|
Optional<uint64_t> Offset) const {
|
||||||
auto DumpLocationList = [&](const LocationList &L) {
|
auto DumpLocationList = [&](const LocationList &L) {
|
||||||
OS << format("0x%8.8x: ", L.Offset);
|
OS << format("0x%8.8x: ", L.Offset);
|
||||||
L.dump(OS, IsLittleEndian, AddressSize, MRI, /*Indent=*/12);
|
L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, /*Indent=*/12);
|
||||||
OS << "\n\n";
|
OS << "\n\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
|
|||||||
FormValue.dump(OS, DumpOpts);
|
FormValue.dump(OS, DumpOpts);
|
||||||
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
|
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
|
||||||
uint32_t Offset = *FormValue.getAsSectionOffset();
|
uint32_t Offset = *FormValue.getAsSectionOffset();
|
||||||
if (!U->isDWOUnit()) {
|
if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) {
|
||||||
DWARFDebugLoc DebugLoc;
|
DWARFDebugLoc DebugLoc;
|
||||||
DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
|
DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
|
||||||
Obj.getAddressSize());
|
Obj.getAddressSize());
|
||||||
@ -115,11 +115,23 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
|
|||||||
Indent);
|
Indent);
|
||||||
} else
|
} else
|
||||||
OS << "error extracting location list.";
|
OS << "error extracting location list.";
|
||||||
} else {
|
return;
|
||||||
DataExtractor Data(U->getLocSectionData(), Ctx.isLittleEndian(), 0);
|
}
|
||||||
auto LL = DWARFDebugLocDWO::parseOneLocationList(Data, &Offset);
|
|
||||||
|
StringRef LoclistsSectionData =
|
||||||
|
U->isDWOUnit() ? U->getLocSectionData() : Obj.getLoclistsSection().Data;
|
||||||
|
if (!LoclistsSectionData.empty()) {
|
||||||
|
DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(),
|
||||||
|
Obj.getAddressSize());
|
||||||
|
auto LL = DWARFDebugLoclists::parseOneLocationList(Data, &Offset);
|
||||||
|
|
||||||
|
uint64_t BaseAddr = 0;
|
||||||
|
if (Optional<SectionedAddress> BA = U->getBaseAddress())
|
||||||
|
BaseAddr = BA->Address;
|
||||||
|
|
||||||
if (LL)
|
if (LL)
|
||||||
LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, Indent);
|
LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI,
|
||||||
|
Indent);
|
||||||
else
|
else
|
||||||
OS << "error extracting location list.";
|
OS << "error extracting location list.";
|
||||||
}
|
}
|
||||||
|
168
test/DebugInfo/X86/dwarfdump-debug-loclists.test
Normal file
168
test/DebugInfo/X86/dwarfdump-debug-loclists.test
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t.o
|
||||||
|
# RUN: llvm-dwarfdump -v %t.o | FileCheck %s
|
||||||
|
|
||||||
|
# CHECK: .debug_info
|
||||||
|
# CHECK: DW_AT_name{{.*}}"stub"
|
||||||
|
# CHECK: DW_AT_location [DW_FORM_sec_offset] (0x0000000c
|
||||||
|
# CHECK-NEXT: [0x00000010, 0x00000020): DW_OP_breg5 RDI+0
|
||||||
|
# CHECK-NEXT: [0x00000530, 0x00000540): DW_OP_breg6 RBP-8, DW_OP_deref
|
||||||
|
# CHECK-NEXT: [0x00000700, 0x00000710): DW_OP_breg5 RDI+0
|
||||||
|
|
||||||
|
# CHECK: .debug_loclists contents:
|
||||||
|
# CHECK-NEXT: 0x00000000: locations list header: length = 0x00000031, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
|
||||||
|
# CHECK-NEXT: 0x00000000:
|
||||||
|
# CHECK-NEXT: [0x00000000, 0x00000010): DW_OP_breg5 RDI+0
|
||||||
|
# CHECK-NEXT: [0x00000530, 0x00000540): DW_OP_breg6 RBP-8, DW_OP_deref
|
||||||
|
# CHECK-NEXT: [0x00000700, 0x00000710): DW_OP_breg5 RDI+0
|
||||||
|
|
||||||
|
.section .debug_str,"MS",@progbits,1
|
||||||
|
.asciz "stub"
|
||||||
|
|
||||||
|
.section .debug_str_offsets,"",@progbits
|
||||||
|
.long 68
|
||||||
|
.short 5
|
||||||
|
.short 0
|
||||||
|
.Lstr_offsets_base0:
|
||||||
|
.zero 64
|
||||||
|
|
||||||
|
.section .debug_loclists,"",@progbits
|
||||||
|
.long .Ldebug_loclist_table_end0-.Ldebug_loclist_table_start0
|
||||||
|
.Ldebug_loclist_table_start0:
|
||||||
|
.short 5 # Version.
|
||||||
|
.byte 8 # Address size.
|
||||||
|
.byte 0 # Segmen selector size.
|
||||||
|
.long 0 # Offset entry count.
|
||||||
|
.Lloclists_table_base0:
|
||||||
|
.Ldebug_loc0:
|
||||||
|
.byte 4 # DW_LLE_offset_pair
|
||||||
|
.uleb128 0x0 # starting offset
|
||||||
|
.uleb128 0x10 # ending offset
|
||||||
|
.short 2 # Loc expr size
|
||||||
|
.byte 117 # DW_OP_breg5
|
||||||
|
.byte 0 # 0
|
||||||
|
|
||||||
|
.byte 6 # DW_LLE_base_address
|
||||||
|
.quad 0x500 # Some address
|
||||||
|
.short 0 # Loc expr size = 0.
|
||||||
|
|
||||||
|
.byte 4 # DW_LLE_offset_pair
|
||||||
|
.uleb128 0x30 # starting offset
|
||||||
|
.uleb128 0x40 # ending offset
|
||||||
|
.short 3 # Loc expr size
|
||||||
|
.byte 118 # DW_OP_breg6
|
||||||
|
.byte 120 # -8
|
||||||
|
.byte 6 # DW_OP_deref
|
||||||
|
|
||||||
|
.byte 8 # DW_LLE_start_length
|
||||||
|
.quad 0x700 # Some address
|
||||||
|
.uleb128 0x10 # length
|
||||||
|
.short 2 # Loc expr size
|
||||||
|
.byte 117 # DW_OP_breg5
|
||||||
|
.byte 0 # 0
|
||||||
|
|
||||||
|
.byte 0 # DW_LLE_end_of_list
|
||||||
|
|
||||||
|
.Ldebug_loclist_table_end0:
|
||||||
|
|
||||||
|
.section .debug_abbrev,"",@progbits
|
||||||
|
.byte 1 # Abbreviation Code
|
||||||
|
.byte 17 # DW_TAG_compile_unit
|
||||||
|
.byte 1 # DW_CHILDREN_yes
|
||||||
|
.byte 37 # DW_AT_producer
|
||||||
|
.byte 37 # DW_FORM_strx1
|
||||||
|
.byte 19 # DW_AT_language
|
||||||
|
.byte 5 # DW_FORM_data2
|
||||||
|
.byte 3 # DW_AT_name
|
||||||
|
.byte 37 # DW_FORM_strx1
|
||||||
|
.byte 114 # DW_AT_str_offsets_base
|
||||||
|
.byte 23 # DW_FORM_sec_offset
|
||||||
|
.byte 16 # DW_AT_stmt_list
|
||||||
|
.byte 23 # DW_FORM_sec_offset
|
||||||
|
.byte 27 # DW_AT_comp_dir
|
||||||
|
.byte 37 # DW_FORM_strx1
|
||||||
|
.byte 17 # DW_AT_low_pc
|
||||||
|
.byte 1 # DW_FORM_addr
|
||||||
|
.byte 18 # DW_AT_high_pc
|
||||||
|
.byte 6 # DW_FORM_data4
|
||||||
|
.ascii "\214\001" # DW_AT_loclists_base
|
||||||
|
.byte 23 # DW_FORM_sec_offset
|
||||||
|
.byte 0 # EOM(1)
|
||||||
|
.byte 0 # EOM(2)
|
||||||
|
.byte 2 # Abbreviation Code
|
||||||
|
.byte 46 # DW_TAG_subprogram
|
||||||
|
.byte 1 # DW_CHILDREN_yes
|
||||||
|
.byte 17 # DW_AT_low_pc
|
||||||
|
.byte 1 # DW_FORM_addr
|
||||||
|
.byte 18 # DW_AT_high_pc
|
||||||
|
.byte 6 # DW_FORM_data4
|
||||||
|
.byte 64 # DW_AT_frame_base
|
||||||
|
.byte 24 # DW_FORM_exprloc
|
||||||
|
.byte 110 # DW_AT_linkage_name
|
||||||
|
.byte 37 # DW_FORM_strx1
|
||||||
|
.byte 3 # DW_AT_name
|
||||||
|
.byte 37 # DW_FORM_strx1
|
||||||
|
.byte 58 # DW_AT_decl_file
|
||||||
|
.byte 11 # DW_FORM_data1
|
||||||
|
.byte 59 # DW_AT_decl_line
|
||||||
|
.byte 11 # DW_FORM_data1
|
||||||
|
.byte 63 # DW_AT_external
|
||||||
|
.byte 25 # DW_FORM_flag_present
|
||||||
|
.byte 0 # EOM(1)
|
||||||
|
.byte 0 # EOM(2)
|
||||||
|
.byte 3 # Abbreviation Code
|
||||||
|
.byte 52 # DW_TAG_variable
|
||||||
|
.byte 0 # DW_CHILDREN_no
|
||||||
|
.byte 2 # DW_AT_location
|
||||||
|
.byte 23 # DW_FORM_sec_offset
|
||||||
|
.byte 3 # DW_AT_name
|
||||||
|
.byte 37 # DW_FORM_strx1
|
||||||
|
.byte 58 # DW_AT_decl_file
|
||||||
|
.byte 11 # DW_FORM_data1
|
||||||
|
.byte 59 # DW_AT_decl_line
|
||||||
|
.byte 11 # DW_FORM_data1
|
||||||
|
.byte 73 # DW_AT_type
|
||||||
|
.byte 19 # DW_FORM_ref4
|
||||||
|
.byte 0 # EOM(1)
|
||||||
|
.byte 0 # EOM(2)
|
||||||
|
.byte 0 # EOM(3)
|
||||||
|
|
||||||
|
.section .debug_info,"",@progbits
|
||||||
|
.Lcu_begin0:
|
||||||
|
.long 70 # Length of Unit
|
||||||
|
.short 5 # DWARF version number
|
||||||
|
.byte 1 # DWARF Unit Type
|
||||||
|
.byte 8 # Address Size (in bytes)
|
||||||
|
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||||
|
.byte 1 # Abbrev [1] 0xc:0xef DW_TAG_compile_unit
|
||||||
|
.byte 0 # DW_AT_producer
|
||||||
|
.short 4 # DW_AT_language
|
||||||
|
.byte 1 # DW_AT_name
|
||||||
|
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||||
|
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||||
|
.byte 2 # DW_AT_comp_dir
|
||||||
|
.quad 0x10 # DW_AT_low_pc
|
||||||
|
.long 0 # DW_AT_high_pc
|
||||||
|
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||||
|
.byte 2 # Abbrev [2] 0x2a:0x20 DW_TAG_subprogram
|
||||||
|
.quad 0 # DW_AT_low_pc
|
||||||
|
.long 0 # DW_AT_high_pc
|
||||||
|
.byte 1 # DW_AT_frame_base
|
||||||
|
.byte 86
|
||||||
|
.byte 11 # DW_AT_linkage_name
|
||||||
|
.byte 12 # DW_AT_name
|
||||||
|
.byte 1 # DW_AT_decl_file
|
||||||
|
.byte 6 # DW_AT_decl_line
|
||||||
|
# DW_AT_external
|
||||||
|
.byte 3 # Abbrev [3] 0x40:0xb DW_TAG_variable
|
||||||
|
.long .Ldebug_loc0 # DW_AT_location
|
||||||
|
.byte 7 # DW_AT_name
|
||||||
|
.byte 1 # DW_AT_decl_file
|
||||||
|
.byte 6 # DW_AT_decl_line
|
||||||
|
.long 76 # DW_AT_type
|
||||||
|
.byte 0 # End Of Children Mark
|
||||||
|
.byte 0 # End Of Children Mark
|
||||||
|
.byte 0 # End Of Children Mark
|
||||||
|
|
||||||
|
.section .debug_line,"",@progbits
|
||||||
|
.Lline_table_start0:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user