forked from OSchip/llvm-project
[BOLT][DWARF] Implement monolithic DWARF5
Added implementation to support DWARF5 in monolithic mode. Next step DWARF5 split dwarf support. Reviewed By: maksfb Differential Revision: https://reviews.llvm.org/D121876
This commit is contained in:
parent
3348991106
commit
014cd37f51
|
@ -204,6 +204,9 @@ class BinaryContext {
|
|||
using DWOIdToCUMapType = std::unordered_map<uint64_t, DWARFUnit *>;
|
||||
DWOIdToCUMapType DWOCUs;
|
||||
|
||||
bool ContainsDwarf5{false};
|
||||
bool ContainsDwarfLegacy{false};
|
||||
|
||||
/// Preprocess DWO debug information.
|
||||
void preprocessDWODebugInfo();
|
||||
|
||||
|
@ -234,7 +237,13 @@ public:
|
|||
/// Get Number of DWOCUs in a map.
|
||||
uint32_t getNumDWOCUs() { return DWOCUs.size(); }
|
||||
|
||||
const std::map<unsigned, DwarfLineTable> &getDwarfLineTables() const {
|
||||
/// Returns true if DWARF5 is used.
|
||||
bool isDWARF5Used() const { return ContainsDwarf5; }
|
||||
|
||||
/// Returns true if DWARF4 or lower is used.
|
||||
bool isDWARFLegacyUsed() const { return ContainsDwarfLegacy; }
|
||||
|
||||
std::map<unsigned, DwarfLineTable> &getDwarfLineTables() {
|
||||
return DwarfLineTablesCUMap;
|
||||
}
|
||||
|
||||
|
@ -245,7 +254,8 @@ public:
|
|||
Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName,
|
||||
unsigned FileNumber,
|
||||
Optional<MD5::MD5Result> Checksum,
|
||||
Optional<StringRef> Source, unsigned CUID);
|
||||
Optional<StringRef> Source, unsigned CUID,
|
||||
unsigned DWARFVersion);
|
||||
|
||||
/// [start memory address] -> [segment info] mapping.
|
||||
std::map<uint64_t, SegmentInfo> SegmentMapInfo;
|
||||
|
|
|
@ -34,6 +34,21 @@ namespace llvm {
|
|||
|
||||
namespace bolt {
|
||||
|
||||
// DWARF5 Header in order of encoding.
|
||||
// Types represent encodnig sizes.
|
||||
using UnitLengthType = uint32_t;
|
||||
using VersionType = uint16_t;
|
||||
using AddressSizeType = uint8_t;
|
||||
using SegmentSelectorType = uint8_t;
|
||||
using OffsetEntryCountType = uint32_t;
|
||||
/// Get DWARF5 Header size.
|
||||
/// Rangelists and Loclists have the same header.
|
||||
constexpr uint32_t getDWARF5RngListLocListHeaderSize() {
|
||||
return sizeof(UnitLengthType) + sizeof(VersionType) +
|
||||
sizeof(AddressSizeType) + sizeof(SegmentSelectorType) +
|
||||
sizeof(OffsetEntryCountType);
|
||||
}
|
||||
|
||||
class BinaryContext;
|
||||
|
||||
/// Address range representation. Takes less space than DWARFAddressRange.
|
||||
|
@ -114,18 +129,23 @@ struct CUInfo {
|
|||
};
|
||||
using CUOffsetMap = std::map<uint32_t, CUInfo>;
|
||||
|
||||
enum class RangesWriterKind { DebugRangesWriter, DebugRangeListsWriter };
|
||||
/// Serializes the .debug_ranges DWARF section.
|
||||
class DebugRangesSectionWriter {
|
||||
public:
|
||||
DebugRangesSectionWriter();
|
||||
|
||||
DebugRangesSectionWriter(RangesWriterKind K) : Kind(K){};
|
||||
|
||||
virtual ~DebugRangesSectionWriter(){};
|
||||
|
||||
/// Add ranges with caching.
|
||||
uint64_t
|
||||
virtual uint64_t
|
||||
addRanges(DebugAddressRangesVector &&Ranges,
|
||||
std::map<DebugAddressRangesVector, uint64_t> &CachedRanges);
|
||||
|
||||
/// Add ranges and return offset into section.
|
||||
uint64_t addRanges(const DebugAddressRangesVector &Ranges);
|
||||
virtual uint64_t addRanges(const DebugAddressRangesVector &Ranges);
|
||||
|
||||
/// Returns an offset of an empty address ranges list that is always written
|
||||
/// to .debug_ranges
|
||||
|
@ -134,11 +154,18 @@ public:
|
|||
/// Returns the SectionOffset.
|
||||
uint64_t getSectionOffset();
|
||||
|
||||
std::unique_ptr<DebugBufferVector> finalize() {
|
||||
/// Returns a buffer containing Ranges.
|
||||
virtual std::unique_ptr<DebugBufferVector> finalize() {
|
||||
return std::move(RangesBuffer);
|
||||
}
|
||||
|
||||
private:
|
||||
RangesWriterKind getKind() const { return Kind; }
|
||||
|
||||
static bool classof(const DebugRangesSectionWriter *Writer) {
|
||||
return Writer->getKind() == RangesWriterKind::DebugRangesWriter;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<DebugBufferVector> RangesBuffer;
|
||||
|
||||
std::unique_ptr<raw_svector_ostream> RangesStream;
|
||||
|
@ -151,6 +178,58 @@ private:
|
|||
|
||||
/// Offset of an empty address ranges list.
|
||||
static constexpr uint64_t EmptyRangesOffset{0};
|
||||
|
||||
private:
|
||||
RangesWriterKind Kind;
|
||||
};
|
||||
|
||||
class DebugAddrWriter;
|
||||
class DebugRangeListsSectionWriter : public DebugRangesSectionWriter {
|
||||
public:
|
||||
DebugRangeListsSectionWriter()
|
||||
: DebugRangesSectionWriter(RangesWriterKind::DebugRangeListsWriter) {
|
||||
RangesBuffer = std::make_unique<DebugBufferVector>();
|
||||
RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer);
|
||||
};
|
||||
virtual ~DebugRangeListsSectionWriter(){};
|
||||
|
||||
static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
|
||||
|
||||
/// Add ranges with caching.
|
||||
virtual uint64_t addRanges(
|
||||
DebugAddressRangesVector &&Ranges,
|
||||
std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) override;
|
||||
|
||||
/// Add ranges and return offset into section.
|
||||
virtual uint64_t addRanges(const DebugAddressRangesVector &Ranges) override;
|
||||
|
||||
virtual std::unique_ptr<DebugBufferVector> finalize() override {
|
||||
return std::move(RangesBuffer);
|
||||
}
|
||||
|
||||
/// Needs to be invoked before each CU is processed.
|
||||
/// \p CUID is a unique ID of each CU.
|
||||
void initSection(uint64_t CUID);
|
||||
|
||||
/// Writes out range lists for a current CU being processed.
|
||||
void finalizeSection();
|
||||
|
||||
static bool classof(const DebugRangesSectionWriter *Writer) {
|
||||
return Writer->getKind() == RangesWriterKind::DebugRangeListsWriter;
|
||||
}
|
||||
|
||||
private:
|
||||
static DebugAddrWriter *AddrWriter;
|
||||
/// Unique ID of CU being processed.
|
||||
uint64_t CUID{0};
|
||||
/// Current relative offset of range list entry within this CUs rangelist
|
||||
/// body.
|
||||
uint32_t CurrentOffset{0};
|
||||
/// Contains relative offset of each range list entry.
|
||||
SmallVector<uint32_t, 1> RangeEntries;
|
||||
|
||||
std::unique_ptr<DebugBufferVector> CUBodyBuffer;
|
||||
std::unique_ptr<raw_svector_ostream> CUBodyStream;
|
||||
};
|
||||
|
||||
/// Serializes the .debug_aranges DWARF section.
|
||||
|
@ -193,23 +272,25 @@ class DebugAddrWriter {
|
|||
public:
|
||||
DebugAddrWriter() = delete;
|
||||
DebugAddrWriter(BinaryContext *BC_);
|
||||
virtual ~DebugAddrWriter(){};
|
||||
/// Given an address returns an index in .debug_addr.
|
||||
/// Adds Address to map.
|
||||
uint32_t getIndexFromAddress(uint64_t Address, uint64_t DWOId);
|
||||
uint32_t getIndexFromAddress(uint64_t Address, uint64_t CUID);
|
||||
|
||||
/// Adds {Address, Index} to DWO ID CU.
|
||||
void addIndexAddress(uint64_t Address, uint32_t Index, uint64_t DWOId);
|
||||
void addIndexAddress(uint64_t Address, uint32_t Index, uint64_t CUID);
|
||||
|
||||
/// Creates consolidated .debug_addr section, and builds DWOID to offset map.
|
||||
AddressSectionBuffer finalize();
|
||||
virtual AddressSectionBuffer finalize();
|
||||
|
||||
/// Given DWOID returns offset of this CU in to .debug_addr section.
|
||||
uint64_t getOffset(uint64_t DWOId);
|
||||
/// Given DWARFUnit \p Unit returns offset of this CU in to .debug_addr
|
||||
/// section.
|
||||
virtual uint64_t getOffset(DWARFUnit &Unit);
|
||||
|
||||
/// Returns False if .debug_addr section was created..
|
||||
bool isInitialized() const { return !AddressMaps.empty(); }
|
||||
|
||||
private:
|
||||
protected:
|
||||
class AddressForDWOCU {
|
||||
public:
|
||||
AddressToIndexMap::iterator find(uint64_t Adddress) {
|
||||
|
@ -266,6 +347,18 @@ private:
|
|||
std::mutex WriterMutex;
|
||||
};
|
||||
|
||||
class DebugAddrWriterDwarf5 : public DebugAddrWriter {
|
||||
public:
|
||||
DebugAddrWriterDwarf5() = delete;
|
||||
DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
|
||||
|
||||
/// Creates consolidated .debug_addr section, and builds DWOID to offset map.
|
||||
virtual AddressSectionBuffer finalize() override;
|
||||
/// Given DWARFUnit \p Unit returns offset of this CU in to .debug_addr
|
||||
/// section.
|
||||
virtual uint64_t getOffset(DWARFUnit &Unit) override;
|
||||
};
|
||||
|
||||
using DebugStrBufferVector = SmallVector<char, 16>;
|
||||
class DebugStrWriter {
|
||||
public:
|
||||
|
@ -305,7 +398,8 @@ public:
|
|||
virtual ~DebugLocWriter(){};
|
||||
|
||||
/// Writes out location lists and stores internal patches.
|
||||
virtual void addList(uint64_t AttrOffset, DebugLocationsVector &&LocList);
|
||||
virtual void addList(uint64_t AttrOffset, uint32_t LocListIndex,
|
||||
DebugLocationsVector &&LocList);
|
||||
|
||||
/// Writes out locations in to a local buffer, and adds Debug Info patches.
|
||||
virtual void finalize(uint64_t SectionOffset,
|
||||
|
@ -314,6 +408,9 @@ public:
|
|||
/// Return internal buffer.
|
||||
virtual std::unique_ptr<DebugBufferVector> getBuffer();
|
||||
|
||||
/// Returns DWARF version.
|
||||
uint8_t getDwarfVersion() const { return DwarfVersion; }
|
||||
|
||||
/// Offset of an empty location list.
|
||||
static constexpr uint32_t EmptyListOffset = 0;
|
||||
|
||||
|
@ -325,13 +422,13 @@ public:
|
|||
|
||||
protected:
|
||||
std::unique_ptr<DebugBufferVector> LocBuffer;
|
||||
|
||||
std::unique_ptr<raw_svector_ostream> LocStream;
|
||||
/// Current offset in the section (updated as new entries are written).
|
||||
/// Starts with 0 here since this only writes part of a full location lists
|
||||
/// section. In the final section, the first 16 bytes are reserved for an
|
||||
/// empty list.
|
||||
uint32_t SectionOffset{0};
|
||||
uint8_t DwarfVersion{4};
|
||||
LocWriterKind Kind{LocWriterKind::DebugLocWriter};
|
||||
|
||||
private:
|
||||
|
@ -354,9 +451,12 @@ class DebugLoclistWriter : public DebugLocWriter {
|
|||
public:
|
||||
~DebugLoclistWriter() {}
|
||||
DebugLoclistWriter() = delete;
|
||||
DebugLoclistWriter(BinaryContext *BC, uint64_t DWOId_)
|
||||
: DebugLocWriter(BC), DWOId(DWOId_) {
|
||||
DebugLoclistWriter(BinaryContext *BC, uint64_t CID,
|
||||
uint32_t LocListsBaseAttrOffset, uint8_t DV, bool SD)
|
||||
: DebugLocWriter(BC), CUID(CID),
|
||||
LocListsBaseAttrOffset(LocListsBaseAttrOffset), IsSplitDwarf(SD) {
|
||||
Kind = LocWriterKind::DebugLoclistWriter;
|
||||
DwarfVersion = DV;
|
||||
assert(DebugLoclistWriter::AddrWriter &&
|
||||
"Please use SetAddressWriter to initialize "
|
||||
"DebugAddrWriter before instantiation.");
|
||||
|
@ -365,7 +465,7 @@ public:
|
|||
static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
|
||||
|
||||
/// Stores location lists internally to be written out during finalize phase.
|
||||
virtual void addList(uint64_t AttrOffset,
|
||||
virtual void addList(uint64_t AttrOffset, uint32_t LocListIndex,
|
||||
DebugLocationsVector &&LocList) override;
|
||||
|
||||
/// Writes out locations in to a local buffer and applies debug info patches.
|
||||
|
@ -373,15 +473,31 @@ public:
|
|||
SimpleBinaryPatcher &DebugInfoPatcher) override;
|
||||
|
||||
/// Returns DWO ID.
|
||||
uint64_t getDWOID() const { return DWOId; }
|
||||
uint64_t getCUID() const { return CUID; }
|
||||
|
||||
LocWriterKind getKind() const { return DebugLocWriter::getKind(); }
|
||||
|
||||
static bool classof(const DebugLocWriter *Writer) {
|
||||
return Writer->getKind() == LocWriterKind::DebugLoclistWriter;
|
||||
}
|
||||
|
||||
bool isSplitDwarf() const { return IsSplitDwarf; }
|
||||
|
||||
constexpr static uint32_t InvalidIndex = UINT32_MAX;
|
||||
constexpr static uint32_t InvalidLocListsBaseAttrOffset = UINT32_MAX;
|
||||
|
||||
private:
|
||||
/// Writes out locations in to a local buffer and applies debug info patches.
|
||||
void finalizeDWARFLegacy(uint64_t SectionOffset,
|
||||
SimpleBinaryPatcher &DebugInfoPatcher);
|
||||
|
||||
/// Writes out locations in to a local buffer and applies debug info patches.
|
||||
void finalizeDWARF5(uint64_t SectionOffset,
|
||||
SimpleBinaryPatcher &DebugInfoPatcher);
|
||||
|
||||
struct LocPatch {
|
||||
uint64_t AttrOffset{0};
|
||||
uint32_t Index;
|
||||
DebugLocationsVector LocList;
|
||||
};
|
||||
using LocPatchVec = SmallVector<LocPatch, 4>;
|
||||
|
@ -395,7 +511,9 @@ private:
|
|||
uint64_t Address{0};
|
||||
};
|
||||
static DebugAddrWriter *AddrWriter;
|
||||
uint64_t DWOId{0};
|
||||
uint64_t CUID{0};
|
||||
uint32_t LocListsBaseAttrOffset{InvalidLocListsBaseAttrOffset};
|
||||
bool IsSplitDwarf{false};
|
||||
};
|
||||
|
||||
enum class PatcherKind { SimpleBinaryPatcher, DebugInfoBinaryPatcher };
|
||||
|
@ -914,6 +1032,9 @@ private:
|
|||
/// Raw data representing complete debug line section for the unit.
|
||||
StringRef RawData;
|
||||
|
||||
/// DWARF Version
|
||||
uint16_t DwarfVersion;
|
||||
|
||||
public:
|
||||
/// Emit line info for all units in the binary context.
|
||||
static void emit(BinaryContext &BC, MCStreamer &Streamer);
|
||||
|
@ -937,6 +1058,14 @@ public:
|
|||
|
||||
void setLabel(MCSymbol *Label) { Header.Label = Label; }
|
||||
|
||||
/// Sets the root file \p Directory, \p FileName, optional \p CheckSum, and
|
||||
/// optional \p Source.
|
||||
void setRootFile(StringRef Directory, StringRef FileName,
|
||||
Optional<MD5::MD5Result> Checksum,
|
||||
Optional<StringRef> Source) {
|
||||
Header.setRootFile(Directory, FileName, Checksum, Source);
|
||||
}
|
||||
|
||||
/// Access to MC line info.
|
||||
MCLineSection &getMCLineSections() { return MCLineSections; }
|
||||
|
||||
|
@ -956,6 +1085,12 @@ public:
|
|||
void addRawContents(StringRef DebugLineContents) {
|
||||
RawData = DebugLineContents;
|
||||
}
|
||||
|
||||
/// Sets DWARF version for this line table.
|
||||
void setDwarfVersion(uint16_t V) { DwarfVersion = V; }
|
||||
|
||||
// Returns DWARF Version for this line table.
|
||||
uint16_t getDwarfVersion() const { return DwarfVersion; }
|
||||
};
|
||||
|
||||
struct AttrInfo {
|
||||
|
|
|
@ -51,8 +51,7 @@ class DWARFRewriter {
|
|||
/// .debug_abbrev section writer for the main binary.
|
||||
std::unique_ptr<DebugAbbrevWriter> AbbrevWriter;
|
||||
|
||||
using LocWriters =
|
||||
std::unordered_map<uint64_t, std::unique_ptr<DebugLocWriter>>;
|
||||
using LocWriters = std::map<uint64_t, std::unique_ptr<DebugLocWriter>>;
|
||||
/// Use a separate location list writer for each compilation unit
|
||||
LocWriters LocListWritersByCU;
|
||||
|
||||
|
@ -68,11 +67,15 @@ class DWARFRewriter {
|
|||
|
||||
std::mutex LocListDebugInfoPatchesMutex;
|
||||
|
||||
/// DWARFLegacy is all DWARF versions before DWARF 5.
|
||||
enum class DWARFVersion { DWARFLegacy, DWARF5 };
|
||||
|
||||
/// Update debug info for all DIEs in \p Unit.
|
||||
void updateUnitDebugInfo(DWARFUnit &Unit,
|
||||
DebugInfoBinaryPatcher &DebugInfoPatcher,
|
||||
DebugAbbrevWriter &AbbrevWriter,
|
||||
DebugLocWriter &DebugLocWriter,
|
||||
DebugRangesSectionWriter &RangesWriter,
|
||||
Optional<uint64_t> RangesBase = None);
|
||||
|
||||
/// Patches the binary for an object's address ranges to be updated.
|
||||
|
@ -91,7 +94,8 @@ class DWARFRewriter {
|
|||
Optional<uint64_t> RangesBase = None);
|
||||
|
||||
std::unique_ptr<DebugBufferVector>
|
||||
makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher);
|
||||
makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher,
|
||||
DWARFVersion Version);
|
||||
|
||||
/// Finalize debug sections in the main binary.
|
||||
CUOffsetMap finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher);
|
||||
|
|
|
@ -1325,14 +1325,13 @@ void BinaryContext::printGlobalSymbols(raw_ostream &OS) const {
|
|||
}
|
||||
}
|
||||
|
||||
Expected<unsigned>
|
||||
BinaryContext::getDwarfFile(StringRef Directory, StringRef FileName,
|
||||
unsigned FileNumber,
|
||||
Optional<MD5::MD5Result> Checksum,
|
||||
Optional<StringRef> Source, unsigned CUID) {
|
||||
Expected<unsigned> BinaryContext::getDwarfFile(
|
||||
StringRef Directory, StringRef FileName, unsigned FileNumber,
|
||||
Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source,
|
||||
unsigned CUID, unsigned DWARFVersion) {
|
||||
DwarfLineTable &Table = DwarfLineTablesCUMap[CUID];
|
||||
return Table.tryGetFile(Directory, FileName, Checksum, Source,
|
||||
Ctx->getDwarfVersion(), FileNumber);
|
||||
return Table.tryGetFile(Directory, FileName, Checksum, Source, DWARFVersion,
|
||||
FileNumber);
|
||||
}
|
||||
|
||||
unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
|
||||
|
@ -1360,7 +1359,9 @@ unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
|
|||
dwarf::toString(FileNames[FileIndex - 1].Name))
|
||||
FileName = *FName;
|
||||
assert(FileName != "");
|
||||
return cantFail(getDwarfFile(Dir, FileName, 0, None, None, DestCUID));
|
||||
DWARFCompileUnit *DstUnit = DwCtx->getCompileUnitForOffset(DestCUID);
|
||||
return cantFail(getDwarfFile(Dir, FileName, 0, None, None, DestCUID,
|
||||
DstUnit->getVersion()));
|
||||
}
|
||||
|
||||
std::vector<BinaryFunction *> BinaryContext::getSortedFunctions() {
|
||||
|
@ -1458,8 +1459,15 @@ void BinaryContext::preprocessDebugInfo() {
|
|||
if (containsAddress(Range.LowPC))
|
||||
AllRanges.emplace_back(CURange{Range.LowPC, Range.HighPC, CU.get()});
|
||||
}
|
||||
|
||||
ContainsDwarf5 |= CU->getVersion() >= 5;
|
||||
ContainsDwarfLegacy |= CU->getVersion() < 5;
|
||||
}
|
||||
|
||||
if (ContainsDwarf5 && ContainsDwarfLegacy)
|
||||
llvm::errs() << "BOLT-WARNING: BOLT does not support mix mode binary with "
|
||||
"DWARF5 and DWARF{2,3,4}.\n";
|
||||
|
||||
std::sort(AllRanges.begin(), AllRanges.end());
|
||||
for (auto &KV : BinaryFunctions) {
|
||||
const uint64_t FunctionAddress = KV.first;
|
||||
|
@ -1496,7 +1504,8 @@ void BinaryContext::preprocessDebugInfo() {
|
|||
StringRef GlobalPrefix = AsmInfo->getPrivateGlobalPrefix();
|
||||
for (const std::unique_ptr<DWARFUnit> &CU : DwCtx->compile_units()) {
|
||||
const uint64_t CUID = CU->getOffset();
|
||||
getDwarfLineTable(CUID).setLabel(Ctx->getOrCreateSymbol(
|
||||
DwarfLineTable &BinaryLineTable = getDwarfLineTable(CUID);
|
||||
BinaryLineTable.setLabel(Ctx->getOrCreateSymbol(
|
||||
GlobalPrefix + "line_table_start" + Twine(CUID)));
|
||||
|
||||
if (!ProcessedCUs.count(CU.get()))
|
||||
|
@ -1507,26 +1516,45 @@ void BinaryContext::preprocessDebugInfo() {
|
|||
const std::vector<DWARFDebugLine::FileNameEntry> &FileNames =
|
||||
LineTable->Prologue.FileNames;
|
||||
|
||||
uint16_t DwarfVersion = LineTable->Prologue.getVersion();
|
||||
if (DwarfVersion >= 5) {
|
||||
Optional<MD5::MD5Result> Checksum = None;
|
||||
if (LineTable->Prologue.ContentTypes.HasMD5)
|
||||
Checksum = LineTable->Prologue.FileNames[0].Checksum;
|
||||
BinaryLineTable.setRootFile(
|
||||
CU->getCompilationDir(),
|
||||
dwarf::toString(CU->getUnitDIE().find(dwarf::DW_AT_name), nullptr),
|
||||
Checksum, None);
|
||||
}
|
||||
|
||||
BinaryLineTable.setDwarfVersion(DwarfVersion);
|
||||
|
||||
// Assign a unique label to every line table, one per CU.
|
||||
// Make sure empty debug line tables are registered too.
|
||||
if (FileNames.empty()) {
|
||||
cantFail(getDwarfFile("", "<unknown>", 0, None, None, CUID));
|
||||
cantFail(
|
||||
getDwarfFile("", "<unknown>", 0, None, None, CUID, DwarfVersion));
|
||||
continue;
|
||||
}
|
||||
const uint32_t Offset = DwarfVersion < 5 ? 1 : 0;
|
||||
for (size_t I = 0, Size = FileNames.size(); I != Size; ++I) {
|
||||
// Dir indexes start at 1, as DWARF file numbers, and a dir index 0
|
||||
// means empty dir.
|
||||
StringRef Dir = "";
|
||||
if (FileNames[I].DirIdx != 0)
|
||||
if (FileNames[I].DirIdx != 0 || DwarfVersion >= 5)
|
||||
if (Optional<const char *> DirName = dwarf::toString(
|
||||
LineTable->Prologue
|
||||
.IncludeDirectories[FileNames[I].DirIdx - 1]))
|
||||
.IncludeDirectories[FileNames[I].DirIdx - Offset]))
|
||||
Dir = *DirName;
|
||||
StringRef FileName = "";
|
||||
if (Optional<const char *> FName = dwarf::toString(FileNames[I].Name))
|
||||
FileName = *FName;
|
||||
assert(FileName != "");
|
||||
cantFail(getDwarfFile(Dir, FileName, 0, None, None, CUID));
|
||||
Optional<MD5::MD5Result> Checksum = None;
|
||||
if (DwarfVersion >= 5 && LineTable->Prologue.ContentTypes.HasMD5)
|
||||
Checksum = LineTable->Prologue.FileNames[I].Checksum;
|
||||
cantFail(
|
||||
getDwarfFile(Dir, FileName, 0, Checksum, None, CUID, DwarfVersion));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,11 @@
|
|||
|
||||
#include "bolt/Core/DebugData.h"
|
||||
#include "bolt/Core/BinaryContext.h"
|
||||
#include "bolt/Rewrite/RewriteInstance.h"
|
||||
#include "bolt/Utils/Utils.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
|
||||
#include "llvm/MC/MCAssembler.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCObjectStreamer.h"
|
||||
|
@ -118,6 +120,7 @@ DebugRangesSectionWriter::DebugRangesSectionWriter() {
|
|||
// Add an empty range as the first entry;
|
||||
SectionOffset +=
|
||||
writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
|
||||
Kind = RangesWriterKind::DebugRangesWriter;
|
||||
}
|
||||
|
||||
uint64_t DebugRangesSectionWriter::addRanges(
|
||||
|
@ -155,6 +158,94 @@ uint64_t DebugRangesSectionWriter::getSectionOffset() {
|
|||
return SectionOffset;
|
||||
}
|
||||
|
||||
DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
|
||||
|
||||
uint64_t DebugRangeListsSectionWriter::addRanges(
|
||||
DebugAddressRangesVector &&Ranges,
|
||||
std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
|
||||
return addRanges(Ranges);
|
||||
}
|
||||
|
||||
struct LocListsRangelistsHeader {
|
||||
UnitLengthType UnitLength; // Size of loclist entris section, not including
|
||||
// size of header.
|
||||
VersionType Version;
|
||||
AddressSizeType AddressSize;
|
||||
SegmentSelectorType SegmentSelector;
|
||||
OffsetEntryCountType OffsetEntryCount;
|
||||
};
|
||||
|
||||
static std::unique_ptr<DebugBufferVector>
|
||||
getDWARF5Header(const LocListsRangelistsHeader &Header) {
|
||||
std::unique_ptr<DebugBufferVector> HeaderBuffer =
|
||||
std::make_unique<DebugBufferVector>();
|
||||
std::unique_ptr<raw_svector_ostream> HeaderStream =
|
||||
std::make_unique<raw_svector_ostream>(*HeaderBuffer);
|
||||
|
||||
// 7.29 length of the set of entries for this compilation unit, not including
|
||||
// the length field itself
|
||||
const uint32_t HeaderSize =
|
||||
getDWARF5RngListLocListHeaderSize() - sizeof(UnitLengthType);
|
||||
|
||||
support::endian::write(*HeaderStream, Header.UnitLength + HeaderSize,
|
||||
support::little);
|
||||
support::endian::write(*HeaderStream, Header.Version, support::little);
|
||||
support::endian::write(*HeaderStream, Header.AddressSize, support::little);
|
||||
support::endian::write(*HeaderStream, Header.SegmentSelector,
|
||||
support::little);
|
||||
support::endian::write(*HeaderStream, Header.OffsetEntryCount,
|
||||
support::little);
|
||||
return HeaderBuffer;
|
||||
}
|
||||
|
||||
uint64_t DebugRangeListsSectionWriter::addRanges(
|
||||
const DebugAddressRangesVector &Ranges) {
|
||||
std::lock_guard<std::mutex> Lock(WriterMutex);
|
||||
|
||||
RangeEntries.push_back(CurrentOffset);
|
||||
for (const DebugAddressRange &Range : Ranges) {
|
||||
support::endian::write(*CUBodyStream,
|
||||
static_cast<uint8_t>(dwarf::DW_RLE_startx_length),
|
||||
support::little);
|
||||
const uint32_t Index = AddrWriter->getIndexFromAddress(Range.LowPC, CUID);
|
||||
encodeULEB128(Index, *CUBodyStream);
|
||||
encodeULEB128(Range.HighPC - Range.LowPC, *CUBodyStream);
|
||||
}
|
||||
support::endian::write(*CUBodyStream,
|
||||
static_cast<uint8_t>(dwarf::DW_RLE_end_of_list),
|
||||
support::little);
|
||||
CurrentOffset = CUBodyBuffer->size();
|
||||
return RangeEntries.size() - 1;
|
||||
}
|
||||
|
||||
void DebugRangeListsSectionWriter::finalizeSection() {
|
||||
std::unique_ptr<DebugBufferVector> CUArrayBuffer =
|
||||
std::make_unique<DebugBufferVector>();
|
||||
std::unique_ptr<raw_svector_ostream> CUArrayStream =
|
||||
std::make_unique<raw_svector_ostream>(*CUArrayBuffer);
|
||||
constexpr uint32_t SizeOfArrayEntry = 4;
|
||||
const uint32_t SizeOfArraySection = RangeEntries.size() * SizeOfArrayEntry;
|
||||
for (uint32_t Offset : RangeEntries)
|
||||
support::endian::write(*CUArrayStream, Offset + SizeOfArraySection,
|
||||
support::little);
|
||||
|
||||
std::unique_ptr<DebugBufferVector> Header = getDWARF5Header(
|
||||
{static_cast<uint32_t>(SizeOfArraySection + CUBodyBuffer.get()->size()),
|
||||
5, 8, 0, static_cast<uint32_t>(RangeEntries.size())});
|
||||
*RangesStream << *Header;
|
||||
*RangesStream << *CUArrayBuffer;
|
||||
*RangesStream << *CUBodyBuffer;
|
||||
SectionOffset = RangesBuffer->size();
|
||||
}
|
||||
|
||||
void DebugRangeListsSectionWriter::initSection(uint64_t CUId_) {
|
||||
CUBodyBuffer = std::make_unique<DebugBufferVector>();
|
||||
CUBodyStream = std::make_unique<raw_svector_ostream>(*CUBodyBuffer);
|
||||
RangeEntries.clear();
|
||||
CurrentOffset = 0;
|
||||
CUID = CUId_;
|
||||
}
|
||||
|
||||
void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
|
||||
DebugAddressRangesVector &&Ranges) {
|
||||
std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
|
||||
|
@ -220,13 +311,12 @@ void DebugAddrWriter::AddressForDWOCU::dump() {
|
|||
for (auto &Pair : SortedMap)
|
||||
dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
|
||||
}
|
||||
uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address,
|
||||
uint64_t DWOId) {
|
||||
uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, uint64_t CUID) {
|
||||
std::lock_guard<std::mutex> Lock(WriterMutex);
|
||||
if (!AddressMaps.count(DWOId))
|
||||
AddressMaps[DWOId] = AddressForDWOCU();
|
||||
if (!AddressMaps.count(CUID))
|
||||
AddressMaps[CUID] = AddressForDWOCU();
|
||||
|
||||
AddressForDWOCU &Map = AddressMaps[DWOId];
|
||||
AddressForDWOCU &Map = AddressMaps[CUID];
|
||||
auto Entry = Map.find(Address);
|
||||
if (Entry == Map.end()) {
|
||||
auto Index = Map.getNextIndex();
|
||||
|
@ -240,9 +330,9 @@ uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address,
|
|||
// IndexToAddrss. Case3) Address is in the map but Index is lower. Need to
|
||||
// update AddressToIndex and IndexToAddress
|
||||
void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index,
|
||||
uint64_t DWOId) {
|
||||
uint64_t CUID) {
|
||||
std::lock_guard<std::mutex> Lock(WriterMutex);
|
||||
AddressForDWOCU &Map = AddressMaps[DWOId];
|
||||
AddressForDWOCU &Map = AddressMaps[CUID];
|
||||
auto Entry = Map.find(Address);
|
||||
if (Entry != Map.end()) {
|
||||
if (Entry->second > Index)
|
||||
|
@ -265,6 +355,7 @@ AddressSectionBuffer DebugAddrWriter::finalize() {
|
|||
if (!DWOId)
|
||||
continue;
|
||||
auto AM = AddressMaps.find(*DWOId);
|
||||
assert(AM != AddressMaps.end() && "Address Map not found.");
|
||||
// Adding to map even if it did not contribute to .debug_addr.
|
||||
// The Skeleton CU will still have DW_AT_GNU_addr_base.
|
||||
DWOIdToOffsetMap[*DWOId] = Buffer.size();
|
||||
|
@ -306,9 +397,97 @@ AddressSectionBuffer DebugAddrWriter::finalize() {
|
|||
|
||||
return Buffer;
|
||||
}
|
||||
AddressSectionBuffer DebugAddrWriterDwarf5::finalize() {
|
||||
// Need to layout all sections within .debug_addr
|
||||
// Within each section sort Address by index.
|
||||
AddressSectionBuffer Buffer;
|
||||
raw_svector_ostream AddressStream(Buffer);
|
||||
const endianness Endian =
|
||||
BC->DwCtx->isLittleEndian() ? support::little : support::big;
|
||||
const DWARFSection &AddrSec = BC->DwCtx->getDWARFObj().getAddrSection();
|
||||
DWARFDataExtractor AddrData(BC->DwCtx->getDWARFObj(), AddrSec, Endian, 0);
|
||||
DWARFDebugAddrTable AddrTable;
|
||||
DIDumpOptions DumpOpts;
|
||||
constexpr uint32_t HeaderSize = 8;
|
||||
for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) {
|
||||
const uint64_t CUID = CU->getOffset();
|
||||
const uint8_t AddrSize = CU->getAddressByteSize();
|
||||
auto Iter = AddressMaps.find(CUID);
|
||||
// A case where CU has entry in .debug_addr, but we don't modify addresses
|
||||
// for it.
|
||||
if (Iter == AddressMaps.end()) {
|
||||
Iter = AddressMaps.insert({CUID, AddressForDWOCU()}).first;
|
||||
Optional<uint64_t> BaseOffset = CU->getAddrOffsetSectionBase();
|
||||
if (!BaseOffset)
|
||||
continue;
|
||||
// Address base offset is to the first entry.
|
||||
// The size of header is 8 bytes.
|
||||
uint64_t Offset = *BaseOffset - HeaderSize;
|
||||
if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddrSize,
|
||||
DumpOpts.WarningHandler)) {
|
||||
DumpOpts.RecoverableErrorHandler(std::move(Err));
|
||||
continue;
|
||||
}
|
||||
uint32_t Index = 0;
|
||||
for (uint64_t Addr : AddrTable.getAddressEntries())
|
||||
Iter->second.insert(Addr, Index++);
|
||||
}
|
||||
|
||||
uint64_t DebugAddrWriter::getOffset(uint64_t DWOId) {
|
||||
auto Iter = DWOIdToOffsetMap.find(DWOId);
|
||||
DWOIdToOffsetMap[CUID] = Buffer.size() + HeaderSize;
|
||||
|
||||
std::vector<IndexAddressPair> SortedMap(Iter->second.indexToAddressBegin(),
|
||||
Iter->second.indexToAdddessEnd());
|
||||
// Sorting address in increasing order of indices.
|
||||
std::sort(SortedMap.begin(), SortedMap.end(),
|
||||
[](const IndexAddressPair &A, const IndexAddressPair &B) {
|
||||
return A.first < B.first;
|
||||
});
|
||||
// Writing out Header
|
||||
const uint32_t Length = SortedMap.size() * AddrSize + 4;
|
||||
support::endian::write(AddressStream, Length, Endian);
|
||||
support::endian::write(AddressStream, static_cast<uint16_t>(5), Endian);
|
||||
support::endian::write(AddressStream, static_cast<uint8_t>(AddrSize),
|
||||
Endian);
|
||||
support::endian::write(AddressStream, static_cast<uint8_t>(0), Endian);
|
||||
|
||||
uint32_t Counter = 0;
|
||||
auto writeAddress = [&](uint64_t Address) -> void {
|
||||
++Counter;
|
||||
switch (AddrSize) {
|
||||
default:
|
||||
llvm_unreachable("Address Size is invalid.");
|
||||
break;
|
||||
case 4:
|
||||
support::endian::write(AddressStream, static_cast<uint32_t>(Address),
|
||||
Endian);
|
||||
break;
|
||||
case 8:
|
||||
support::endian::write(AddressStream, Address, Endian);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
for (const IndexAddressPair &Val : SortedMap) {
|
||||
while (Val.first > Counter)
|
||||
writeAddress(0);
|
||||
writeAddress(Val.second);
|
||||
}
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
uint64_t DebugAddrWriter::getOffset(DWARFUnit &Unit) {
|
||||
Optional<uint64_t> DWOId = Unit.getDWOId();
|
||||
assert(DWOId && "Can't get offset, not a skeleton CU.");
|
||||
auto Iter = DWOIdToOffsetMap.find(*DWOId);
|
||||
assert(Iter != DWOIdToOffsetMap.end() &&
|
||||
"Offset in to.debug_addr was not found for DWO ID.");
|
||||
return Iter->second;
|
||||
}
|
||||
|
||||
uint64_t DebugAddrWriterDwarf5::getOffset(DWARFUnit &Unit) {
|
||||
auto Iter = DWOIdToOffsetMap.find(Unit.getOffset());
|
||||
assert(Iter != DWOIdToOffsetMap.end() &&
|
||||
"Offset in to.debug_addr was not found for DWO ID.");
|
||||
return Iter->second;
|
||||
|
@ -319,7 +498,7 @@ DebugLocWriter::DebugLocWriter(BinaryContext *BC) {
|
|||
LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
|
||||
}
|
||||
|
||||
void DebugLocWriter::addList(uint64_t AttrOffset,
|
||||
void DebugLocWriter::addList(uint64_t AttrOffset, uint32_t LocListIndex,
|
||||
DebugLocationsVector &&LocList) {
|
||||
if (LocList.empty()) {
|
||||
EmptyAttrLists.push_back(AttrOffset);
|
||||
|
@ -345,9 +524,9 @@ void DebugLocWriter::addList(uint64_t AttrOffset,
|
|||
LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset});
|
||||
}
|
||||
|
||||
void DebugLoclistWriter::addList(uint64_t AttrOffset,
|
||||
void DebugLoclistWriter::addList(uint64_t AttrOffset, uint32_t LocListIndex,
|
||||
DebugLocationsVector &&LocList) {
|
||||
Patches.push_back({AttrOffset, std::move(LocList)});
|
||||
Patches.push_back({AttrOffset, LocListIndex, std::move(LocList)});
|
||||
}
|
||||
|
||||
std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() {
|
||||
|
@ -368,8 +547,95 @@ void DebugLocWriter::finalize(uint64_t SectionOffset,
|
|||
DebugLocWriter::EmptyListOffset);
|
||||
}
|
||||
|
||||
void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
||||
SimpleBinaryPatcher &DebugInfoPatcher) {
|
||||
static void writeEmptyListDwarf5(raw_svector_ostream &Stream) {
|
||||
support::endian::write(Stream, static_cast<uint32_t>(4), support::little);
|
||||
support::endian::write(Stream, static_cast<uint8_t>(dwarf::DW_LLE_start_end),
|
||||
support::little);
|
||||
|
||||
const char Zeroes[16] = {0};
|
||||
Stream << StringRef(Zeroes, 16);
|
||||
encodeULEB128(0, Stream);
|
||||
support::endian::write(
|
||||
Stream, static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), support::little);
|
||||
}
|
||||
|
||||
void DebugLoclistWriter::finalizeDWARF5(uint64_t SectionOffset,
|
||||
SimpleBinaryPatcher &DebugInfoPatcher) {
|
||||
|
||||
std::unique_ptr<DebugBufferVector> LocArrayBuffer =
|
||||
std::make_unique<DebugBufferVector>();
|
||||
std::unique_ptr<raw_svector_ostream> LocArrayStream =
|
||||
std::make_unique<raw_svector_ostream>(*LocArrayBuffer);
|
||||
std::unique_ptr<DebugBufferVector> LocBodyBuffer =
|
||||
std::make_unique<DebugBufferVector>();
|
||||
std::unique_ptr<raw_svector_ostream> LocBodyStream =
|
||||
std::make_unique<raw_svector_ostream>(*LocBodyBuffer);
|
||||
|
||||
const uint32_t SizeOfArraySection = Patches.size() * sizeof(uint32_t);
|
||||
std::sort(Patches.begin(), Patches.end(),
|
||||
[](const LocPatch &P1, const LocPatch &P2) -> bool {
|
||||
return P1.Index < P2.Index;
|
||||
});
|
||||
|
||||
if (LocListsBaseAttrOffset != InvalidLocListsBaseAttrOffset)
|
||||
DebugInfoPatcher.addLE32Patch(LocListsBaseAttrOffset,
|
||||
SectionOffset +
|
||||
getDWARF5RngListLocListHeaderSize());
|
||||
|
||||
uint32_t Index{0};
|
||||
for (LocPatch &Patch : Patches) {
|
||||
const uint32_t EntryOffset = LocBodyBuffer->size();
|
||||
if (Patch.LocList.empty()) {
|
||||
if (Patch.Index == DebugLoclistWriter::InvalidIndex)
|
||||
DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, EntryOffset);
|
||||
|
||||
writeEmptyListDwarf5(*LocBodyStream);
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(Patch.Index == DebugLoclistWriter::InvalidIndex ||
|
||||
Patch.Index == Index++ && "Gap in LocList Index Array.");
|
||||
|
||||
std::vector<uint64_t> OffsetsArray;
|
||||
for (const DebugLocationEntry &Entry : Patch.LocList) {
|
||||
support::endian::write(*LocBodyStream,
|
||||
static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
|
||||
support::little);
|
||||
const uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, CUID);
|
||||
encodeULEB128(Index, *LocBodyStream);
|
||||
encodeULEB128(Entry.HighPC - Entry.LowPC, *LocBodyStream);
|
||||
encodeULEB128(Entry.Expr.size(), *LocBodyStream);
|
||||
*LocBodyStream << StringRef(
|
||||
reinterpret_cast<const char *>(Entry.Expr.data()), Entry.Expr.size());
|
||||
}
|
||||
support::endian::write(*LocBodyStream,
|
||||
static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
|
||||
support::little);
|
||||
|
||||
// Write out IndexArray
|
||||
support::endian::write(
|
||||
*LocArrayStream,
|
||||
static_cast<uint32_t>(SizeOfArraySection + EntryOffset),
|
||||
support::little);
|
||||
// Don't need to patch Index since we are re-using them.
|
||||
if (Patch.Index == DebugLoclistWriter::InvalidIndex)
|
||||
DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, EntryOffset);
|
||||
clearList(Patch.LocList);
|
||||
}
|
||||
if (!Patches.empty()) {
|
||||
std::unique_ptr<DebugBufferVector> Header =
|
||||
getDWARF5Header({static_cast<uint32_t>(SizeOfArraySection +
|
||||
LocBodyBuffer.get()->size()),
|
||||
5, 8, 0, static_cast<uint32_t>(Patches.size())});
|
||||
*LocStream << *Header;
|
||||
*LocStream << *LocArrayBuffer;
|
||||
*LocStream << *LocBodyBuffer;
|
||||
}
|
||||
clearList(Patches);
|
||||
}
|
||||
|
||||
void DebugLoclistWriter::finalizeDWARFLegacy(
|
||||
uint64_t SectionOffset, SimpleBinaryPatcher &DebugInfoPatcher) {
|
||||
for (LocPatch &Patch : Patches) {
|
||||
if (Patch.LocList.empty()) {
|
||||
DebugInfoPatcher.addLE32Patch(Patch.AttrOffset,
|
||||
|
@ -381,7 +647,7 @@ void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
|||
support::endian::write(*LocStream,
|
||||
static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
|
||||
support::little);
|
||||
uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, DWOId);
|
||||
const uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, CUID);
|
||||
encodeULEB128(Index, *LocStream);
|
||||
|
||||
// TODO: Support DWARF5
|
||||
|
@ -403,6 +669,14 @@ void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
|||
clearList(Patches);
|
||||
}
|
||||
|
||||
void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
||||
SimpleBinaryPatcher &DebugInfoPatcher) {
|
||||
if (DwarfVersion < 5)
|
||||
finalizeDWARFLegacy(SectionOffset, DebugInfoPatcher);
|
||||
else
|
||||
finalizeDWARF5(SectionOffset, DebugInfoPatcher);
|
||||
}
|
||||
|
||||
DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
|
||||
|
||||
void DebugInfoBinaryPatcher::addUnitBaseOffsetLabel(uint64_t Offset) {
|
||||
|
@ -1154,7 +1428,7 @@ static inline void emitDwarfLineTable(
|
|||
MCOS->emitULEB128IntValue(Column);
|
||||
}
|
||||
if (Discriminator != LineEntry.getDiscriminator() &&
|
||||
MCOS->getContext().getDwarfVersion() >= 4) {
|
||||
MCOS->getContext().getDwarfVersion() >= 2) {
|
||||
Discriminator = LineEntry.getDiscriminator();
|
||||
unsigned Size = getULEB128Size(Discriminator);
|
||||
MCOS->emitInt8(dwarf::DW_LNS_extended_op);
|
||||
|
@ -1228,6 +1502,31 @@ void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
|
|||
MCOS->emitLabel(LineEndSym);
|
||||
}
|
||||
|
||||
// Helper function to parse .debug_line_str, and populate one we are using.
|
||||
// For functions that we do not modify we output them as raw data.
|
||||
// Re-constructing .debug_line_str so that offsets are correct for those
|
||||
// debut line tables.
|
||||
// Bonus is that when we output a final binary we can re-use .debug_line_str
|
||||
// section. So we don't have to do the SHF_ALLOC trick we did with
|
||||
// .debug_line.
|
||||
static void parseAndPopulateDebugLineStr(BinarySection &LineStrSection,
|
||||
MCDwarfLineStr &LineStr,
|
||||
BinaryContext &BC,
|
||||
MCStreamer &Streamer) {
|
||||
DataExtractor StrData(LineStrSection.getContents(),
|
||||
BC.DwCtx->isLittleEndian(), 0);
|
||||
uint64_t Offset = 0;
|
||||
while (StrData.isValidOffset(Offset)) {
|
||||
Error Err = Error::success();
|
||||
const char *CStr = StrData.getCStr(&Offset, &Err);
|
||||
if (Err) {
|
||||
errs() << "BOLT-ERROR: could not extract string from .debug_line_str";
|
||||
continue;
|
||||
}
|
||||
LineStr.emitRef(&Streamer, CStr);
|
||||
}
|
||||
}
|
||||
|
||||
void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
|
||||
MCAssembler &Assembler =
|
||||
static_cast<MCObjectStreamer *>(&Streamer)->getAssembler();
|
||||
|
@ -1240,19 +1539,39 @@ void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
|
|||
// in doing so create an unnecessary (if empty) section.
|
||||
if (LineTables.empty())
|
||||
return;
|
||||
|
||||
// In a v5 non-split line table, put the strings in a separate section.
|
||||
Optional<MCDwarfLineStr> LineStr(None);
|
||||
if (BC.Ctx->getDwarfVersion() >= 5)
|
||||
ErrorOr<BinarySection &> LineStrSection =
|
||||
BC.getUniqueSectionByName(".debug_line_str");
|
||||
// Some versions of GCC output DWARF5 .debug_info, but DWARF4 or lower
|
||||
// .debug_line
|
||||
if (LineStrSection) {
|
||||
LineStr = MCDwarfLineStr(*BC.Ctx);
|
||||
parseAndPopulateDebugLineStr(*LineStrSection, *LineStr, BC, Streamer);
|
||||
}
|
||||
|
||||
// Switch to the section where the table will be emitted into.
|
||||
Streamer.SwitchSection(BC.MOFI->getDwarfLineSection());
|
||||
|
||||
const uint16_t DwarfVersion = BC.Ctx->getDwarfVersion();
|
||||
// Handle the rest of the Compile Units.
|
||||
for (auto &CUIDTablePair : LineTables) {
|
||||
Streamer.getContext().setDwarfVersion(
|
||||
CUIDTablePair.second.getDwarfVersion());
|
||||
CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC);
|
||||
}
|
||||
|
||||
// Resetting DWARF version for rest of the flow.
|
||||
BC.Ctx->setDwarfVersion(DwarfVersion);
|
||||
|
||||
// Still need to write the section out for the ExecutionEngine, and temp in
|
||||
// memory object we are constructing.
|
||||
if (LineStr) {
|
||||
LineStr->emitSection(&Streamer);
|
||||
SmallString<0> Data = LineStr->getFinalizedData();
|
||||
BC.registerOrUpdateNoteSection(".debug_line_str", copyByteArray(Data.str()),
|
||||
Data.size());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace bolt
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/ThreadPool.h"
|
||||
#include "llvm/Support/ToolOutputFile.h"
|
||||
#include <algorithm>
|
||||
|
@ -72,6 +73,19 @@ static Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
|
|||
return None;
|
||||
return findAttributeInfo(DIE, AbbrevDecl, *Index);
|
||||
}
|
||||
|
||||
/// Finds attributes FormValue and Offset.
|
||||
///
|
||||
/// \param DIE die to look up in.
|
||||
/// \param Attrs finds the first attribute that matches and extracts it.
|
||||
/// \return an optional AttrInfo with DWARFFormValue and Offset.
|
||||
Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
|
||||
std::vector<dwarf::Attribute> Attrs) {
|
||||
for (dwarf::Attribute &Attr : Attrs)
|
||||
if (Optional<AttrInfo> Info = findAttributeInfo(DIE, Attr))
|
||||
return Info;
|
||||
return None;
|
||||
}
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
||||
|
||||
|
@ -158,24 +172,40 @@ void DWARFRewriter::updateDebugInfo() {
|
|||
static_cast<DebugInfoBinaryPatcher *>(DebugInfo->getPatcher());
|
||||
|
||||
ARangesSectionWriter = std::make_unique<DebugARangesSectionWriter>();
|
||||
RangesSectionWriter = std::make_unique<DebugRangesSectionWriter>();
|
||||
StrWriter = std::make_unique<DebugStrWriter>(&BC);
|
||||
AbbrevWriter = std::make_unique<DebugAbbrevWriter>(*BC.DwCtx);
|
||||
|
||||
AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
|
||||
DebugLoclistWriter::setAddressWriter(AddrWriter.get());
|
||||
|
||||
uint64_t NumCUs = BC.DwCtx->getNumCompileUnits();
|
||||
if ((opts::NoThreads || opts::DeterministicDebugInfo) &&
|
||||
BC.getNumDWOCUs() == 0) {
|
||||
// Use single entry for efficiency when running single-threaded
|
||||
NumCUs = 1;
|
||||
if (BC.isDWARF5Used()) {
|
||||
// Disabling none deterministic mode for dwarf5, to keep implementation
|
||||
// simpler.
|
||||
opts::DeterministicDebugInfo = true;
|
||||
AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
|
||||
RangesSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
|
||||
DebugRangeListsSectionWriter::setAddressWriter(AddrWriter.get());
|
||||
} else {
|
||||
AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
|
||||
RangesSectionWriter = std::make_unique<DebugRangesSectionWriter>();
|
||||
}
|
||||
|
||||
LocListWritersByCU.reserve(NumCUs);
|
||||
DebugLoclistWriter::setAddressWriter(AddrWriter.get());
|
||||
|
||||
for (size_t CUIndex = 0; CUIndex < NumCUs; ++CUIndex)
|
||||
LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>(&BC);
|
||||
size_t CUIndex = 0;
|
||||
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
|
||||
if (CU->getVersion() >= 5) {
|
||||
uint32_t AttrInfoOffset =
|
||||
DebugLoclistWriter::InvalidLocListsBaseAttrOffset;
|
||||
if (Optional<AttrInfo> AttrInfoVal =
|
||||
findAttributeInfo(CU->getUnitDIE(), dwarf::DW_AT_loclists_base))
|
||||
AttrInfoOffset = AttrInfoVal->Offset;
|
||||
|
||||
LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
|
||||
&BC, CU->isDWOUnit() ? *CU->getDWOId() : CU->getOffset(),
|
||||
AttrInfoOffset, 5, false);
|
||||
} else {
|
||||
LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>(&BC);
|
||||
}
|
||||
++CUIndex;
|
||||
}
|
||||
|
||||
// Unordered maps to handle name collision if output DWO directory is
|
||||
// specified.
|
||||
|
@ -185,8 +215,8 @@ void DWARFRewriter::updateDebugInfo() {
|
|||
|
||||
auto updateDWONameCompDir = [&](DWARFUnit &Unit) -> void {
|
||||
const DWARFDie &DIE = Unit.getUnitDIE();
|
||||
Optional<AttrInfo> AttrInfoVal =
|
||||
findAttributeInfo(DIE, dwarf::DW_AT_GNU_dwo_name);
|
||||
Optional<AttrInfo> AttrInfoVal = findAttributeInfo(
|
||||
DIE, {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name});
|
||||
(void)AttrInfoVal;
|
||||
assert(AttrInfoVal && "Skeleton CU doesn't have dwo_name.");
|
||||
|
||||
|
@ -234,8 +264,8 @@ void DWARFRewriter::updateDebugInfo() {
|
|||
std::lock_guard<std::mutex> Lock(AccessMutex);
|
||||
DebugLocWriter =
|
||||
LocListWritersByCU
|
||||
.insert(
|
||||
{*DWOId, std::make_unique<DebugLoclistWriter>(&BC, *DWOId)})
|
||||
.insert({*DWOId, std::make_unique<DebugLoclistWriter>(
|
||||
&BC, *DWOId, 0, Unit->getVersion(), true)})
|
||||
.first->second.get();
|
||||
}
|
||||
DebugInfoBinaryPatcher *DwoDebugInfoPatcher =
|
||||
|
@ -251,7 +281,7 @@ void DWARFRewriter::updateDebugInfo() {
|
|||
DebugAbbrevWriter *DWOAbbrevWriter =
|
||||
createBinaryDWOAbbrevWriter((*SplitCU)->getContext(), *DWOId);
|
||||
updateUnitDebugInfo(*(*SplitCU), *DwoDebugInfoPatcher, *DWOAbbrevWriter,
|
||||
*DebugLocWriter);
|
||||
*DebugLocWriter, *RangesSectionWriter);
|
||||
DwoDebugInfoPatcher->clearDestinationLabels();
|
||||
if (!DwoDebugInfoPatcher->getWasRangBasedUsed())
|
||||
RangesBase = None;
|
||||
|
@ -261,18 +291,33 @@ void DWARFRewriter::updateDebugInfo() {
|
|||
std::lock_guard<std::mutex> Lock(AccessMutex);
|
||||
DebugLocWriter = LocListWritersByCU[CUIndex].get();
|
||||
}
|
||||
if (Unit->getVersion() >= 5) {
|
||||
RangesBase = RangesSectionWriter->getSectionOffset() +
|
||||
getDWARF5RngListLocListHeaderSize();
|
||||
reinterpret_cast<DebugRangeListsSectionWriter *>(
|
||||
RangesSectionWriter.get())
|
||||
->initSection(Unit->getOffset());
|
||||
}
|
||||
|
||||
DebugInfoPatcher->addUnitBaseOffsetLabel(Unit->getOffset());
|
||||
updateUnitDebugInfo(*Unit, *DebugInfoPatcher, *AbbrevWriter,
|
||||
*DebugLocWriter, RangesBase);
|
||||
*DebugLocWriter, *RangesSectionWriter, RangesBase);
|
||||
if (Unit->getVersion() >= 5)
|
||||
reinterpret_cast<DebugRangeListsSectionWriter *>(
|
||||
RangesSectionWriter.get())
|
||||
->finalizeSection();
|
||||
};
|
||||
|
||||
CUIndex = 0;
|
||||
if (opts::NoThreads || opts::DeterministicDebugInfo) {
|
||||
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units())
|
||||
processUnitDIE(0, CU.get());
|
||||
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
|
||||
processUnitDIE(CUIndex, CU.get());
|
||||
if (CU->getVersion() >= 5)
|
||||
++CUIndex;
|
||||
}
|
||||
} else {
|
||||
// Update unit debug info in parallel
|
||||
ThreadPool &ThreadPool = ParallelUtilities::getThreadPool();
|
||||
size_t CUIndex = 0;
|
||||
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
|
||||
ThreadPool.async(processUnitDIE, CUIndex, CU.get());
|
||||
CUIndex++;
|
||||
|
@ -291,9 +336,18 @@ void DWARFRewriter::updateDebugInfo() {
|
|||
updateGdbIndexSection(OffsetMap);
|
||||
}
|
||||
|
||||
static uint64_t getCUId(DWARFUnit &Unit) {
|
||||
if (Unit.getVersion() >= 5)
|
||||
return Unit.getOffset();
|
||||
|
||||
assert(Unit.isDWOUnit() && "Unit is not Skeleton CU.");
|
||||
return *Unit.getDWOId();
|
||||
}
|
||||
|
||||
void DWARFRewriter::updateUnitDebugInfo(
|
||||
DWARFUnit &Unit, DebugInfoBinaryPatcher &DebugInfoPatcher,
|
||||
DebugAbbrevWriter &AbbrevWriter, DebugLocWriter &DebugLocWriter,
|
||||
DebugRangesSectionWriter &RangesSectionWriter,
|
||||
Optional<uint64_t> RangesBase) {
|
||||
// Cache debug ranges so that the offset for identical ranges could be reused.
|
||||
std::map<DebugAddressRangesVector, uint64_t> CachedRanges;
|
||||
|
@ -332,7 +386,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
DebugAddressRangesVector OutputRanges =
|
||||
BC.translateModuleAddressRanges(ModuleRanges);
|
||||
const uint64_t RangesSectionOffset =
|
||||
RangesSectionWriter->addRanges(OutputRanges);
|
||||
RangesSectionWriter.addRanges(OutputRanges);
|
||||
if (!Unit.isDWOUnit())
|
||||
ARangesSectionWriter->addCURanges(Unit.getOffset(),
|
||||
std::move(OutputRanges));
|
||||
|
@ -371,7 +425,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
FunctionRanges.push_back({0, 0});
|
||||
|
||||
updateDWARFObjectAddressRanges(
|
||||
DIE, RangesSectionWriter->addRanges(FunctionRanges), DebugInfoPatcher,
|
||||
DIE, RangesSectionWriter.addRanges(FunctionRanges), DebugInfoPatcher,
|
||||
AbbrevWriter);
|
||||
|
||||
break;
|
||||
|
@ -380,8 +434,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
case dwarf::DW_TAG_inlined_subroutine:
|
||||
case dwarf::DW_TAG_try_block:
|
||||
case dwarf::DW_TAG_catch_block: {
|
||||
uint64_t RangesSectionOffset =
|
||||
RangesSectionWriter->getEmptyRangesOffset();
|
||||
uint64_t RangesSectionOffset = RangesSectionWriter.getEmptyRangesOffset();
|
||||
Expected<DWARFAddressRangesVector> RangesOrError = DIE.getAddressRanges();
|
||||
const BinaryFunction *Function =
|
||||
RangesOrError && !RangesOrError->empty()
|
||||
|
@ -396,7 +449,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
<< Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
|
||||
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
||||
});
|
||||
RangesSectionOffset = RangesSectionWriter->addRanges(
|
||||
RangesSectionOffset = RangesSectionWriter.addRanges(
|
||||
std::move(OutputRanges), CachedRanges);
|
||||
} else if (!RangesOrError) {
|
||||
consumeError(RangesOrError.takeError());
|
||||
|
@ -426,6 +479,12 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
if (SectionAddress)
|
||||
BaseAddress = SectionAddress->Address;
|
||||
|
||||
if (Unit.getVersion() >= 5) {
|
||||
Optional<uint64_t> LocOffset = Unit.getLoclistOffset(Offset);
|
||||
assert(LocOffset && "Location Offset is invalid.");
|
||||
Offset = *LocOffset;
|
||||
}
|
||||
|
||||
Error E = Unit.getLocationTable().visitLocationList(
|
||||
&Offset, [&](const DWARFLocationEntry &Entry) {
|
||||
switch (Entry.Kind) {
|
||||
|
@ -433,11 +492,12 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
llvm_unreachable("Unsupported DWARFLocationEntry Kind.");
|
||||
case dwarf::DW_LLE_end_of_list:
|
||||
return false;
|
||||
case dwarf::DW_LLE_base_address:
|
||||
case dwarf::DW_LLE_base_address: {
|
||||
assert(Entry.SectionIndex == SectionedAddress::UndefSection &&
|
||||
"absolute address expected");
|
||||
BaseAddress = Entry.Value0;
|
||||
break;
|
||||
}
|
||||
case dwarf::DW_LLE_offset_pair:
|
||||
assert(
|
||||
(Entry.SectionIndex == SectionedAddress::UndefSection &&
|
||||
|
@ -447,9 +507,18 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
BaseAddress + Entry.Value0, BaseAddress + Entry.Value1,
|
||||
Entry.Loc});
|
||||
break;
|
||||
case dwarf::DW_LLE_startx_length:
|
||||
assert(Unit.isDWOUnit() &&
|
||||
"None DWO Unit with DW_LLE_startx_length encoding.");
|
||||
case dwarf::DW_RLE_start_length:
|
||||
InputLL.emplace_back(DebugLocationEntry{
|
||||
Entry.Value0, Entry.Value0 + Entry.Value1, Entry.Loc});
|
||||
break;
|
||||
case dwarf::DW_LLE_base_addressx: {
|
||||
Optional<object::SectionedAddress> EntryAddress =
|
||||
Unit.getAddrOffsetSectionItem(Entry.Value0);
|
||||
assert(EntryAddress && "base Address not found.");
|
||||
BaseAddress = EntryAddress->Address;
|
||||
break;
|
||||
}
|
||||
case dwarf::DW_LLE_startx_length: {
|
||||
Optional<object::SectionedAddress> EntryAddress =
|
||||
Unit.getAddrOffsetSectionItem(Entry.Value0);
|
||||
assert(EntryAddress && "Address does not exist.");
|
||||
|
@ -458,6 +527,18 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
EntryAddress->Address + Entry.Value1, Entry.Loc});
|
||||
break;
|
||||
}
|
||||
case dwarf::DW_LLE_startx_endx: {
|
||||
Optional<object::SectionedAddress> StartAddress =
|
||||
Unit.getAddrOffsetSectionItem(Entry.Value0);
|
||||
assert(StartAddress && "Start Address does not exist.");
|
||||
Optional<object::SectionedAddress> EndAddress =
|
||||
Unit.getAddrOffsetSectionItem(Entry.Value1);
|
||||
assert(EndAddress && "Start Address does not exist.");
|
||||
InputLL.emplace_back(DebugLocationEntry{
|
||||
StartAddress->Address, EndAddress->Address, Entry.Loc});
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -469,42 +550,90 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
||||
} else {
|
||||
const uint64_t Address = InputLL.front().LowPC;
|
||||
DebugLocationsVector OutputLL;
|
||||
if (const BinaryFunction *Function =
|
||||
BC.getBinaryFunctionContainingAddress(Address)) {
|
||||
DebugLocationsVector OutputLL =
|
||||
Function->translateInputToOutputLocationList(InputLL);
|
||||
OutputLL = Function->translateInputToOutputLocationList(InputLL);
|
||||
LLVM_DEBUG(if (OutputLL.empty()) {
|
||||
dbgs() << "BOLT-DEBUG: location list translated to an empty "
|
||||
"one at 0x"
|
||||
<< Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
|
||||
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
||||
});
|
||||
DebugLocWriter.addList(AttrOffset, std::move(OutputLL));
|
||||
} else {
|
||||
// It's possible for a subprogram to be removed and to have
|
||||
// address of 0. Adding this entry to output to preserve debug
|
||||
// information.
|
||||
OutputLL = InputLL;
|
||||
}
|
||||
uint32_t LocListIndex = 0;
|
||||
dwarf::Form Form = Value.getForm();
|
||||
if (Form == dwarf::DW_FORM_sec_offset ||
|
||||
Form == dwarf::DW_FORM_data4) {
|
||||
// For DWARF5 we can access location list entry either using
|
||||
// index, or offset. If it's offset, then it's from begnning of
|
||||
// the file. This implementation was before we could add entries
|
||||
// to the DIE. For DWARF4 this is no-op.
|
||||
// TODO: For DWARF5 convert all the offset based entries to index
|
||||
// based, and insert loclist_base if necessary.
|
||||
LocListIndex = DebugLoclistWriter::InvalidIndex;
|
||||
} else if (Form == dwarf::DW_FORM_loclistx) {
|
||||
LocListIndex = Value.getRawUValue();
|
||||
} else {
|
||||
llvm_unreachable("Unsupported LocList access Form.");
|
||||
}
|
||||
DebugLocWriter.addList(AttrOffset, LocListIndex,
|
||||
std::move(OutputLL));
|
||||
}
|
||||
} else {
|
||||
assert((Value.isFormClass(DWARFFormValue::FC_Exprloc) ||
|
||||
Value.isFormClass(DWARFFormValue::FC_Block)) &&
|
||||
"unexpected DW_AT_location form");
|
||||
if (Unit.isDWOUnit()) {
|
||||
if (Unit.isDWOUnit() || Unit.getVersion() >= 5) {
|
||||
ArrayRef<uint8_t> Expr = *Value.getAsBlock();
|
||||
DataExtractor Data(
|
||||
StringRef((const char *)Expr.data(), Expr.size()),
|
||||
Unit.getContext().isLittleEndian(), 0);
|
||||
DWARFExpression LocExpr(Data, Unit.getAddressByteSize(),
|
||||
Unit.getFormParams().Format);
|
||||
uint32_t PrevOffset = 0;
|
||||
constexpr uint32_t SizeOfOpcode = 1;
|
||||
constexpr uint32_t SizeOfForm = 1;
|
||||
for (auto &Expr : LocExpr) {
|
||||
if (Expr.getCode() != dwarf::DW_OP_GNU_addr_index)
|
||||
if (!(Expr.getCode() == dwarf::DW_OP_GNU_addr_index ||
|
||||
Expr.getCode() == dwarf::DW_OP_addrx))
|
||||
continue;
|
||||
uint64_t Index = Expr.getRawOperand(0);
|
||||
|
||||
const uint64_t Index = Expr.getRawOperand(0);
|
||||
Optional<object::SectionedAddress> EntryAddress =
|
||||
Unit.getAddrOffsetSectionItem(Index);
|
||||
assert(EntryAddress && "Address is not found.");
|
||||
assert(Index <= std::numeric_limits<uint32_t>::max() &&
|
||||
"Invalid Operand Index.");
|
||||
AddrWriter->addIndexAddress(EntryAddress->Address,
|
||||
static_cast<uint32_t>(Index),
|
||||
*Unit.getDWOId());
|
||||
if (Expr.getCode() == dwarf::DW_OP_addrx) {
|
||||
const uint32_t EncodingSize =
|
||||
Expr.getOperandEndOffset(0) - PrevOffset - SizeOfOpcode;
|
||||
const uint32_t Index = AddrWriter->getIndexFromAddress(
|
||||
EntryAddress->Address, getCUId(Unit));
|
||||
// Encoding new size.
|
||||
SmallString<8> Tmp;
|
||||
raw_svector_ostream OSE(Tmp);
|
||||
encodeULEB128(Index, OSE);
|
||||
DebugInfoPatcher.addUDataPatch(AttrOffset, Tmp.size() + 1, 1);
|
||||
DebugInfoPatcher.addUDataPatch(AttrOffset + PrevOffset +
|
||||
SizeOfOpcode + SizeOfForm,
|
||||
Index, EncodingSize);
|
||||
} else {
|
||||
// TODO: Re-do this as DWARF5.
|
||||
AddrWriter->addIndexAddress(EntryAddress->Address,
|
||||
static_cast<uint32_t>(Index),
|
||||
getCUId(Unit));
|
||||
}
|
||||
if (Expr.getDescription().Op[1] ==
|
||||
DWARFExpression::Operation::SizeNA)
|
||||
PrevOffset = Expr.getOperandEndOffset(0);
|
||||
else
|
||||
PrevOffset = Expr.getOperandEndOffset(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -531,15 +660,20 @@ void DWARFRewriter::updateUnitDebugInfo(
|
|||
"DW_FORM_LLVM_addrx_offset is not supported");
|
||||
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
||||
if (Form == dwarf::DW_FORM_GNU_addr_index) {
|
||||
assert(Unit.isDWOUnit() &&
|
||||
"DW_FORM_GNU_addr_index in Non DWO unit.");
|
||||
uint64_t Index = Value.getRawUValue();
|
||||
const uint64_t Index = Value.getRawUValue();
|
||||
// If there is no new address, storing old address.
|
||||
// Re-using Index to make implementation easier.
|
||||
// DW_FORM_GNU_addr_index is variable lenght encoding so we either
|
||||
// have to create indices of same sizes, or use same index.
|
||||
// DW_FORM_GNU_addr_index is variable lenght encoding
|
||||
// so we either have to create indices of same sizes, or use same
|
||||
// index.
|
||||
// TODO: We can now re-write .debug_info. This can be simplified to
|
||||
// just getting a new index and creating a patch.
|
||||
AddrWriter->addIndexAddress(NewAddress ? NewAddress : Address,
|
||||
Index, *Unit.getDWOId());
|
||||
Index, getCUId(Unit));
|
||||
} else if (Form == dwarf::DW_FORM_addrx) {
|
||||
const uint32_t Index = AddrWriter->getIndexFromAddress(
|
||||
NewAddress ? NewAddress : Address, getCUId(Unit));
|
||||
DebugInfoPatcher.addUDataPatch(AttrOffset, Index, AttrVal->Size);
|
||||
} else {
|
||||
DebugInfoPatcher.addLE64Patch(AttrOffset, NewAddress);
|
||||
}
|
||||
|
@ -613,6 +747,9 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
|
|||
// are needed for ranges base.
|
||||
Optional<AttrInfo> RangesBaseAttrInfo =
|
||||
findAttributeInfo(DIE, dwarf::DW_AT_GNU_ranges_base);
|
||||
if (!RangesBaseAttrInfo)
|
||||
RangesBaseAttrInfo = findAttributeInfo(DIE, dwarf::DW_AT_rnglists_base);
|
||||
|
||||
if (RangesBaseAttrInfo) {
|
||||
DebugInfoPatcher.addLE32Patch(RangesBaseAttrInfo->Offset,
|
||||
static_cast<uint32_t>(*RangesBase),
|
||||
|
@ -623,15 +760,28 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
|
|||
|
||||
Optional<AttrInfo> LowPCAttrInfo =
|
||||
findAttributeInfo(DIE, dwarf::DW_AT_low_pc);
|
||||
if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_ranges)) {
|
||||
if (Optional<AttrInfo> AttrVal =
|
||||
findAttributeInfo(DIE, dwarf::DW_AT_ranges)) {
|
||||
// Case 1: The object was already non-contiguous and had DW_AT_ranges.
|
||||
// In this case we simply need to update the value of DW_AT_ranges
|
||||
// and introduce DW_AT_GNU_ranges_base if required.
|
||||
Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, dwarf::DW_AT_ranges);
|
||||
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
||||
DebugInfoPatcher.addLE32Patch(
|
||||
AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(),
|
||||
AttrVal->Size);
|
||||
// For DWARF5 converting all of DW_AT_ranges into DW_FORM_rnglistx
|
||||
bool Converted = false;
|
||||
if (DIE.getDwarfUnit()->getVersion() >= 5 &&
|
||||
AttrVal->V.getForm() == dwarf::DW_FORM_sec_offset) {
|
||||
AbbrevWriter.addAttributePatch(*DIE.getDwarfUnit(), AbbreviationDecl,
|
||||
dwarf::DW_AT_ranges, dwarf::DW_AT_ranges,
|
||||
dwarf::DW_FORM_rnglistx);
|
||||
Converted = true;
|
||||
}
|
||||
if (Converted || AttrVal->V.getForm() == dwarf::DW_FORM_rnglistx)
|
||||
DebugInfoPatcher.addUDataPatch(AttrVal->Offset, DebugRangesOffset,
|
||||
AttrVal->Size);
|
||||
else
|
||||
DebugInfoPatcher.addLE32Patch(
|
||||
AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(),
|
||||
AttrVal->Size);
|
||||
|
||||
if (!RangesBase) {
|
||||
if (LowPCAttrInfo &&
|
||||
|
@ -766,15 +916,27 @@ DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
|||
|
||||
std::unique_ptr<DebugBufferVector> RangesSectionContents =
|
||||
RangesSectionWriter->finalize();
|
||||
BC.registerOrUpdateNoteSection(".debug_ranges",
|
||||
copyByteArray(*RangesSectionContents),
|
||||
RangesSectionContents->size());
|
||||
BC.registerOrUpdateNoteSection(
|
||||
llvm::isa<DebugRangeListsSectionWriter>(*RangesSectionWriter)
|
||||
? ".debug_rnglists"
|
||||
: ".debug_ranges",
|
||||
copyByteArray(*RangesSectionContents), RangesSectionContents->size());
|
||||
|
||||
std::unique_ptr<DebugBufferVector> LocationListSectionContents =
|
||||
makeFinalLocListsSection(DebugInfoPatcher);
|
||||
BC.registerOrUpdateNoteSection(".debug_loc",
|
||||
copyByteArray(*LocationListSectionContents),
|
||||
LocationListSectionContents->size());
|
||||
if (BC.isDWARF5Used()) {
|
||||
std::unique_ptr<DebugBufferVector> LocationListSectionContents =
|
||||
makeFinalLocListsSection(DebugInfoPatcher, DWARFVersion::DWARF5);
|
||||
BC.registerOrUpdateNoteSection(".debug_loclists",
|
||||
copyByteArray(*LocationListSectionContents),
|
||||
LocationListSectionContents->size());
|
||||
}
|
||||
|
||||
if (BC.isDWARFLegacyUsed()) {
|
||||
std::unique_ptr<DebugBufferVector> LocationListSectionContents =
|
||||
makeFinalLocListsSection(DebugInfoPatcher, DWARFVersion::DWARFLegacy);
|
||||
BC.registerOrUpdateNoteSection(".debug_loc",
|
||||
copyByteArray(*LocationListSectionContents),
|
||||
LocationListSectionContents->size());
|
||||
}
|
||||
|
||||
// AddrWriter should be finalized after debug_loc since more addresses can be
|
||||
// added there.
|
||||
|
@ -785,12 +947,39 @@ DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
|||
AddressSectionContents.size());
|
||||
for (auto &CU : BC.DwCtx->compile_units()) {
|
||||
DWARFDie DIE = CU->getUnitDIE();
|
||||
if (Optional<AttrInfo> AttrVal =
|
||||
findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base)) {
|
||||
uint64_t Offset = AddrWriter->getOffset(*CU->getDWOId());
|
||||
DebugInfoPatcher.addLE32Patch(
|
||||
AttrVal->Offset, static_cast<int32_t>(Offset), AttrVal->Size);
|
||||
uint64_t Offset = 0;
|
||||
uint64_t AttrOffset = 0;
|
||||
uint32_t Size = 0;
|
||||
Optional<AttrInfo> AttrValGnu =
|
||||
findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base);
|
||||
Optional<AttrInfo> AttrVal =
|
||||
findAttributeInfo(DIE, dwarf::DW_AT_addr_base);
|
||||
Offset = AddrWriter->getOffset(*CU);
|
||||
|
||||
if (AttrValGnu) {
|
||||
AttrOffset = AttrValGnu->Offset;
|
||||
Size = AttrValGnu->Size;
|
||||
}
|
||||
|
||||
if (AttrVal) {
|
||||
AttrOffset = AttrVal->Offset;
|
||||
Size = AttrVal->Size;
|
||||
}
|
||||
|
||||
if (AttrValGnu || AttrVal) {
|
||||
DebugInfoPatcher.addLE32Patch(AttrOffset, static_cast<int32_t>(Offset),
|
||||
Size);
|
||||
} else if (CU->getVersion() >= 5) {
|
||||
// A case where we were not using .debug_addr section, but after update
|
||||
// now using it.
|
||||
const DWARFAbbreviationDeclaration *Abbrev =
|
||||
DIE.getAbbreviationDeclarationPtr();
|
||||
AbbrevWriter->addAttribute(*CU, Abbrev, dwarf::DW_AT_addr_base,
|
||||
dwarf::DW_FORM_sec_offset);
|
||||
DebugInfoPatcher.insertNewEntry(DIE, static_cast<int32_t>(Offset));
|
||||
} else
|
||||
llvm_unreachable(
|
||||
"DWO CU uses .debug_address, but DW_AT_GNU_addr_base is missing.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,13 +997,22 @@ DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
|||
if (Unit->getAbbreviationsOffset() == NewAbbrevOffset)
|
||||
continue;
|
||||
|
||||
// DWARFv4
|
||||
// DWARFv4 or earlier
|
||||
// unit_length - 4 bytes
|
||||
// version - 2 bytes
|
||||
// So + 6 to patch debug_abbrev_offset
|
||||
constexpr uint64_t AbbrevFieldOffset = 6;
|
||||
if (!Unit->isTypeUnit()) {
|
||||
DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevFieldOffset,
|
||||
constexpr uint64_t AbbrevFieldOffsetLegacy = 6;
|
||||
// DWARFv5
|
||||
// unit_length - 4 bytes
|
||||
// version - 2 bytes
|
||||
// unit_type - 1 byte
|
||||
// address_size - 1 byte
|
||||
// So + 8 to patch debug_abbrev_offset
|
||||
constexpr uint64_t AbbrevFieldOffsetV5 = 8;
|
||||
uint64_t AbbrevOffset =
|
||||
Unit->getVersion() >= 5 ? AbbrevFieldOffsetV5 : AbbrevFieldOffsetLegacy;
|
||||
if (!Unit->isTypeUnit() || Unit->getVersion() >= 5) {
|
||||
DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevOffset,
|
||||
static_cast<uint32_t>(NewAbbrevOffset));
|
||||
continue;
|
||||
}
|
||||
|
@ -826,7 +1024,7 @@ DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
|||
DebugTypesPatcher =
|
||||
static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher());
|
||||
}
|
||||
DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevFieldOffset,
|
||||
DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevOffset,
|
||||
static_cast<uint32_t>(NewAbbrevOffset));
|
||||
}
|
||||
|
||||
|
@ -1033,7 +1231,7 @@ void DWARFRewriter::writeDWP(
|
|||
if (!DWOCU)
|
||||
continue;
|
||||
|
||||
assert(CU->getVersion() == 4 && "For DWP output only DWARF4 is supported");
|
||||
assert(CU->getVersion() <= 4 && "For DWP output only DWARF4 is supported");
|
||||
UnitIndexEntry CurEntry = {};
|
||||
CurEntry.DWOName =
|
||||
dwarf::toString(CU->getUnitDIE().find(
|
||||
|
@ -1292,25 +1490,40 @@ void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap) {
|
|||
}
|
||||
|
||||
std::unique_ptr<DebugBufferVector>
|
||||
DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher) {
|
||||
DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher,
|
||||
DWARFVersion Version) {
|
||||
auto LocBuffer = std::make_unique<DebugBufferVector>();
|
||||
auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
|
||||
auto Writer =
|
||||
std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream));
|
||||
|
||||
uint64_t SectionOffset = 0;
|
||||
|
||||
// Add an empty list as the first entry;
|
||||
const char Zeroes[16] = {0};
|
||||
*LocStream << StringRef(Zeroes, 16);
|
||||
SectionOffset += 2 * 8;
|
||||
if (LocListWritersByCU.empty() ||
|
||||
LocListWritersByCU.begin()->second.get()->getDwarfVersion() < 5) {
|
||||
// Should be fine for both DWARF4 and DWARF5?
|
||||
const char Zeroes[16] = {0};
|
||||
*LocStream << StringRef(Zeroes, 16);
|
||||
SectionOffset += 2 * 8;
|
||||
}
|
||||
|
||||
for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc :
|
||||
LocListWritersByCU) {
|
||||
DebugLocWriter *LocWriter = Loc.second.get();
|
||||
if (auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter)) {
|
||||
auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter);
|
||||
|
||||
if (Version == DWARFVersion::DWARF5 &&
|
||||
(!LocListWriter || LocListWriter->getDwarfVersion() <= 4))
|
||||
continue;
|
||||
|
||||
if (Version == DWARFVersion::DWARFLegacy &&
|
||||
(LocListWriter && LocListWriter->getDwarfVersion() >= 5))
|
||||
continue;
|
||||
if (LocListWriter && (LocListWriter->getDwarfVersion() <= 4 ||
|
||||
(LocListWriter->getDwarfVersion() >= 5 &&
|
||||
LocListWriter->isSplitDwarf()))) {
|
||||
SimpleBinaryPatcher *Patcher =
|
||||
getBinaryDWODebugInfoPatcher(LocListWriter->getDWOID());
|
||||
getBinaryDWODebugInfoPatcher(LocListWriter->getCUID());
|
||||
LocListWriter->finalize(0, *Patcher);
|
||||
continue;
|
||||
}
|
||||
|
@ -1336,7 +1549,8 @@ void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
|
|||
dwarf::Form HighPCForm = HighPCVal->V.getForm();
|
||||
|
||||
if (LowPCForm != dwarf::DW_FORM_addr &&
|
||||
LowPCForm != dwarf::DW_FORM_GNU_addr_index) {
|
||||
LowPCForm != dwarf::DW_FORM_GNU_addr_index &&
|
||||
LowPCForm != dwarf::DW_FORM_addrx) {
|
||||
errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE "
|
||||
<< "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n";
|
||||
return;
|
||||
|
@ -1351,7 +1565,8 @@ void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
|
|||
return;
|
||||
}
|
||||
if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) &&
|
||||
LowPCForm != dwarf::DW_FORM_GNU_addr_index) {
|
||||
LowPCForm != dwarf::DW_FORM_GNU_addr_index &&
|
||||
LowPCForm != dwarf::DW_FORM_addrx) {
|
||||
errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. "
|
||||
<< "Cannot update DIE at offset 0x"
|
||||
<< Twine::utohexstr(DIE.getOffset()) << '\n';
|
||||
|
@ -1364,24 +1579,27 @@ void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
|
|||
void DWARFRewriter::convertToRangesPatchAbbrev(
|
||||
const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev,
|
||||
DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) {
|
||||
auto getAttributeForm = [&Abbrev](const dwarf::Attribute Attr) {
|
||||
Optional<uint32_t> Index = Abbrev->findAttributeIndex(Attr);
|
||||
assert(Index && "attribute not found");
|
||||
return Abbrev->getFormByIndex(*Index);
|
||||
};
|
||||
dwarf::Form LowPCForm = getAttributeForm(dwarf::DW_AT_low_pc);
|
||||
|
||||
// DW_FORM_GNU_addr_index is already variable encoding so nothing to do
|
||||
// there.
|
||||
if (RangesBase) {
|
||||
assert(LowPCForm != dwarf::DW_FORM_GNU_addr_index);
|
||||
AbbrevWriter.addAttribute(Unit, Abbrev, dwarf::DW_AT_GNU_ranges_base,
|
||||
dwarf::DW_FORM_sec_offset);
|
||||
dwarf::Attribute RangeBaseAttribute = dwarf::DW_AT_GNU_ranges_base;
|
||||
dwarf::Form RangesForm = dwarf::DW_FORM_sec_offset;
|
||||
|
||||
if (Unit.getVersion() >= 5) {
|
||||
RangeBaseAttribute = dwarf::DW_AT_rnglists_base;
|
||||
RangesForm = dwarf::DW_FORM_rnglistx;
|
||||
}
|
||||
// If we hit this point it means we converted subprogram DIEs from
|
||||
// low_pc/high_pc into ranges. The CU originally didn't have DW_AT_*_base, so
|
||||
// we are adding it here.
|
||||
if (RangesBase)
|
||||
AbbrevWriter.addAttribute(Unit, Abbrev, RangeBaseAttribute,
|
||||
dwarf::DW_FORM_sec_offset);
|
||||
|
||||
// Converting DW_AT_high_pc into DW_AT_ranges.
|
||||
// For DWARF4 it's DW_FORM_sec_offset.
|
||||
// For DWARF5 it can be either DW_FORM_sec_offset or DW_FORM_rnglistx.
|
||||
// For consistency for DWARF5 we always use DW_FORM_rnglistx.
|
||||
AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc,
|
||||
dwarf::DW_AT_ranges,
|
||||
dwarf::DW_FORM_sec_offset);
|
||||
dwarf::DW_AT_ranges, RangesForm);
|
||||
}
|
||||
|
||||
void DWARFRewriter::convertToRangesPatchDebugInfo(
|
||||
|
@ -1395,19 +1613,42 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
|
|||
|
||||
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
||||
uint32_t BaseOffset = 0;
|
||||
if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) {
|
||||
dwarf::Form LowForm = LowPCVal->V.getForm();
|
||||
|
||||
// In DWARF4 for DW_AT_low_pc in binary DW_FORM_addr is used. In the DWO
|
||||
// section DW_FORM_GNU_addr_index is used. So for if we are converting
|
||||
// DW_AT_low_pc/DW_AT_high_pc and see DW_FORM_GNU_addr_index. We are
|
||||
// converting in DWO section, and DW_AT_ranges [DW_FORM_sec_offset] is
|
||||
// relative to DW_AT_GNU_ranges_base.
|
||||
if (LowForm == dwarf::DW_FORM_GNU_addr_index) {
|
||||
// Use ULEB128 for the value.
|
||||
DebugInfoPatcher.addUDataPatch(LowPCOffset, 0,
|
||||
std::abs(int(HighPCOffset - LowPCOffset)));
|
||||
DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, LowPCVal->Size);
|
||||
// Ranges are relative to DW_AT_GNU_ranges_base.
|
||||
BaseOffset = DebugInfoPatcher.getRangeBase();
|
||||
} else {
|
||||
DebugInfoPatcher.addLE64Patch(LowPCOffset, 0);
|
||||
// If DW_AT_GNU_ranges_base was inserted.
|
||||
// In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or
|
||||
// DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is
|
||||
// when it's absent.
|
||||
if (LowForm == dwarf::DW_FORM_addrx) {
|
||||
uint32_t Index =
|
||||
AddrWriter->getIndexFromAddress(0, DIE.getDwarfUnit()->getOffset());
|
||||
DebugInfoPatcher.addUDataPatch(LowPCOffset, Index, LowPCVal->Size);
|
||||
} else
|
||||
DebugInfoPatcher.addLE64Patch(LowPCOffset, 0);
|
||||
|
||||
// Original CU didn't have DW_AT_*_base. We converted it's children (or
|
||||
// dwo), so need to insert it into CU.
|
||||
if (RangesBase)
|
||||
reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher)
|
||||
.insertNewEntry(DIE, *RangesBase);
|
||||
}
|
||||
DebugInfoPatcher.addLE32Patch(HighPCOffset, RangesSectionOffset - BaseOffset,
|
||||
HighPCVal->Size);
|
||||
|
||||
// HighPC was conveted into DW_AT_ranges.
|
||||
// For DWARF5 we only access ranges throught index.
|
||||
if (DIE.getDwarfUnit()->getVersion() >= 5)
|
||||
DebugInfoPatcher.addUDataPatch(HighPCOffset, RangesSectionOffset,
|
||||
HighPCVal->Size);
|
||||
else
|
||||
DebugInfoPatcher.addLE32Patch(
|
||||
HighPCOffset, RangesSectionOffset - BaseOffset, HighPCVal->Size);
|
||||
}
|
||||
|
|
|
@ -311,8 +311,9 @@ WriteBoltInfoSection("bolt-info",
|
|||
|
||||
constexpr const char *RewriteInstance::SectionsToOverwrite[];
|
||||
std::vector<std::string> RewriteInstance::DebugSectionsToOverwrite = {
|
||||
".debug_abbrev", ".debug_aranges", ".debug_line", ".debug_loc",
|
||||
".debug_ranges", ".gdb_index", ".debug_addr"};
|
||||
".debug_abbrev", ".debug_aranges", ".debug_line", ".debug_line_str",
|
||||
".debug_loc", ".debug_loclists", ".debug_ranges", ".debug_rnglists",
|
||||
".gdb_index", ".debug_addr"};
|
||||
|
||||
const char RewriteInstance::TimerGroupName[] = "rewrite";
|
||||
const char RewriteInstance::TimerGroupDesc[] = "Rewrite passes";
|
||||
|
|
|
@ -0,0 +1,424 @@
|
|||
# clang++ helper.cpp -g -O2 -S
|
||||
# int fooVar = 0;
|
||||
# void useFoo(int * x) {
|
||||
# *x += 4;
|
||||
# }
|
||||
#
|
||||
# int foo(int argc) {
|
||||
# int x = argc;
|
||||
# useFoo(&x);
|
||||
# return x;
|
||||
# }
|
||||
.text
|
||||
.file "foo.cpp"
|
||||
.file 0 "/testLocListMultiple" "foo.cpp" md5 0x9410f31145d031fcc1f2464b809e409a
|
||||
.globl _Z6useFooPi # -- Begin function _Z6useFooPi
|
||||
.p2align 4, 0x90
|
||||
.type _Z6useFooPi,@function
|
||||
_Z6useFooPi: # @_Z6useFooPi
|
||||
.Lfunc_begin0:
|
||||
.loc 0 2 0 # foo.cpp:2:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: useFoo:x <- $rdi
|
||||
.loc 0 3 4 prologue_end # foo.cpp:3:4
|
||||
addl $4, (%rdi)
|
||||
.loc 0 4 1 # foo.cpp:4:1
|
||||
retq
|
||||
.Ltmp0:
|
||||
.Lfunc_end0:
|
||||
.size _Z6useFooPi, .Lfunc_end0-_Z6useFooPi
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.globl _Z3fooi # -- Begin function _Z3fooi
|
||||
.p2align 4, 0x90
|
||||
.type _Z3fooi,@function
|
||||
_Z3fooi: # @_Z3fooi
|
||||
.Lfunc_begin1:
|
||||
.loc 0 6 0 # foo.cpp:6:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: foo:argc <- $edi
|
||||
#DEBUG_VALUE: foo:x <- $edi
|
||||
# kill: def $edi killed $edi def $rdi
|
||||
#DEBUG_VALUE: useFoo:x <- undef
|
||||
.loc 0 3 4 prologue_end # foo.cpp:3:4
|
||||
leal 4(%rdi), %eax
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: foo:x <- $eax
|
||||
.loc 0 9 4 # foo.cpp:9:4
|
||||
retq
|
||||
.Ltmp2:
|
||||
.Lfunc_end1:
|
||||
.size _Z3fooi, .Lfunc_end1-_Z3fooi
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.type fooVar,@object # @fooVar
|
||||
.bss
|
||||
.globl fooVar
|
||||
.p2align 2
|
||||
fooVar:
|
||||
.long 0 # 0x0
|
||||
.size fooVar, 4
|
||||
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 1 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 80 # super-register DW_OP_reg0
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.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 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.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 32 # DW_AT_inline
|
||||
.byte 33 # DW_FORM_implicit_const
|
||||
.byte 1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 7 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.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 8 # Abbreviation Code
|
||||
.byte 15 # DW_TAG_pointer_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 9 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.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 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 10 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.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 11 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.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 12 # Abbreviation Code
|
||||
.byte 29 # DW_TAG_inlined_subroutine
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 88 # DW_AT_call_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 89 # DW_AT_call_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 87 # DW_AT_call_column
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.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:0x83 DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 33 # 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
|
||||
.byte 1 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0xb DW_TAG_variable
|
||||
.byte 3 # DW_AT_name
|
||||
.long 50 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 161
|
||||
.byte 0
|
||||
.byte 3 # Abbrev [3] 0x32:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 4 # Abbrev [4] 0x36:0x14 DW_TAG_subprogram
|
||||
.byte 1 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.long 74 # DW_AT_abstract_origin
|
||||
.byte 5 # Abbrev [5] 0x42:0x7 DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.long 79 # DW_AT_abstract_origin
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 6 # Abbrev [6] 0x4a:0xe DW_TAG_subprogram
|
||||
.byte 5 # DW_AT_linkage_name
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
# DW_AT_external
|
||||
# DW_AT_inline
|
||||
.byte 7 # Abbrev [7] 0x4f:0x8 DW_TAG_formal_parameter
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 88 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 8 # Abbrev [8] 0x58:0x5 DW_TAG_pointer_type
|
||||
.long 50 # DW_AT_type
|
||||
.byte 9 # Abbrev [9] 0x5d:0x31 DW_TAG_subprogram
|
||||
.byte 2 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.byte 8 # DW_AT_linkage_name
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 6 # DW_AT_decl_line
|
||||
.long 50 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 10 # Abbrev [10] 0x6d:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 6 # DW_AT_decl_line
|
||||
.long 50 # DW_AT_type
|
||||
.byte 11 # Abbrev [11] 0x77:0x9 DW_TAG_variable
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 7 # DW_AT_decl_line
|
||||
.long 50 # DW_AT_type
|
||||
.byte 12 # Abbrev [12] 0x80:0xd DW_TAG_inlined_subroutine
|
||||
.long 74 # DW_AT_abstract_origin
|
||||
.byte 2 # DW_AT_low_pc
|
||||
.long .Ltmp1-.Lfunc_begin1 # DW_AT_high_pc
|
||||
.byte 0 # DW_AT_call_file
|
||||
.byte 8 # DW_AT_call_line
|
||||
.byte 4 # DW_AT_call_column
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 48 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 15.0.0)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "foo.cpp" # string offset=134
|
||||
.Linfo_string2:
|
||||
.asciz "/testLocListMultiple" # string offset=142
|
||||
.Linfo_string3:
|
||||
.asciz "fooVar" # string offset=199
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=206
|
||||
.Linfo_string5:
|
||||
.asciz "_Z6useFooPi" # string offset=210
|
||||
.Linfo_string6:
|
||||
.asciz "useFoo" # string offset=222
|
||||
.Linfo_string7:
|
||||
.asciz "x" # string offset=229
|
||||
.Linfo_string8:
|
||||
.asciz "_Z3fooi" # string offset=231
|
||||
.Linfo_string9:
|
||||
.asciz "foo" # string offset=239
|
||||
.Linfo_string10:
|
||||
.asciz "argc" # string offset=243
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad fooVar
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Lfunc_begin1
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 15.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
|
@ -0,0 +1,394 @@
|
|||
# clang++ main.cpp -g -O2 -S
|
||||
# void use(int * x, int * y) {
|
||||
# *x += 4;
|
||||
# *y -= 2;
|
||||
# }
|
||||
#
|
||||
# extern int fooVar;
|
||||
# int main(int argc, char *argv[]) {
|
||||
# int x = argc;
|
||||
# int y = fooVar + 3;
|
||||
# use(&x, &y);
|
||||
# return x + y;
|
||||
# }
|
||||
|
||||
|
||||
.text
|
||||
.file "main.cpp"
|
||||
.globl _Z3usePiS_ # -- Begin function _Z3usePiS_
|
||||
.p2align 4, 0x90
|
||||
.type _Z3usePiS_,@function
|
||||
_Z3usePiS_: # @_Z3usePiS_
|
||||
.Lfunc_begin0:
|
||||
.file 0 "/testLocListMultiple" "main.cpp" md5 0xb1a1551182284263b0faa0cae08277da
|
||||
.loc 0 1 0 # main.cpp:1:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: use:x <- $rdi
|
||||
#DEBUG_VALUE: use:y <- $rsi
|
||||
.loc 0 2 4 prologue_end # main.cpp:2:4
|
||||
addl $4, (%rdi)
|
||||
.loc 0 3 4 # main.cpp:3:4
|
||||
addl $-2, (%rsi)
|
||||
.loc 0 4 1 # main.cpp:4:1
|
||||
retq
|
||||
.Ltmp0:
|
||||
.Lfunc_end0:
|
||||
.size _Z3usePiS_, .Lfunc_end0-_Z3usePiS_
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4, 0x90
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin1:
|
||||
.loc 0 7 0 # main.cpp:7:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: main:argc <- $edi
|
||||
#DEBUG_VALUE: main:argv <- $rsi
|
||||
#DEBUG_VALUE: main:x <- $edi
|
||||
# kill: def $edi killed $edi def $rdi
|
||||
.loc 0 9 12 prologue_end # main.cpp:9:12
|
||||
movl fooVar(%rip), %eax
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: main:y <- [DW_OP_plus_uconst 3, DW_OP_stack_value] $eax
|
||||
#DEBUG_VALUE: main:y <- [DW_OP_plus_uconst 1, DW_OP_stack_value] $eax
|
||||
#DEBUG_VALUE: main:x <- [DW_OP_plus_uconst 4, DW_OP_stack_value] $edi
|
||||
.loc 0 11 13 # main.cpp:11:13
|
||||
addl %edi, %eax
|
||||
.Ltmp2:
|
||||
addl $5, %eax
|
||||
.loc 0 11 4 is_stmt 0 # main.cpp:11:4
|
||||
retq
|
||||
.Ltmp3:
|
||||
.Lfunc_end1:
|
||||
.size main, .Lfunc_end1-main
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 2 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.long .Ldebug_loc1-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
|
||||
.byte 10 # Loc expr size
|
||||
.byte 117 # DW_OP_breg5
|
||||
.byte 4 # 4
|
||||
.byte 16 # DW_OP_constu
|
||||
.byte 255 # 4294967295
|
||||
.byte 255 #
|
||||
.byte 255 #
|
||||
.byte 255 #
|
||||
.byte 15 #
|
||||
.byte 26 # DW_OP_and
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc1:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp2-.Lfunc_begin0 # ending offset
|
||||
.byte 10 # Loc expr size
|
||||
.byte 112 # DW_OP_breg0
|
||||
.byte 1 # 1
|
||||
.byte 16 # DW_OP_constu
|
||||
.byte 255 # 4294967295
|
||||
.byte 255 #
|
||||
.byte 255 #
|
||||
.byte 255 #
|
||||
.byte 15 #
|
||||
.byte 26 # DW_OP_and
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.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 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.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 4 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.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 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.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 6 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 7 # Abbreviation Code
|
||||
.byte 15 # DW_TAG_pointer_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.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 .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.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:0x8a DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 33 # 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
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x21 DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.byte 3 # DW_AT_linkage_name
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x33:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 130 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x3d:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 84
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 130 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 4 # Abbrev [4] 0x48:0x36 DW_TAG_subprogram
|
||||
.byte 1 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 7 # DW_AT_decl_line
|
||||
.long 126 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x57:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 7 # DW_AT_decl_line
|
||||
.long 126 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x61:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 84
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 7 # DW_AT_decl_line
|
||||
.long 135 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x6b:0x9 DW_TAG_variable
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 8 # DW_AT_decl_line
|
||||
.long 126 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x74:0x9 DW_TAG_variable
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 9 # DW_AT_decl_line
|
||||
.long 126 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 6 # Abbrev [6] 0x7e:0x4 DW_TAG_base_type
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 7 # Abbrev [7] 0x82:0x5 DW_TAG_pointer_type
|
||||
.long 126 # DW_AT_type
|
||||
.byte 7 # Abbrev [7] 0x87:0x5 DW_TAG_pointer_type
|
||||
.long 140 # DW_AT_type
|
||||
.byte 7 # Abbrev [7] 0x8c:0x5 DW_TAG_pointer_type
|
||||
.long 145 # DW_AT_type
|
||||
.byte 6 # Abbrev [6] 0x91:0x4 DW_TAG_base_type
|
||||
.byte 11 # DW_AT_name
|
||||
.byte 6 # DW_AT_encoding
|
||||
.byte 1 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 52 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 15.0.0" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "main.cpp" # string offset=134
|
||||
.Linfo_string2:
|
||||
.asciz "/testLocListMultiple" # string offset=143
|
||||
.Linfo_string3:
|
||||
.asciz "_Z3usePiS_" # string offset=200
|
||||
.Linfo_string4:
|
||||
.asciz "use" # string offset=211
|
||||
.Linfo_string5:
|
||||
.asciz "main" # string offset=215
|
||||
.Linfo_string6:
|
||||
.asciz "int" # string offset=220
|
||||
.Linfo_string7:
|
||||
.asciz "x" # string offset=224
|
||||
.Linfo_string8:
|
||||
.asciz "y" # string offset=226
|
||||
.Linfo_string9:
|
||||
.asciz "argc" # string offset=228
|
||||
.Linfo_string10:
|
||||
.asciz "argv" # string offset=233
|
||||
.Linfo_string11:
|
||||
.asciz "char" # string offset=238
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.long .Linfo_string11
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Lfunc_begin1
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 15.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
|
@ -0,0 +1,167 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
|
||||
# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.bolt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This test checks that .debug_line gets generated correctly when .debug_info is DWARF5, and .debug_line is DWARF4.
|
||||
|
||||
# PRECHECK: version: 4
|
||||
# PRECHECK: file_names[ 1]:
|
||||
# PRECHECK-NEXT: name: "main.cpp"
|
||||
# PRECHECK-NEXT: dir_index: 0
|
||||
# PRECHECK-NEXT: mod_time: 0x00000000
|
||||
# PRECHECK-NEXT: length: 0x00000000
|
||||
|
||||
# POSTCHECK: version: 4
|
||||
# POSTCHECK: file_names[ 1]:
|
||||
# POSTCHECK-NEXT: name: "main.cpp"
|
||||
# POSTCHECK-NEXT: dir_index: 0
|
||||
# POSTCHECK-NEXT: mod_time: 0x00000000
|
||||
# POSTCHECK-NEXT: length: 0x00000000
|
||||
|
||||
# int main() {
|
||||
# return 0;
|
||||
# }
|
||||
|
||||
|
||||
.file "main.cpp"
|
||||
.text
|
||||
.Ltext0:
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB0:
|
||||
.file 1 "main.cpp"
|
||||
.loc 1 1 12
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
.loc 1 2 10
|
||||
movl $0, %eax
|
||||
.loc 1 3 1
|
||||
popq %rbp
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size main, .-main
|
||||
.Letext0:
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0x50
|
||||
.value 0x5
|
||||
.byte 0x1
|
||||
.byte 0x8
|
||||
.long .Ldebug_abbrev0
|
||||
.uleb128 0x1
|
||||
.long .LASF0
|
||||
.byte 0x21
|
||||
.long .LASF1
|
||||
.long .LASF2
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.long .Ldebug_line0
|
||||
.uleb128 0x2
|
||||
.long .LASF3
|
||||
.byte 0x1
|
||||
.byte 0x1
|
||||
.byte 0x5
|
||||
.long 0x4c
|
||||
.quad .LFB0
|
||||
.quad .LFE0-.LFB0
|
||||
.uleb128 0x1
|
||||
.byte 0x9c
|
||||
.uleb128 0x3
|
||||
.byte 0x4
|
||||
.byte 0x5
|
||||
.string "int"
|
||||
.byte 0
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.Ldebug_abbrev0:
|
||||
.uleb128 0x1
|
||||
.uleb128 0x11
|
||||
.byte 0x1
|
||||
.uleb128 0x25
|
||||
.uleb128 0xe
|
||||
.uleb128 0x13
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x1b
|
||||
.uleb128 0xe
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x10
|
||||
.uleb128 0x17
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x2
|
||||
.uleb128 0x2e
|
||||
.byte 0
|
||||
.uleb128 0x3f
|
||||
.uleb128 0x19
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x40
|
||||
.uleb128 0x18
|
||||
.uleb128 0x7a
|
||||
.uleb128 0x19
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0x24
|
||||
.byte 0
|
||||
.uleb128 0xb
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3e
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0x8
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.section .debug_aranges,"",@progbits
|
||||
.long 0x2c
|
||||
.value 0x2
|
||||
.long .Ldebug_info0
|
||||
.byte 0x8
|
||||
.byte 0
|
||||
.value 0
|
||||
.value 0
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.quad 0
|
||||
.quad 0
|
||||
.section .debug_line,"",@progbits
|
||||
.Ldebug_line0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.LASF0:
|
||||
.string "GNU C++14 8.5.0 20210514 (Red Hat 8.5.0-3) -mtune=generic -march=x86-64 -g2 -gdwarf-5"
|
||||
.LASF1:
|
||||
.string "main.cpp"
|
||||
.LASF3:
|
||||
.string "main"
|
||||
.LASF2:
|
||||
.string "."
|
||||
.ident "GCC: (GNU) 8.5.0 20210514 (Red Hat 8.5.0-3)"
|
||||
.section .note.GNU-stack,"",@progbits
|
|
@ -0,0 +1,185 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
|
||||
# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.bolt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This test checks that DWARF5 .debug_line is handled correctly.
|
||||
|
||||
# PRECHECK: version: 5
|
||||
# PRECHECK: include_directories[ 0] = .debug_line_str[0x00000000]
|
||||
# PRECHECK-NEXT: file_names[ 0]:
|
||||
# PRECHECK-NEXT: name: .debug_line_str[0x00000002] = "main.cpp"
|
||||
# PRECHECK-NEXT: dir_index: 0
|
||||
# PRECHECK-NEXT: md5_checksum: bb12fec8d002b1f0e06f7dee4604c6cc
|
||||
# PRECHECK-NOT: file_names[ 1]:
|
||||
|
||||
# POSTCHECK: version: 5
|
||||
# POSTCHECK: include_directories[ 0] = .debug_line_str[0x00000000]
|
||||
# POSTCHECK-NEXT: file_names[ 0]:
|
||||
# POSTCHECK-NEXT: name: .debug_line_str[0x00000002] = "main.cpp"
|
||||
# POSTCHECK-NEXT: dir_index: 0
|
||||
# POSTCHECK-NEXT: md5_checksum: bb12fec8d002b1f0e06f7dee4604c6cc
|
||||
# POSTCHECK-NOT: file_names[ 1]:
|
||||
|
||||
# int main() {
|
||||
# return 0;
|
||||
# }
|
||||
|
||||
.text
|
||||
.file "main.cpp"
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4, 0x90
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "main.cpp" md5 0xbb12fec8d002b1f0e06f7dee4604c6cc
|
||||
.loc 0 1 0 # main.cpp:1:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
movl $0, -4(%rbp)
|
||||
.Ltmp0:
|
||||
.loc 0 2 3 prologue_end # main.cpp:2:3
|
||||
xorl %eax, %eax
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp1:
|
||||
.Lfunc_end0:
|
||||
.size main, .Lfunc_end0-main
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_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 0 # DW_CHILDREN_no
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.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 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.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:0x2b DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 33 # 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
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.byte 2 # Abbrev [2] 0x23:0xf DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 50 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x32:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 24 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 15.0.0" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "main.cpp" # string offset=134
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=143
|
||||
.Linfo_string3:
|
||||
.asciz "main" # string offset=180
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=185
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 15.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
|
@ -0,0 +1,439 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
|
||||
# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt > %t.txt
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt
|
||||
# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This tests checks that re-writing of .debug_loclists is handled correctly.
|
||||
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# PRECHECK-EMPTY:
|
||||
# PRECHECK: DW_TAG_variable
|
||||
# PRECHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# PRECHECK-SAME: indexed (0x0)
|
||||
# PRECHECK-SAME: loclist = 0x00000010
|
||||
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR:]]
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR2:]]
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# POSTCHECK: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# POSTCHECK: DW_TAG_variable
|
||||
# POSTCHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# POSTCHECK-SAME: indexed (0x0)
|
||||
# POSTCHECK-SAME: loclist = 0x00000010
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR + 3]]
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR2]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR2 + 1]]
|
||||
|
||||
# clang++ main.cpp -g -O2 -S
|
||||
# void use(int * x) {
|
||||
# *x += 4;
|
||||
# }
|
||||
#
|
||||
# int main(int argc, char *argv[]) {
|
||||
# int x = argc;
|
||||
# use(&x);
|
||||
# return x;
|
||||
# }
|
||||
|
||||
.text
|
||||
.file "main.cpp"
|
||||
.globl _Z3usePi # -- Begin function _Z3usePi
|
||||
.p2align 4, 0x90
|
||||
.type _Z3usePi,@function
|
||||
_Z3usePi: # @_Z3usePi
|
||||
.Lfunc_begin0:
|
||||
.file 0 "testLocList" "main.cpp" md5 0x95a77c95663d823a6228bf928825e8c7
|
||||
.loc 0 1 0 # main.cpp:1:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: use:x <- $rdi
|
||||
.loc 0 2 4 prologue_end # main.cpp:2:4
|
||||
addl $4, (%rdi)
|
||||
.loc 0 3 1 # main.cpp:3:1
|
||||
retq
|
||||
.Ltmp0:
|
||||
.Lfunc_end0:
|
||||
.size _Z3usePi, .Lfunc_end0-_Z3usePi
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4, 0x90
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin1:
|
||||
.loc 0 5 0 # main.cpp:5:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: main:argc <- $edi
|
||||
#DEBUG_VALUE: main:argv <- $rsi
|
||||
#DEBUG_VALUE: main:x <- $edi
|
||||
# kill: def $edi killed $edi def $rdi
|
||||
#DEBUG_VALUE: use:x <- undef
|
||||
.loc 0 2 4 prologue_end # main.cpp:2:4
|
||||
leal 4(%rdi), %eax
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: main:x <- $eax
|
||||
.loc 0 8 4 # main.cpp:8:4
|
||||
retq
|
||||
.Ltmp2:
|
||||
.Lfunc_end1:
|
||||
.size main, .Lfunc_end1-main
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 1 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 80 # super-register DW_OP_reg0
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.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 32 # DW_AT_inline
|
||||
.byte 33 # DW_FORM_implicit_const
|
||||
.byte 1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.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 6 # Abbreviation Code
|
||||
.byte 15 # DW_TAG_pointer_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 7 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 8 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.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 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 9 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.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 10 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.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 11 # Abbreviation Code
|
||||
.byte 29 # DW_TAG_inlined_subroutine
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 88 # DW_AT_call_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 89 # DW_AT_call_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 87 # DW_AT_call_column
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.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:0x8f DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 33 # 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
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x14 DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.long 59 # DW_AT_abstract_origin
|
||||
.byte 3 # Abbrev [3] 0x33:0x7 DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.long 64 # DW_AT_abstract_origin
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 4 # Abbrev [4] 0x3b:0xe DW_TAG_subprogram
|
||||
.byte 3 # DW_AT_linkage_name
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
# DW_AT_external
|
||||
# DW_AT_inline
|
||||
.byte 5 # Abbrev [5] 0x40:0x8 DW_TAG_formal_parameter
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 73 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 6 # Abbrev [6] 0x49:0x5 DW_TAG_pointer_type
|
||||
.long 78 # DW_AT_type
|
||||
.byte 7 # Abbrev [7] 0x4e:0x4 DW_TAG_base_type
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 8 # Abbrev [8] 0x52:0x3a DW_TAG_subprogram
|
||||
.byte 1 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 5 # DW_AT_decl_line
|
||||
.long 78 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 9 # Abbrev [9] 0x61:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 5 # DW_AT_decl_line
|
||||
.long 78 # DW_AT_type
|
||||
.byte 9 # Abbrev [9] 0x6b:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 84
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 5 # DW_AT_decl_line
|
||||
.long 140 # DW_AT_type
|
||||
.byte 10 # Abbrev [10] 0x75:0x9 DW_TAG_variable
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 6 # DW_AT_decl_line
|
||||
.long 78 # DW_AT_type
|
||||
.byte 11 # Abbrev [11] 0x7e:0xd DW_TAG_inlined_subroutine
|
||||
.long 59 # DW_AT_abstract_origin
|
||||
.byte 1 # DW_AT_low_pc
|
||||
.long .Ltmp1-.Lfunc_begin1 # DW_AT_high_pc
|
||||
.byte 0 # DW_AT_call_file
|
||||
.byte 7 # DW_AT_call_line
|
||||
.byte 4 # DW_AT_call_column
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 6 # Abbrev [6] 0x8c:0x5 DW_TAG_pointer_type
|
||||
.long 145 # DW_AT_type
|
||||
.byte 6 # Abbrev [6] 0x91:0x5 DW_TAG_pointer_type
|
||||
.long 150 # DW_AT_type
|
||||
.byte 7 # Abbrev [7] 0x96:0x4 DW_TAG_base_type
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 6 # DW_AT_encoding
|
||||
.byte 1 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 48 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 15.0.0)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "main.cpp" # string offset=134
|
||||
.Linfo_string2:
|
||||
.asciz "/testLocList" # string offset=143
|
||||
.Linfo_string3:
|
||||
.asciz "_Z3usePi" # string offset=192
|
||||
.Linfo_string4:
|
||||
.asciz "use" # string offset=201
|
||||
.Linfo_string5:
|
||||
.asciz "x" # string offset=205
|
||||
.Linfo_string6:
|
||||
.asciz "int" # string offset=207
|
||||
.Linfo_string7:
|
||||
.asciz "main" # string offset=211
|
||||
.Linfo_string8:
|
||||
.asciz "argc" # string offset=216
|
||||
.Linfo_string9:
|
||||
.asciz "argv" # string offset=221
|
||||
.Linfo_string10:
|
||||
.asciz "char" # string offset=226
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Lfunc_begin1
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 15.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
|
@ -0,0 +1,302 @@
|
|||
|
||||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o
|
||||
# RUN: %clang %cflags -dwarf-5 %tmain.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt > %t.txt
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt
|
||||
|
||||
# This test checks that we correctly handle DW_AT_low_pc [DW_FORM_addrx] that is part of DW_TAG_label.
|
||||
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_TAG_label
|
||||
# PRECHECK-NEXT: DW_AT_name
|
||||
# PRECHECK-NEXT: DW_AT_decl_file
|
||||
# PRECHECK-NEXT: DW_AT_decl_line
|
||||
# PRECHECK-NEXT:DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001)
|
||||
# PRECHECK: DW_TAG_label
|
||||
# PRECHECK-NEXT: DW_AT_name
|
||||
# PRECHECK-NEXT: DW_AT_decl_file
|
||||
# PRECHECK-NEXT: DW_AT_decl_line
|
||||
# PRECHECK-NEXT:DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002)
|
||||
|
||||
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR:]]
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR2:]]
|
||||
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_TAG_label
|
||||
# POSTCHECK-NEXT: DW_AT_name
|
||||
# POSTCHECK-NEXT: DW_AT_decl_file
|
||||
# POSTCHECK-NEXT: DW_AT_decl_line
|
||||
# POSTCHECK-NEXT:
|
||||
# POSTCHECK-NEXT:DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002)
|
||||
# POSTCHECK-SAME: [0x[[#ADDR]]
|
||||
# POSTCHECK: DW_TAG_label
|
||||
# POSTCHECK-NEXT: DW_AT_name
|
||||
# POSTCHECK-NEXT: DW_AT_decl_file
|
||||
# POSTCHECK-NEXT: DW_AT_decl_line
|
||||
# POSTCHECK-NEXT:
|
||||
# POSTCHECK-NEXT:DW_AT_low_pc [DW_FORM_addrx] (indexed (00000003)
|
||||
# POSTCHECK-SAME: [0x[[#ADDR2]]
|
||||
|
||||
# clang++ main.cpp -g -S
|
||||
# int main() {
|
||||
# int a = 4;
|
||||
# if (a == 5)
|
||||
# goto LABEL1;
|
||||
# else
|
||||
# goto LABEL2;
|
||||
# LABEL1:a++;
|
||||
# LABEL2:a--;
|
||||
# return 0;
|
||||
# }
|
||||
|
||||
.text
|
||||
.file "main.cpp"
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4, 0x90
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin0:
|
||||
.file 0 "/testLabel" "main.cpp" md5 0xa0bd66020d06f1303de7008e3c542050
|
||||
.loc 0 1 0 # main.cpp:1:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
movl $0, -4(%rbp)
|
||||
.Ltmp0:
|
||||
.loc 0 2 7 prologue_end # main.cpp:2:7
|
||||
movl $4, -8(%rbp)
|
||||
.Ltmp1:
|
||||
.loc 0 3 9 # main.cpp:3:9
|
||||
cmpl $5, -8(%rbp)
|
||||
.Ltmp2:
|
||||
.loc 0 3 7 is_stmt 0 # main.cpp:3:7
|
||||
jne .LBB0_2
|
||||
# %bb.1: # %if.then
|
||||
.Ltmp3:
|
||||
.loc 0 4 5 is_stmt 1 # main.cpp:4:5
|
||||
jmp .LBB0_3
|
||||
.LBB0_2: # %if.else
|
||||
.loc 0 6 5 # main.cpp:6:5
|
||||
jmp .LBB0_4
|
||||
.Ltmp4:
|
||||
.LBB0_3: # %LABEL1
|
||||
#DEBUG_LABEL: main:LABEL1
|
||||
.loc 0 7 11 # main.cpp:7:11
|
||||
movl -8(%rbp), %eax
|
||||
addl $1, %eax
|
||||
movl %eax, -8(%rbp)
|
||||
.LBB0_4: # %LABEL2
|
||||
.Ltmp5:
|
||||
#DEBUG_LABEL: main:LABEL2
|
||||
.loc 0 8 11 # main.cpp:8:11
|
||||
movl -8(%rbp), %eax
|
||||
addl $-1, %eax
|
||||
movl %eax, -8(%rbp)
|
||||
.loc 0 9 3 # main.cpp:9:3
|
||||
xorl %eax, %eax
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp6:
|
||||
.Lfunc_end0:
|
||||
.size main, .Lfunc_end0-main
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.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 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 24 # DW_FORM_exprloc
|
||||
.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 4 # Abbreviation Code
|
||||
.byte 10 # DW_TAG_label
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.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 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.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:0x41 DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 33 # 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
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.byte 2 # Abbrev [2] 0x23:0x25 DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 72 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x32:0xb DW_TAG_variable
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 145
|
||||
.byte 120
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 72 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x3d:0x5 DW_TAG_label
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 7 # DW_AT_decl_line
|
||||
.byte 1 # DW_AT_low_pc
|
||||
.byte 4 # Abbrev [4] 0x42:0x5 DW_TAG_label
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 8 # DW_AT_decl_line
|
||||
.byte 2 # DW_AT_low_pc
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 5 # Abbrev [5] 0x48:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 36 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 15.0.0" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "main.cpp" # string offset=134
|
||||
.Linfo_string2:
|
||||
.asciz "/testLabel" # string offset=143
|
||||
.Linfo_string3:
|
||||
.asciz "main" # string offset=190
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=195
|
||||
.Linfo_string5:
|
||||
.asciz "a" # string offset=199
|
||||
.Linfo_string6:
|
||||
.asciz "LABEL1" # string offset=201
|
||||
.Linfo_string7:
|
||||
.asciz "LABEL2" # string offset=208
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Ltmp4
|
||||
.quad .Ltmp5
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 15.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
|
@ -0,0 +1,461 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o
|
||||
# RUN: %clang %cflags -dwarf-5 %tmain.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This test checks that we correctly encode new index into .debug_addr section
|
||||
# from DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x#)
|
||||
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_TAG_variable
|
||||
# PRECHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0)
|
||||
# PRECHECK: DW_TAG_variable
|
||||
# PRECHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x1)
|
||||
# PRECHECK-EMPTY:
|
||||
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_TAG_variable
|
||||
# POSTCHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x3)
|
||||
# POSTCHECK-EMPTY:
|
||||
# POSTCHECK: DW_TAG_variable
|
||||
# POSTCHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x4)
|
||||
# POSTCHECK-EMPTY:
|
||||
|
||||
# clang++ main.cpp -g -O2
|
||||
# void use(int * x, int * y) {
|
||||
# *x += 4;
|
||||
# *y -= 2;
|
||||
# }
|
||||
#
|
||||
# int x = 0;
|
||||
# int y = 1;
|
||||
# int main(int argc, char *argv[]) {
|
||||
# x = argc;
|
||||
# y = argc + 3;
|
||||
# use(&x, &y);
|
||||
# return x + y;
|
||||
# }
|
||||
|
||||
.text
|
||||
.file "main.cpp"
|
||||
.file 0 "/testLocExprLoc" "main.cpp" md5 0xd4fd79ce0087c4cefd089752bf2182c6
|
||||
.globl _Z3usePiS_ # -- Begin function _Z3usePiS_
|
||||
.p2align 4, 0x90
|
||||
.type _Z3usePiS_,@function
|
||||
_Z3usePiS_: # @_Z3usePiS_
|
||||
.Lfunc_begin0:
|
||||
.loc 0 1 0 # main.cpp:1:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: use:x <- $rdi
|
||||
#DEBUG_VALUE: use:y <- $rsi
|
||||
.loc 0 2 4 prologue_end # main.cpp:2:4
|
||||
addl $4, (%rdi)
|
||||
.loc 0 3 4 # main.cpp:3:4
|
||||
addl $-2, (%rsi)
|
||||
.loc 0 4 1 # main.cpp:4:1
|
||||
retq
|
||||
.Ltmp0:
|
||||
.Lfunc_end0:
|
||||
.size _Z3usePiS_, .Lfunc_end0-_Z3usePiS_
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4, 0x90
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin1:
|
||||
.loc 0 8 0 # main.cpp:8:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: main:argc <- $edi
|
||||
#DEBUG_VALUE: main:argv <- $rsi
|
||||
# kill: def $edi killed $edi def $rdi
|
||||
.loc 0 2 4 prologue_end # main.cpp:2:4
|
||||
leal 4(%rdi), %eax
|
||||
movl %eax, x(%rip)
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: use:x <- undef
|
||||
.loc 0 3 4 # main.cpp:3:4
|
||||
leal 1(%rdi), %eax
|
||||
movl %eax, y(%rip)
|
||||
.Ltmp2:
|
||||
#DEBUG_VALUE: use:y <- undef
|
||||
.loc 0 12 13 # main.cpp:12:13
|
||||
leal (%rdi,%rdi), %eax
|
||||
addl $5, %eax
|
||||
.loc 0 12 4 is_stmt 0 # main.cpp:12:4
|
||||
retq
|
||||
.Ltmp3:
|
||||
.Lfunc_end1:
|
||||
.size main, .Lfunc_end1-main
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.type x,@object # @x
|
||||
.bss
|
||||
.globl x
|
||||
.p2align 2
|
||||
x:
|
||||
.long 0 # 0x0
|
||||
.size x, 4
|
||||
|
||||
.type y,@object # @y
|
||||
.data
|
||||
.globl y
|
||||
.p2align 2
|
||||
y:
|
||||
.long 1 # 0x1
|
||||
.size y, 4
|
||||
|
||||
.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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.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 32 # DW_AT_inline
|
||||
.byte 33 # DW_FORM_implicit_const
|
||||
.byte 1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 7 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.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 8 # Abbreviation Code
|
||||
.byte 15 # DW_TAG_pointer_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 9 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.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 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 10 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.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 11 # Abbreviation Code
|
||||
.byte 29 # DW_TAG_inlined_subroutine
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 49 # DW_AT_abstract_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 88 # DW_AT_call_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 89 # DW_AT_call_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 87 # DW_AT_call_column
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.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:0xa7 DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 33 # 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
|
||||
.byte 2 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.byte 2 # Abbrev [2] 0x23:0xb DW_TAG_variable
|
||||
.byte 3 # DW_AT_name
|
||||
.long 46 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 6 # DW_AT_decl_line
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 161
|
||||
.byte 0
|
||||
.byte 3 # Abbrev [3] 0x2e:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 2 # Abbrev [2] 0x32:0xb DW_TAG_variable
|
||||
.byte 5 # DW_AT_name
|
||||
.long 46 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 7 # DW_AT_decl_line
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 161
|
||||
.byte 1
|
||||
.byte 4 # Abbrev [4] 0x3d:0x1b DW_TAG_subprogram
|
||||
.byte 2 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.long 88 # DW_AT_abstract_origin
|
||||
.byte 5 # Abbrev [5] 0x49:0x7 DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.long 93 # DW_AT_abstract_origin
|
||||
.byte 5 # Abbrev [5] 0x50:0x7 DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 84
|
||||
.long 101 # DW_AT_abstract_origin
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 6 # Abbrev [6] 0x58:0x16 DW_TAG_subprogram
|
||||
.byte 6 # DW_AT_linkage_name
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
# DW_AT_external
|
||||
# DW_AT_inline
|
||||
.byte 7 # Abbrev [7] 0x5d:0x8 DW_TAG_formal_parameter
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 110 # DW_AT_type
|
||||
.byte 7 # Abbrev [7] 0x65:0x8 DW_TAG_formal_parameter
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 110 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 8 # Abbrev [8] 0x6e:0x5 DW_TAG_pointer_type
|
||||
.long 46 # DW_AT_type
|
||||
.byte 9 # Abbrev [9] 0x73:0x31 DW_TAG_subprogram
|
||||
.byte 3 # DW_AT_low_pc
|
||||
.long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 87
|
||||
# DW_AT_call_all_calls
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 8 # DW_AT_decl_line
|
||||
.long 46 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 10 # Abbrev [10] 0x82:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 8 # DW_AT_decl_line
|
||||
.long 46 # DW_AT_type
|
||||
.byte 10 # Abbrev [10] 0x8c:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 84
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 8 # DW_AT_decl_line
|
||||
.long 164 # DW_AT_type
|
||||
.byte 11 # Abbrev [11] 0x96:0xd DW_TAG_inlined_subroutine
|
||||
.long 88 # DW_AT_abstract_origin
|
||||
.byte 3 # DW_AT_low_pc
|
||||
.long .Ltmp2-.Lfunc_begin1 # DW_AT_high_pc
|
||||
.byte 0 # DW_AT_call_file
|
||||
.byte 11 # DW_AT_call_line
|
||||
.byte 4 # DW_AT_call_column
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 8 # Abbrev [8] 0xa4:0x5 DW_TAG_pointer_type
|
||||
.long 169 # DW_AT_type
|
||||
.byte 8 # Abbrev [8] 0xa9:0x5 DW_TAG_pointer_type
|
||||
.long 174 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0xae:0x4 DW_TAG_base_type
|
||||
.byte 11 # DW_AT_name
|
||||
.byte 6 # DW_AT_encoding
|
||||
.byte 1 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 52 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 15.0.0" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "main.cpp" # string offset=134
|
||||
.Linfo_string2:
|
||||
.asciz "/testLocExprLoc" # string offset=143
|
||||
.Linfo_string3:
|
||||
.asciz "x" # string offset=195
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=197
|
||||
.Linfo_string5:
|
||||
.asciz "y" # string offset=201
|
||||
.Linfo_string6:
|
||||
.asciz "_Z3usePiS_" # string offset=203
|
||||
.Linfo_string7:
|
||||
.asciz "use" # string offset=214
|
||||
.Linfo_string8:
|
||||
.asciz "main" # string offset=218
|
||||
.Linfo_string9:
|
||||
.asciz "argc" # string offset=223
|
||||
.Linfo_string10:
|
||||
.asciz "argv" # string offset=228
|
||||
.Linfo_string11:
|
||||
.asciz "char" # string offset=233
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.long .Linfo_string11
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad x
|
||||
.quad y
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Lfunc_begin1
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 15.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
|
@ -0,0 +1,196 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
|
||||
# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt > %t.txt
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt
|
||||
# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This tests checks that DW_AT_low_pc/DW_AT_high_pc is converted to DW_AT_low_pc/DW_AT_ranges.
|
||||
# Checks that DW_AT_rnglists_base is inserted, and that correct address is used.
|
||||
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_AT_low_pc
|
||||
# PRECHECK-SAME: DW_FORM_addrx
|
||||
# PRECHECK-SAME: (00000000)
|
||||
# PRECHECK-NEXT: DW_AT_high_pc [DW_FORM_data4] (0x0000000f)
|
||||
# PRECHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
|
||||
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR:]]
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_AT_low_pc
|
||||
# POSTCHECK-SAME: DW_FORM_addrx
|
||||
# POSTCHECK-SAME: (00000001)
|
||||
# POSTCHECK-SAME: address = 0x0000000000000000
|
||||
# POSTCHECK-NEXT: DW_AT_ranges
|
||||
# POSTCHECK-SAME: DW_FORM_rnglistx
|
||||
# POSTCHECK-SAME: (0x0)
|
||||
# POSTCHECK-SAME: rangelist = 0x00000014
|
||||
# POSTCHECK-NEXT: [
|
||||
# POSTCHECK-SAME: 0x[[#ADDR]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR + 15]]
|
||||
# POSTCHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
|
||||
# POSTCHECK-NEXT: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
|
||||
# int main() {
|
||||
# return 0;
|
||||
# }
|
||||
|
||||
.text
|
||||
.file "main.cpp"
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4, 0x90
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "main.cpp" md5 0xbb12fec8d002b1f0e06f7dee4604c6cc
|
||||
.loc 0 1 0 # main.cpp:1:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
movl $0, -4(%rbp)
|
||||
.Ltmp0:
|
||||
.loc 0 2 3 prologue_end # main.cpp:2:3
|
||||
xorl %eax, %eax
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp1:
|
||||
.Lfunc_end0:
|
||||
.size main, .Lfunc_end0-main
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.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 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_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 0 # DW_CHILDREN_no
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.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 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.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:0x2b DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 33 # 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
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.byte 2 # Abbrev [2] 0x23:0xf DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.long 50 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x32:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 24 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 15.0.0" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "main.cpp" # string offset=134
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=143
|
||||
.Linfo_string3:
|
||||
.asciz "main" # string offset=180
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=185
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 15.0.0"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
|
@ -0,0 +1,256 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
|
||||
# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt > %t.txt
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt
|
||||
# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This tests conversion for DWARF5 ranges DW_AT_ranges [DW_FORM_sec_offset] to DW_AT_ranges [DW_FORM_rnglistx]
|
||||
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_AT_ranges [DW_FORM_sec_offset]
|
||||
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR:]]
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR1:]]
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: (indexed (0x0) rangelist = 0x00000018
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR]], 0x[[#ADDR + 11]]
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR1]], 0x[[#ADDR1 + 11]]
|
||||
|
||||
# int foo() {
|
||||
# return 3;
|
||||
# }
|
||||
#
|
||||
# int main() {
|
||||
# return foo();
|
||||
# }
|
||||
|
||||
.file "main.cpp"
|
||||
.text
|
||||
.Ltext0:
|
||||
.file 0 "/testRangeOffsetToRangeX" "main.cpp"
|
||||
.section .text._Z3foov,"ax",@progbits
|
||||
.globl _Z3foov
|
||||
.type _Z3foov, @function
|
||||
_Z3foov:
|
||||
.LFB0:
|
||||
.file 1 "main.cpp"
|
||||
.loc 0 1 11
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
.loc 0 2 10
|
||||
movl $3, %eax
|
||||
.loc 0 3 1
|
||||
popq %rbp
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size _Z3foov, .-_Z3foov
|
||||
.section .text.main,"ax",@progbits
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB1:
|
||||
.loc 0 5 12
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
.loc 0 6 13
|
||||
call _Z3foov
|
||||
.loc 0 6 14
|
||||
nop
|
||||
.loc 0 7 1
|
||||
popq %rbp
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE1:
|
||||
.size main, .-main
|
||||
.text
|
||||
.Letext0:
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0x6e
|
||||
.value 0x5
|
||||
.byte 0x1
|
||||
.byte 0x8
|
||||
.long .Ldebug_abbrev0
|
||||
.uleb128 0x1
|
||||
.long .LASF2
|
||||
.byte 0x21
|
||||
.long .LASF0
|
||||
.long .LASF1
|
||||
.long .LLRL0
|
||||
.quad 0
|
||||
.long .Ldebug_line0
|
||||
.uleb128 0x2
|
||||
.long .LASF3
|
||||
.byte 0x1
|
||||
.byte 0x5
|
||||
.byte 0x5
|
||||
.long 0x48
|
||||
.quad .LFB1
|
||||
.quad .LFE1-.LFB1
|
||||
.uleb128 0x1
|
||||
.byte 0x9c
|
||||
.uleb128 0x3
|
||||
.byte 0x4
|
||||
.byte 0x5
|
||||
.string "int"
|
||||
.uleb128 0x4
|
||||
.string "foo"
|
||||
.byte 0x1
|
||||
.byte 0x1
|
||||
.byte 0x5
|
||||
.long .LASF4
|
||||
.long 0x48
|
||||
.quad .LFB0
|
||||
.quad .LFE0-.LFB0
|
||||
.uleb128 0x1
|
||||
.byte 0x9c
|
||||
.byte 0
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.Ldebug_abbrev0:
|
||||
.uleb128 0x1
|
||||
.uleb128 0x11
|
||||
.byte 0x1
|
||||
.uleb128 0x25
|
||||
.uleb128 0xe
|
||||
.uleb128 0x13
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0x1f
|
||||
.uleb128 0x1b
|
||||
.uleb128 0x1f
|
||||
.uleb128 0x55
|
||||
.uleb128 0x17
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x10
|
||||
.uleb128 0x17
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x2
|
||||
.uleb128 0x2e
|
||||
.byte 0
|
||||
.uleb128 0x3f
|
||||
.uleb128 0x19
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x40
|
||||
.uleb128 0x18
|
||||
.uleb128 0x7c
|
||||
.uleb128 0x19
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0x24
|
||||
.byte 0
|
||||
.uleb128 0xb
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3e
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0x8
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x4
|
||||
.uleb128 0x2e
|
||||
.byte 0
|
||||
.uleb128 0x3f
|
||||
.uleb128 0x19
|
||||
.uleb128 0x3
|
||||
.uleb128 0x8
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x6e
|
||||
.uleb128 0xe
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x40
|
||||
.uleb128 0x18
|
||||
.uleb128 0x7a
|
||||
.uleb128 0x19
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.section .debug_aranges,"",@progbits
|
||||
.long 0x3c
|
||||
.value 0x2
|
||||
.long .Ldebug_info0
|
||||
.byte 0x8
|
||||
.byte 0
|
||||
.value 0
|
||||
.value 0
|
||||
.quad .LFB0
|
||||
.quad .LFE0-.LFB0
|
||||
.quad .LFB1
|
||||
.quad .LFE1-.LFB1
|
||||
.quad 0
|
||||
.quad 0
|
||||
.section .debug_rnglists,"",@progbits
|
||||
.Ldebug_ranges0:
|
||||
.long .Ldebug_ranges3-.Ldebug_ranges2
|
||||
.Ldebug_ranges2:
|
||||
.value 0x5
|
||||
.byte 0x8
|
||||
.byte 0
|
||||
.long 0
|
||||
.LLRL0:
|
||||
.byte 0x7
|
||||
.quad .LFB0
|
||||
.uleb128 .LFE0-.LFB0
|
||||
.byte 0x7
|
||||
.quad .LFB1
|
||||
.uleb128 .LFE1-.LFB1
|
||||
.byte 0
|
||||
.Ldebug_ranges3:
|
||||
.section .debug_line,"",@progbits
|
||||
.Ldebug_line0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.LASF4:
|
||||
.string "_Z3foov"
|
||||
.LASF3:
|
||||
.string "main"
|
||||
.LASF2:
|
||||
.string "GNU C++17 11.x"
|
||||
.section .debug_line_str,"MS",@progbits,1
|
||||
.LASF0:
|
||||
.string "main.cpp"
|
||||
.LASF1:
|
||||
.string "/testRangeOffsetToRangeX"
|
||||
.ident "GCC: (GNU) 11.x"
|
||||
.section .note.GNU-stack,"",@progbits
|
|
@ -0,0 +1,78 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_main.s -o %tmain.o
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_helper.s -o %thelper.o
|
||||
# RUN: %clang %cflags -dwarf-5 %tmain.o %thelper.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt > %t.txt
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt
|
||||
# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This tests checks that re-writing of .debug_loclists is handled correctly for two CUs,
|
||||
# and two loclist entries.
|
||||
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# PRECHECK-EMPTY:
|
||||
# PRECHECK: DW_TAG_variable
|
||||
# PRECHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# PRECHECK-SAME: indexed (0x0)
|
||||
# PRECHECK-SAME: loclist = 0x00000014
|
||||
# PRECHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# PRECHECK-SAME: indexed (0x1)
|
||||
# PRECHECK-SAME: loclist = 0x00000028
|
||||
# PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x00000043)
|
||||
# PRECHECK-EMPTY:
|
||||
# PRECHECK: DW_TAG_variable
|
||||
# PRECHECK: DW_TAG_variable
|
||||
# PRECHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# PRECHECK-SAME: indexed (0x0)
|
||||
# PRECHECK-SAME: loclist = 0x00000047
|
||||
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR:]]
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR2:]]
|
||||
# For second CU.
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR3:]]
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR4:]]
|
||||
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# POSTCHECK: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# POSTCHECK-EMPTY
|
||||
# POSTCHECK: DW_TAG_variable
|
||||
# POSTCHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# POSTCHECK-SAME: indexed (0x0)
|
||||
# POSTCHECK-SAME: loclist = 0x00000014
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR + 6]]
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR2]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR2 + 6]]
|
||||
# POSTCHECK: DW_TAG_variable
|
||||
# POSTCHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# POSTCHECK-SAME: indexed (0x1)
|
||||
# POSTCHECK-SAME: loclist = 0x00000028
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR2]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR2 + 2]]
|
||||
|
||||
# Checking second CU
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x00000043)
|
||||
# POSTCHECK: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x00000033)
|
||||
# POSTCHECK-EMPTY:
|
||||
# POSTCHECK: DW_TAG_variable
|
||||
# POSTCHECK: DW_TAG_variable
|
||||
# POSTCHECK: DW_AT_location [DW_FORM_loclistx]
|
||||
# POSTCHECK-SAME: indexed (0x0)
|
||||
# POSTCHECK-SAME: loclist = 0x00000047
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR3]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR3 + 3]]
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR4]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR4 + 1]]
|
|
@ -0,0 +1,110 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_main.s -o %tmain.o
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5_helper.s -o %thelper.o
|
||||
# RUN: %clang %cflags -dwarf-5 %tmain.o %thelper.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-addr %t.bolt > %t.txt
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt
|
||||
# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This tests checks that re-writing of .debug_rnglists is handled correctly for two CUs,
|
||||
# and DW_AT_low_pc/DW_AT_high_pc conversion is handled correctly.
|
||||
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# PRECHECK: DW_AT_high_pc [DW_FORM_data4]
|
||||
# PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# PRECHECK-EMPTY:
|
||||
# PRECHECK: version = 0x0005
|
||||
# PRECHECK: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# PRECHECK: DW_AT_high_pc [DW_FORM_data4]
|
||||
# PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x00000043)
|
||||
|
||||
# PRECHECK: DW_TAG_inlined_subroutine
|
||||
# PRECHECK-NEXT: DW_AT_abstract_origin
|
||||
# PRECHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# PRECHECK-NEXT: DW_AT_high_pc [DW_FORM_data4] (0x00000003)
|
||||
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR:]]
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR1:]]
|
||||
# POSTCHECK-NEXT: 0x
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR2:]]
|
||||
# For second CU.
|
||||
# POSTCHECK: Addrs: [
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR3:]]
|
||||
# POSTCHECK-NEXT: 0x[[#%.16x,ADDR4:]]
|
||||
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: (indexed (0x0)
|
||||
# POSTCHECK-SAME: rangelist = 0x00000018
|
||||
# POSTCHECK-NEXT: [
|
||||
# POSTCHECK-SAME: 0x[[#ADDR]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR + 7]]
|
||||
# POSTCHECK-NEXT: [
|
||||
# POSTCHECK-SAME: 0x[[#ADDR1]]
|
||||
# POSTCHECK-SAME: 0x[[#ADDR1 + 12]]
|
||||
# POSTCHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
|
||||
# POSTCHECK-NEXT: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# POSTCHECK-NEXT: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# POSTCHECK-EMPTY
|
||||
# POSTCHECK: DW_TAG_subprogram
|
||||
# POSTCHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# POSTCHECK-SAME: indexed (00000002)
|
||||
# POSTCHECK-SAME: address = 0x0000000000000000
|
||||
# POSTCHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: indexed (0x1)
|
||||
# POSTCHECK-SAME: rangelist = 0x0000001f
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR]], 0x[[#ADDR + 7]])
|
||||
|
||||
# POSTCHECK: DW_TAG_subprogram
|
||||
# POSTCHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# POSTCHECK-SAME: indexed (00000002)
|
||||
# POSTCHECK-SAME: address = 0x0000000000000000
|
||||
# POSTCHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: indexed (0x2)
|
||||
# POSTCHECK-SAME: rangelist = 0x00000023
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR1]], 0x[[#ADDR1 + 12]])
|
||||
|
||||
# Checking second CU
|
||||
# POSTCHECK: version = 0x0005
|
||||
# POSTCHECK: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: (indexed (0x0)
|
||||
# POSTCHECK-SAME: rangelist = 0x00000043
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR3]], 0x[[#ADDR3 + 4]])
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR4]], 0x[[#ADDR4 + 4]])
|
||||
# POSTCHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000030)
|
||||
# POSTCHECK-NEXT: DW_AT_loclists_base [DW_FORM_sec_offset] (0x00000043)
|
||||
# POSTCHECK-NEXT: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x00000033)
|
||||
# POSTCHECK-EMPTY
|
||||
|
||||
# POSTCHECK: DW_TAG_subprogram
|
||||
# POSTCHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# POSTCHECK-SAME: indexed (00000002)
|
||||
# POSTCHECK-SAME: address = 0x0000000000000000
|
||||
# POSTCHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: indexed (0x1)
|
||||
# POSTCHECK-SAME: rangelist = 0x0000004a
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR3]], 0x[[#ADDR3 + 4]])
|
||||
# POSTCHECK: DW_TAG_subprogram
|
||||
# POSTCHECK: DW_TAG_subprogram
|
||||
# POSTCHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# POSTCHECK-SAME: indexed (00000002)
|
||||
# POSTCHECK-SAME: address = 0x0000000000000000
|
||||
# POSTCHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: indexed (0x2)
|
||||
# POSTCHECK-SAME: rangelist = 0x0000004e
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR4]], 0x[[#ADDR4 + 4]])
|
||||
|
||||
# POSTCHECK: DW_TAG_inlined_subroutine
|
||||
# POSTCHECK-NEXT: DW_AT_abstract_origin
|
||||
# POSTCHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx]
|
||||
# POSTCHECK-SAME: indexed (00000002)
|
||||
# POSTCHECK-SAME: address = 0x0000000000000000
|
||||
# POSTCHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK-SAME: indexed (0x3)
|
||||
# POSTCHECK-SAME: rangelist = 0x00000052
|
||||
# POSTCHECK-NEXT: [0x[[#ADDR4]], 0x[[#ADDR4 + 3]])
|
|
@ -0,0 +1,158 @@
|
|||
# REQUIRES: system-linux
|
||||
|
||||
# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
|
||||
# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
|
||||
# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s
|
||||
|
||||
# This test checks we correctly insert DW_AT_addr_base, when converting DW_AT_low_pc into DW_AT_ranges.
|
||||
# PRECHECK-NOT: DW_AT_addr_base
|
||||
|
||||
# POSTCHECK: DW_AT_ranges [DW_FORM_rnglistx]
|
||||
# POSTCHECK: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c)
|
||||
# POSTCHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
|
||||
|
||||
# int main() {
|
||||
# return 0;
|
||||
# }
|
||||
|
||||
|
||||
.file "main.cpp"
|
||||
.text
|
||||
.Ltext0:
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB0:
|
||||
.file 1 "main.cpp"
|
||||
.loc 1 1 12
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
.loc 1 2 10
|
||||
movl $0, %eax
|
||||
.loc 1 3 1
|
||||
popq %rbp
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size main, .-main
|
||||
.Letext0:
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0x50
|
||||
.value 0x5
|
||||
.byte 0x1
|
||||
.byte 0x8
|
||||
.long .Ldebug_abbrev0
|
||||
.uleb128 0x1
|
||||
.long .LASF0
|
||||
.byte 0x21
|
||||
.long .LASF1
|
||||
.long .LASF2
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.long .Ldebug_line0
|
||||
.uleb128 0x2
|
||||
.long .LASF3
|
||||
.byte 0x1
|
||||
.byte 0x1
|
||||
.byte 0x5
|
||||
.long 0x4c
|
||||
.quad .LFB0
|
||||
.quad .LFE0-.LFB0
|
||||
.uleb128 0x1
|
||||
.byte 0x9c
|
||||
.uleb128 0x3
|
||||
.byte 0x4
|
||||
.byte 0x5
|
||||
.string "int"
|
||||
.byte 0
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.Ldebug_abbrev0:
|
||||
.uleb128 0x1
|
||||
.uleb128 0x11
|
||||
.byte 0x1
|
||||
.uleb128 0x25
|
||||
.uleb128 0xe
|
||||
.uleb128 0x13
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x1b
|
||||
.uleb128 0xe
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x10
|
||||
.uleb128 0x17
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x2
|
||||
.uleb128 0x2e
|
||||
.byte 0
|
||||
.uleb128 0x3f
|
||||
.uleb128 0x19
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x40
|
||||
.uleb128 0x18
|
||||
.uleb128 0x7a
|
||||
.uleb128 0x19
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0x24
|
||||
.byte 0
|
||||
.uleb128 0xb
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3e
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0x8
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.section .debug_aranges,"",@progbits
|
||||
.long 0x2c
|
||||
.value 0x2
|
||||
.long .Ldebug_info0
|
||||
.byte 0x8
|
||||
.byte 0
|
||||
.value 0
|
||||
.value 0
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.quad 0
|
||||
.quad 0
|
||||
.section .debug_line,"",@progbits
|
||||
.Ldebug_line0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.LASF0:
|
||||
.string "GNU C++14 8.5.0 20210514 (Red Hat 8.5.0-3) -mtune=generic -march=x86-64 -g2 -gdwarf-5"
|
||||
.LASF1:
|
||||
.string "main.cpp"
|
||||
.LASF3:
|
||||
.string "main"
|
||||
.LASF2:
|
||||
.string "."
|
||||
.ident "GCC: (GNU) 8.5.0 20210514 (Red Hat 8.5.0-3)"
|
||||
.section .note.GNU-stack,"",@progbits
|
|
@ -3,18 +3,18 @@
|
|||
# DW_TAG_compile_unit->DW_AT_stmt_list where the DW_AT_decl_file is located (and
|
||||
# not where the DW_AT_abstract_origin is located).
|
||||
# DW_TAG_variable in CU 1 is using DW_AT_decl_file 3.
|
||||
# CU 1 has files:
|
||||
# CU 1 has files:
|
||||
# file_names[ 1]: name: "inlinevarother.h"
|
||||
# file_names[ 2]: name: "inlinevar1.c"
|
||||
# file_names[ 3]: name: "inlinevar.h"
|
||||
# CU 2 has files:
|
||||
# CU 2 has files:
|
||||
# file_names[ 1]: name: "inlinevar2.c"
|
||||
# file_names[ 2]: name: "inlinevar.h"
|
||||
|
||||
# UNSUPPORTED: system-darwin, system-windows
|
||||
# REQUIRES: target-x86_64
|
||||
|
||||
# RUN: %clang_host -o %t %s \
|
||||
# RUN: %clang_host -gdwarf-4 -o %t %s \
|
||||
# RUN: %S/Inputs/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu2.s
|
||||
|
||||
# RUN: %lldb %t \
|
||||
|
@ -36,7 +36,7 @@ main: # @main
|
|||
.Ltmp2:
|
||||
.file 3 "" "./inlinevar.h"
|
||||
.loc 3 2 16 prologue_end # ./inlinevar.h:2:16
|
||||
movl $42, %eax
|
||||
movl $42, %eax
|
||||
pushq %rax
|
||||
.loc 3 3 10 # ./inlinevar.h:3:10
|
||||
.Ltmp3:
|
||||
|
|
Loading…
Reference in New Issue