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 *>;
|
using DWOIdToCUMapType = std::unordered_map<uint64_t, DWARFUnit *>;
|
||||||
DWOIdToCUMapType DWOCUs;
|
DWOIdToCUMapType DWOCUs;
|
||||||
|
|
||||||
|
bool ContainsDwarf5{false};
|
||||||
|
bool ContainsDwarfLegacy{false};
|
||||||
|
|
||||||
/// Preprocess DWO debug information.
|
/// Preprocess DWO debug information.
|
||||||
void preprocessDWODebugInfo();
|
void preprocessDWODebugInfo();
|
||||||
|
|
||||||
|
@ -234,7 +237,13 @@ public:
|
||||||
/// Get Number of DWOCUs in a map.
|
/// Get Number of DWOCUs in a map.
|
||||||
uint32_t getNumDWOCUs() { return DWOCUs.size(); }
|
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;
|
return DwarfLineTablesCUMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +254,8 @@ public:
|
||||||
Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName,
|
Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName,
|
||||||
unsigned FileNumber,
|
unsigned FileNumber,
|
||||||
Optional<MD5::MD5Result> Checksum,
|
Optional<MD5::MD5Result> Checksum,
|
||||||
Optional<StringRef> Source, unsigned CUID);
|
Optional<StringRef> Source, unsigned CUID,
|
||||||
|
unsigned DWARFVersion);
|
||||||
|
|
||||||
/// [start memory address] -> [segment info] mapping.
|
/// [start memory address] -> [segment info] mapping.
|
||||||
std::map<uint64_t, SegmentInfo> SegmentMapInfo;
|
std::map<uint64_t, SegmentInfo> SegmentMapInfo;
|
||||||
|
|
|
@ -34,6 +34,21 @@ namespace llvm {
|
||||||
|
|
||||||
namespace bolt {
|
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;
|
class BinaryContext;
|
||||||
|
|
||||||
/// Address range representation. Takes less space than DWARFAddressRange.
|
/// Address range representation. Takes less space than DWARFAddressRange.
|
||||||
|
@ -114,18 +129,23 @@ struct CUInfo {
|
||||||
};
|
};
|
||||||
using CUOffsetMap = std::map<uint32_t, CUInfo>;
|
using CUOffsetMap = std::map<uint32_t, CUInfo>;
|
||||||
|
|
||||||
|
enum class RangesWriterKind { DebugRangesWriter, DebugRangeListsWriter };
|
||||||
/// Serializes the .debug_ranges DWARF section.
|
/// Serializes the .debug_ranges DWARF section.
|
||||||
class DebugRangesSectionWriter {
|
class DebugRangesSectionWriter {
|
||||||
public:
|
public:
|
||||||
DebugRangesSectionWriter();
|
DebugRangesSectionWriter();
|
||||||
|
|
||||||
|
DebugRangesSectionWriter(RangesWriterKind K) : Kind(K){};
|
||||||
|
|
||||||
|
virtual ~DebugRangesSectionWriter(){};
|
||||||
|
|
||||||
/// Add ranges with caching.
|
/// Add ranges with caching.
|
||||||
uint64_t
|
virtual uint64_t
|
||||||
addRanges(DebugAddressRangesVector &&Ranges,
|
addRanges(DebugAddressRangesVector &&Ranges,
|
||||||
std::map<DebugAddressRangesVector, uint64_t> &CachedRanges);
|
std::map<DebugAddressRangesVector, uint64_t> &CachedRanges);
|
||||||
|
|
||||||
/// Add ranges and return offset into section.
|
/// 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
|
/// Returns an offset of an empty address ranges list that is always written
|
||||||
/// to .debug_ranges
|
/// to .debug_ranges
|
||||||
|
@ -134,11 +154,18 @@ public:
|
||||||
/// Returns the SectionOffset.
|
/// Returns the SectionOffset.
|
||||||
uint64_t getSectionOffset();
|
uint64_t getSectionOffset();
|
||||||
|
|
||||||
std::unique_ptr<DebugBufferVector> finalize() {
|
/// Returns a buffer containing Ranges.
|
||||||
|
virtual std::unique_ptr<DebugBufferVector> finalize() {
|
||||||
return std::move(RangesBuffer);
|
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<DebugBufferVector> RangesBuffer;
|
||||||
|
|
||||||
std::unique_ptr<raw_svector_ostream> RangesStream;
|
std::unique_ptr<raw_svector_ostream> RangesStream;
|
||||||
|
@ -151,6 +178,58 @@ private:
|
||||||
|
|
||||||
/// Offset of an empty address ranges list.
|
/// Offset of an empty address ranges list.
|
||||||
static constexpr uint64_t EmptyRangesOffset{0};
|
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.
|
/// Serializes the .debug_aranges DWARF section.
|
||||||
|
@ -193,23 +272,25 @@ class DebugAddrWriter {
|
||||||
public:
|
public:
|
||||||
DebugAddrWriter() = delete;
|
DebugAddrWriter() = delete;
|
||||||
DebugAddrWriter(BinaryContext *BC_);
|
DebugAddrWriter(BinaryContext *BC_);
|
||||||
|
virtual ~DebugAddrWriter(){};
|
||||||
/// Given an address returns an index in .debug_addr.
|
/// Given an address returns an index in .debug_addr.
|
||||||
/// Adds Address to map.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// Given DWARFUnit \p Unit returns offset of this CU in to .debug_addr
|
||||||
uint64_t getOffset(uint64_t DWOId);
|
/// section.
|
||||||
|
virtual uint64_t getOffset(DWARFUnit &Unit);
|
||||||
|
|
||||||
/// Returns False if .debug_addr section was created..
|
/// Returns False if .debug_addr section was created..
|
||||||
bool isInitialized() const { return !AddressMaps.empty(); }
|
bool isInitialized() const { return !AddressMaps.empty(); }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
class AddressForDWOCU {
|
class AddressForDWOCU {
|
||||||
public:
|
public:
|
||||||
AddressToIndexMap::iterator find(uint64_t Adddress) {
|
AddressToIndexMap::iterator find(uint64_t Adddress) {
|
||||||
|
@ -266,6 +347,18 @@ private:
|
||||||
std::mutex WriterMutex;
|
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>;
|
using DebugStrBufferVector = SmallVector<char, 16>;
|
||||||
class DebugStrWriter {
|
class DebugStrWriter {
|
||||||
public:
|
public:
|
||||||
|
@ -305,7 +398,8 @@ public:
|
||||||
virtual ~DebugLocWriter(){};
|
virtual ~DebugLocWriter(){};
|
||||||
|
|
||||||
/// Writes out location lists and stores internal patches.
|
/// 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.
|
/// Writes out locations in to a local buffer, and adds Debug Info patches.
|
||||||
virtual void finalize(uint64_t SectionOffset,
|
virtual void finalize(uint64_t SectionOffset,
|
||||||
|
@ -314,6 +408,9 @@ public:
|
||||||
/// Return internal buffer.
|
/// Return internal buffer.
|
||||||
virtual std::unique_ptr<DebugBufferVector> getBuffer();
|
virtual std::unique_ptr<DebugBufferVector> getBuffer();
|
||||||
|
|
||||||
|
/// Returns DWARF version.
|
||||||
|
uint8_t getDwarfVersion() const { return DwarfVersion; }
|
||||||
|
|
||||||
/// Offset of an empty location list.
|
/// Offset of an empty location list.
|
||||||
static constexpr uint32_t EmptyListOffset = 0;
|
static constexpr uint32_t EmptyListOffset = 0;
|
||||||
|
|
||||||
|
@ -325,13 +422,13 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<DebugBufferVector> LocBuffer;
|
std::unique_ptr<DebugBufferVector> LocBuffer;
|
||||||
|
|
||||||
std::unique_ptr<raw_svector_ostream> LocStream;
|
std::unique_ptr<raw_svector_ostream> LocStream;
|
||||||
/// Current offset in the section (updated as new entries are written).
|
/// 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
|
/// 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
|
/// section. In the final section, the first 16 bytes are reserved for an
|
||||||
/// empty list.
|
/// empty list.
|
||||||
uint32_t SectionOffset{0};
|
uint32_t SectionOffset{0};
|
||||||
|
uint8_t DwarfVersion{4};
|
||||||
LocWriterKind Kind{LocWriterKind::DebugLocWriter};
|
LocWriterKind Kind{LocWriterKind::DebugLocWriter};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -354,9 +451,12 @@ class DebugLoclistWriter : public DebugLocWriter {
|
||||||
public:
|
public:
|
||||||
~DebugLoclistWriter() {}
|
~DebugLoclistWriter() {}
|
||||||
DebugLoclistWriter() = delete;
|
DebugLoclistWriter() = delete;
|
||||||
DebugLoclistWriter(BinaryContext *BC, uint64_t DWOId_)
|
DebugLoclistWriter(BinaryContext *BC, uint64_t CID,
|
||||||
: DebugLocWriter(BC), DWOId(DWOId_) {
|
uint32_t LocListsBaseAttrOffset, uint8_t DV, bool SD)
|
||||||
|
: DebugLocWriter(BC), CUID(CID),
|
||||||
|
LocListsBaseAttrOffset(LocListsBaseAttrOffset), IsSplitDwarf(SD) {
|
||||||
Kind = LocWriterKind::DebugLoclistWriter;
|
Kind = LocWriterKind::DebugLoclistWriter;
|
||||||
|
DwarfVersion = DV;
|
||||||
assert(DebugLoclistWriter::AddrWriter &&
|
assert(DebugLoclistWriter::AddrWriter &&
|
||||||
"Please use SetAddressWriter to initialize "
|
"Please use SetAddressWriter to initialize "
|
||||||
"DebugAddrWriter before instantiation.");
|
"DebugAddrWriter before instantiation.");
|
||||||
|
@ -365,7 +465,7 @@ public:
|
||||||
static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
|
static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
|
||||||
|
|
||||||
/// Stores location lists internally to be written out during finalize phase.
|
/// 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;
|
DebugLocationsVector &&LocList) override;
|
||||||
|
|
||||||
/// Writes out locations in to a local buffer and applies debug info patches.
|
/// Writes out locations in to a local buffer and applies debug info patches.
|
||||||
|
@ -373,15 +473,31 @@ public:
|
||||||
SimpleBinaryPatcher &DebugInfoPatcher) override;
|
SimpleBinaryPatcher &DebugInfoPatcher) override;
|
||||||
|
|
||||||
/// Returns DWO ID.
|
/// 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) {
|
static bool classof(const DebugLocWriter *Writer) {
|
||||||
return Writer->getKind() == LocWriterKind::DebugLoclistWriter;
|
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:
|
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 {
|
struct LocPatch {
|
||||||
uint64_t AttrOffset{0};
|
uint64_t AttrOffset{0};
|
||||||
|
uint32_t Index;
|
||||||
DebugLocationsVector LocList;
|
DebugLocationsVector LocList;
|
||||||
};
|
};
|
||||||
using LocPatchVec = SmallVector<LocPatch, 4>;
|
using LocPatchVec = SmallVector<LocPatch, 4>;
|
||||||
|
@ -395,7 +511,9 @@ private:
|
||||||
uint64_t Address{0};
|
uint64_t Address{0};
|
||||||
};
|
};
|
||||||
static DebugAddrWriter *AddrWriter;
|
static DebugAddrWriter *AddrWriter;
|
||||||
uint64_t DWOId{0};
|
uint64_t CUID{0};
|
||||||
|
uint32_t LocListsBaseAttrOffset{InvalidLocListsBaseAttrOffset};
|
||||||
|
bool IsSplitDwarf{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PatcherKind { SimpleBinaryPatcher, DebugInfoBinaryPatcher };
|
enum class PatcherKind { SimpleBinaryPatcher, DebugInfoBinaryPatcher };
|
||||||
|
@ -914,6 +1032,9 @@ private:
|
||||||
/// Raw data representing complete debug line section for the unit.
|
/// Raw data representing complete debug line section for the unit.
|
||||||
StringRef RawData;
|
StringRef RawData;
|
||||||
|
|
||||||
|
/// DWARF Version
|
||||||
|
uint16_t DwarfVersion;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Emit line info for all units in the binary context.
|
/// Emit line info for all units in the binary context.
|
||||||
static void emit(BinaryContext &BC, MCStreamer &Streamer);
|
static void emit(BinaryContext &BC, MCStreamer &Streamer);
|
||||||
|
@ -937,6 +1058,14 @@ public:
|
||||||
|
|
||||||
void setLabel(MCSymbol *Label) { Header.Label = Label; }
|
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.
|
/// Access to MC line info.
|
||||||
MCLineSection &getMCLineSections() { return MCLineSections; }
|
MCLineSection &getMCLineSections() { return MCLineSections; }
|
||||||
|
|
||||||
|
@ -956,6 +1085,12 @@ public:
|
||||||
void addRawContents(StringRef DebugLineContents) {
|
void addRawContents(StringRef DebugLineContents) {
|
||||||
RawData = 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 {
|
struct AttrInfo {
|
||||||
|
|
|
@ -51,8 +51,7 @@ class DWARFRewriter {
|
||||||
/// .debug_abbrev section writer for the main binary.
|
/// .debug_abbrev section writer for the main binary.
|
||||||
std::unique_ptr<DebugAbbrevWriter> AbbrevWriter;
|
std::unique_ptr<DebugAbbrevWriter> AbbrevWriter;
|
||||||
|
|
||||||
using LocWriters =
|
using LocWriters = std::map<uint64_t, std::unique_ptr<DebugLocWriter>>;
|
||||||
std::unordered_map<uint64_t, std::unique_ptr<DebugLocWriter>>;
|
|
||||||
/// Use a separate location list writer for each compilation unit
|
/// Use a separate location list writer for each compilation unit
|
||||||
LocWriters LocListWritersByCU;
|
LocWriters LocListWritersByCU;
|
||||||
|
|
||||||
|
@ -68,11 +67,15 @@ class DWARFRewriter {
|
||||||
|
|
||||||
std::mutex LocListDebugInfoPatchesMutex;
|
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.
|
/// Update debug info for all DIEs in \p Unit.
|
||||||
void updateUnitDebugInfo(DWARFUnit &Unit,
|
void updateUnitDebugInfo(DWARFUnit &Unit,
|
||||||
DebugInfoBinaryPatcher &DebugInfoPatcher,
|
DebugInfoBinaryPatcher &DebugInfoPatcher,
|
||||||
DebugAbbrevWriter &AbbrevWriter,
|
DebugAbbrevWriter &AbbrevWriter,
|
||||||
DebugLocWriter &DebugLocWriter,
|
DebugLocWriter &DebugLocWriter,
|
||||||
|
DebugRangesSectionWriter &RangesWriter,
|
||||||
Optional<uint64_t> RangesBase = None);
|
Optional<uint64_t> RangesBase = None);
|
||||||
|
|
||||||
/// Patches the binary for an object's address ranges to be updated.
|
/// Patches the binary for an object's address ranges to be updated.
|
||||||
|
@ -91,7 +94,8 @@ class DWARFRewriter {
|
||||||
Optional<uint64_t> RangesBase = None);
|
Optional<uint64_t> RangesBase = None);
|
||||||
|
|
||||||
std::unique_ptr<DebugBufferVector>
|
std::unique_ptr<DebugBufferVector>
|
||||||
makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher);
|
makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher,
|
||||||
|
DWARFVersion Version);
|
||||||
|
|
||||||
/// Finalize debug sections in the main binary.
|
/// Finalize debug sections in the main binary.
|
||||||
CUOffsetMap finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher);
|
CUOffsetMap finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher);
|
||||||
|
|
|
@ -1325,14 +1325,13 @@ void BinaryContext::printGlobalSymbols(raw_ostream &OS) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<unsigned>
|
Expected<unsigned> BinaryContext::getDwarfFile(
|
||||||
BinaryContext::getDwarfFile(StringRef Directory, StringRef FileName,
|
StringRef Directory, StringRef FileName, unsigned FileNumber,
|
||||||
unsigned FileNumber,
|
Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source,
|
||||||
Optional<MD5::MD5Result> Checksum,
|
unsigned CUID, unsigned DWARFVersion) {
|
||||||
Optional<StringRef> Source, unsigned CUID) {
|
|
||||||
DwarfLineTable &Table = DwarfLineTablesCUMap[CUID];
|
DwarfLineTable &Table = DwarfLineTablesCUMap[CUID];
|
||||||
return Table.tryGetFile(Directory, FileName, Checksum, Source,
|
return Table.tryGetFile(Directory, FileName, Checksum, Source, DWARFVersion,
|
||||||
Ctx->getDwarfVersion(), FileNumber);
|
FileNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
|
unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
|
||||||
|
@ -1360,7 +1359,9 @@ unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
|
||||||
dwarf::toString(FileNames[FileIndex - 1].Name))
|
dwarf::toString(FileNames[FileIndex - 1].Name))
|
||||||
FileName = *FName;
|
FileName = *FName;
|
||||||
assert(FileName != "");
|
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() {
|
std::vector<BinaryFunction *> BinaryContext::getSortedFunctions() {
|
||||||
|
@ -1458,8 +1459,15 @@ void BinaryContext::preprocessDebugInfo() {
|
||||||
if (containsAddress(Range.LowPC))
|
if (containsAddress(Range.LowPC))
|
||||||
AllRanges.emplace_back(CURange{Range.LowPC, Range.HighPC, CU.get()});
|
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());
|
std::sort(AllRanges.begin(), AllRanges.end());
|
||||||
for (auto &KV : BinaryFunctions) {
|
for (auto &KV : BinaryFunctions) {
|
||||||
const uint64_t FunctionAddress = KV.first;
|
const uint64_t FunctionAddress = KV.first;
|
||||||
|
@ -1496,7 +1504,8 @@ void BinaryContext::preprocessDebugInfo() {
|
||||||
StringRef GlobalPrefix = AsmInfo->getPrivateGlobalPrefix();
|
StringRef GlobalPrefix = AsmInfo->getPrivateGlobalPrefix();
|
||||||
for (const std::unique_ptr<DWARFUnit> &CU : DwCtx->compile_units()) {
|
for (const std::unique_ptr<DWARFUnit> &CU : DwCtx->compile_units()) {
|
||||||
const uint64_t CUID = CU->getOffset();
|
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)));
|
GlobalPrefix + "line_table_start" + Twine(CUID)));
|
||||||
|
|
||||||
if (!ProcessedCUs.count(CU.get()))
|
if (!ProcessedCUs.count(CU.get()))
|
||||||
|
@ -1507,26 +1516,45 @@ void BinaryContext::preprocessDebugInfo() {
|
||||||
const std::vector<DWARFDebugLine::FileNameEntry> &FileNames =
|
const std::vector<DWARFDebugLine::FileNameEntry> &FileNames =
|
||||||
LineTable->Prologue.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.
|
// Assign a unique label to every line table, one per CU.
|
||||||
// Make sure empty debug line tables are registered too.
|
// Make sure empty debug line tables are registered too.
|
||||||
if (FileNames.empty()) {
|
if (FileNames.empty()) {
|
||||||
cantFail(getDwarfFile("", "<unknown>", 0, None, None, CUID));
|
cantFail(
|
||||||
|
getDwarfFile("", "<unknown>", 0, None, None, CUID, DwarfVersion));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
const uint32_t Offset = DwarfVersion < 5 ? 1 : 0;
|
||||||
for (size_t I = 0, Size = FileNames.size(); I != Size; ++I) {
|
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
|
// Dir indexes start at 1, as DWARF file numbers, and a dir index 0
|
||||||
// means empty dir.
|
// means empty dir.
|
||||||
StringRef Dir = "";
|
StringRef Dir = "";
|
||||||
if (FileNames[I].DirIdx != 0)
|
if (FileNames[I].DirIdx != 0 || DwarfVersion >= 5)
|
||||||
if (Optional<const char *> DirName = dwarf::toString(
|
if (Optional<const char *> DirName = dwarf::toString(
|
||||||
LineTable->Prologue
|
LineTable->Prologue
|
||||||
.IncludeDirectories[FileNames[I].DirIdx - 1]))
|
.IncludeDirectories[FileNames[I].DirIdx - Offset]))
|
||||||
Dir = *DirName;
|
Dir = *DirName;
|
||||||
StringRef FileName = "";
|
StringRef FileName = "";
|
||||||
if (Optional<const char *> FName = dwarf::toString(FileNames[I].Name))
|
if (Optional<const char *> FName = dwarf::toString(FileNames[I].Name))
|
||||||
FileName = *FName;
|
FileName = *FName;
|
||||||
assert(FileName != "");
|
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/DebugData.h"
|
||||||
#include "bolt/Core/BinaryContext.h"
|
#include "bolt/Core/BinaryContext.h"
|
||||||
|
#include "bolt/Rewrite/RewriteInstance.h"
|
||||||
#include "bolt/Utils/Utils.h"
|
#include "bolt/Utils/Utils.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
|
||||||
#include "llvm/MC/MCAssembler.h"
|
#include "llvm/MC/MCAssembler.h"
|
||||||
#include "llvm/MC/MCContext.h"
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/MC/MCObjectStreamer.h"
|
#include "llvm/MC/MCObjectStreamer.h"
|
||||||
|
@ -118,6 +120,7 @@ DebugRangesSectionWriter::DebugRangesSectionWriter() {
|
||||||
// Add an empty range as the first entry;
|
// Add an empty range as the first entry;
|
||||||
SectionOffset +=
|
SectionOffset +=
|
||||||
writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
|
writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
|
||||||
|
Kind = RangesWriterKind::DebugRangesWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DebugRangesSectionWriter::addRanges(
|
uint64_t DebugRangesSectionWriter::addRanges(
|
||||||
|
@ -155,6 +158,94 @@ uint64_t DebugRangesSectionWriter::getSectionOffset() {
|
||||||
return SectionOffset;
|
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,
|
void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
|
||||||
DebugAddressRangesVector &&Ranges) {
|
DebugAddressRangesVector &&Ranges) {
|
||||||
std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
|
std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
|
||||||
|
@ -220,13 +311,12 @@ void DebugAddrWriter::AddressForDWOCU::dump() {
|
||||||
for (auto &Pair : SortedMap)
|
for (auto &Pair : SortedMap)
|
||||||
dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
|
dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
|
||||||
}
|
}
|
||||||
uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address,
|
uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, uint64_t CUID) {
|
||||||
uint64_t DWOId) {
|
|
||||||
std::lock_guard<std::mutex> Lock(WriterMutex);
|
std::lock_guard<std::mutex> Lock(WriterMutex);
|
||||||
if (!AddressMaps.count(DWOId))
|
if (!AddressMaps.count(CUID))
|
||||||
AddressMaps[DWOId] = AddressForDWOCU();
|
AddressMaps[CUID] = AddressForDWOCU();
|
||||||
|
|
||||||
AddressForDWOCU &Map = AddressMaps[DWOId];
|
AddressForDWOCU &Map = AddressMaps[CUID];
|
||||||
auto Entry = Map.find(Address);
|
auto Entry = Map.find(Address);
|
||||||
if (Entry == Map.end()) {
|
if (Entry == Map.end()) {
|
||||||
auto Index = Map.getNextIndex();
|
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
|
// IndexToAddrss. Case3) Address is in the map but Index is lower. Need to
|
||||||
// update AddressToIndex and IndexToAddress
|
// update AddressToIndex and IndexToAddress
|
||||||
void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index,
|
void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index,
|
||||||
uint64_t DWOId) {
|
uint64_t CUID) {
|
||||||
std::lock_guard<std::mutex> Lock(WriterMutex);
|
std::lock_guard<std::mutex> Lock(WriterMutex);
|
||||||
AddressForDWOCU &Map = AddressMaps[DWOId];
|
AddressForDWOCU &Map = AddressMaps[CUID];
|
||||||
auto Entry = Map.find(Address);
|
auto Entry = Map.find(Address);
|
||||||
if (Entry != Map.end()) {
|
if (Entry != Map.end()) {
|
||||||
if (Entry->second > Index)
|
if (Entry->second > Index)
|
||||||
|
@ -265,6 +355,7 @@ AddressSectionBuffer DebugAddrWriter::finalize() {
|
||||||
if (!DWOId)
|
if (!DWOId)
|
||||||
continue;
|
continue;
|
||||||
auto AM = AddressMaps.find(*DWOId);
|
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.
|
// Adding to map even if it did not contribute to .debug_addr.
|
||||||
// The Skeleton CU will still have DW_AT_GNU_addr_base.
|
// The Skeleton CU will still have DW_AT_GNU_addr_base.
|
||||||
DWOIdToOffsetMap[*DWOId] = Buffer.size();
|
DWOIdToOffsetMap[*DWOId] = Buffer.size();
|
||||||
|
@ -306,9 +397,97 @@ AddressSectionBuffer DebugAddrWriter::finalize() {
|
||||||
|
|
||||||
return Buffer;
|
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) {
|
DWOIdToOffsetMap[CUID] = Buffer.size() + HeaderSize;
|
||||||
auto Iter = DWOIdToOffsetMap.find(DWOId);
|
|
||||||
|
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() &&
|
assert(Iter != DWOIdToOffsetMap.end() &&
|
||||||
"Offset in to.debug_addr was not found for DWO ID.");
|
"Offset in to.debug_addr was not found for DWO ID.");
|
||||||
return Iter->second;
|
return Iter->second;
|
||||||
|
@ -319,7 +498,7 @@ DebugLocWriter::DebugLocWriter(BinaryContext *BC) {
|
||||||
LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
|
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) {
|
DebugLocationsVector &&LocList) {
|
||||||
if (LocList.empty()) {
|
if (LocList.empty()) {
|
||||||
EmptyAttrLists.push_back(AttrOffset);
|
EmptyAttrLists.push_back(AttrOffset);
|
||||||
|
@ -345,9 +524,9 @@ void DebugLocWriter::addList(uint64_t AttrOffset,
|
||||||
LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset});
|
LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLoclistWriter::addList(uint64_t AttrOffset,
|
void DebugLoclistWriter::addList(uint64_t AttrOffset, uint32_t LocListIndex,
|
||||||
DebugLocationsVector &&LocList) {
|
DebugLocationsVector &&LocList) {
|
||||||
Patches.push_back({AttrOffset, std::move(LocList)});
|
Patches.push_back({AttrOffset, LocListIndex, std::move(LocList)});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() {
|
std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() {
|
||||||
|
@ -368,8 +547,95 @@ void DebugLocWriter::finalize(uint64_t SectionOffset,
|
||||||
DebugLocWriter::EmptyListOffset);
|
DebugLocWriter::EmptyListOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
static void writeEmptyListDwarf5(raw_svector_ostream &Stream) {
|
||||||
SimpleBinaryPatcher &DebugInfoPatcher) {
|
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) {
|
for (LocPatch &Patch : Patches) {
|
||||||
if (Patch.LocList.empty()) {
|
if (Patch.LocList.empty()) {
|
||||||
DebugInfoPatcher.addLE32Patch(Patch.AttrOffset,
|
DebugInfoPatcher.addLE32Patch(Patch.AttrOffset,
|
||||||
|
@ -381,7 +647,7 @@ void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
||||||
support::endian::write(*LocStream,
|
support::endian::write(*LocStream,
|
||||||
static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
|
static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
|
||||||
support::little);
|
support::little);
|
||||||
uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, DWOId);
|
const uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, CUID);
|
||||||
encodeULEB128(Index, *LocStream);
|
encodeULEB128(Index, *LocStream);
|
||||||
|
|
||||||
// TODO: Support DWARF5
|
// TODO: Support DWARF5
|
||||||
|
@ -403,6 +669,14 @@ void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
||||||
clearList(Patches);
|
clearList(Patches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugLoclistWriter::finalize(uint64_t SectionOffset,
|
||||||
|
SimpleBinaryPatcher &DebugInfoPatcher) {
|
||||||
|
if (DwarfVersion < 5)
|
||||||
|
finalizeDWARFLegacy(SectionOffset, DebugInfoPatcher);
|
||||||
|
else
|
||||||
|
finalizeDWARF5(SectionOffset, DebugInfoPatcher);
|
||||||
|
}
|
||||||
|
|
||||||
DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
|
DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
|
||||||
|
|
||||||
void DebugInfoBinaryPatcher::addUnitBaseOffsetLabel(uint64_t Offset) {
|
void DebugInfoBinaryPatcher::addUnitBaseOffsetLabel(uint64_t Offset) {
|
||||||
|
@ -1154,7 +1428,7 @@ static inline void emitDwarfLineTable(
|
||||||
MCOS->emitULEB128IntValue(Column);
|
MCOS->emitULEB128IntValue(Column);
|
||||||
}
|
}
|
||||||
if (Discriminator != LineEntry.getDiscriminator() &&
|
if (Discriminator != LineEntry.getDiscriminator() &&
|
||||||
MCOS->getContext().getDwarfVersion() >= 4) {
|
MCOS->getContext().getDwarfVersion() >= 2) {
|
||||||
Discriminator = LineEntry.getDiscriminator();
|
Discriminator = LineEntry.getDiscriminator();
|
||||||
unsigned Size = getULEB128Size(Discriminator);
|
unsigned Size = getULEB128Size(Discriminator);
|
||||||
MCOS->emitInt8(dwarf::DW_LNS_extended_op);
|
MCOS->emitInt8(dwarf::DW_LNS_extended_op);
|
||||||
|
@ -1228,6 +1502,31 @@ void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
|
||||||
MCOS->emitLabel(LineEndSym);
|
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) {
|
void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
|
||||||
MCAssembler &Assembler =
|
MCAssembler &Assembler =
|
||||||
static_cast<MCObjectStreamer *>(&Streamer)->getAssembler();
|
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.
|
// in doing so create an unnecessary (if empty) section.
|
||||||
if (LineTables.empty())
|
if (LineTables.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// In a v5 non-split line table, put the strings in a separate section.
|
// In a v5 non-split line table, put the strings in a separate section.
|
||||||
Optional<MCDwarfLineStr> LineStr(None);
|
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);
|
LineStr = MCDwarfLineStr(*BC.Ctx);
|
||||||
|
parseAndPopulateDebugLineStr(*LineStrSection, *LineStr, BC, Streamer);
|
||||||
|
}
|
||||||
|
|
||||||
// Switch to the section where the table will be emitted into.
|
// Switch to the section where the table will be emitted into.
|
||||||
Streamer.SwitchSection(BC.MOFI->getDwarfLineSection());
|
Streamer.SwitchSection(BC.MOFI->getDwarfLineSection());
|
||||||
|
|
||||||
|
const uint16_t DwarfVersion = BC.Ctx->getDwarfVersion();
|
||||||
// Handle the rest of the Compile Units.
|
// Handle the rest of the Compile Units.
|
||||||
for (auto &CUIDTablePair : LineTables) {
|
for (auto &CUIDTablePair : LineTables) {
|
||||||
|
Streamer.getContext().setDwarfVersion(
|
||||||
|
CUIDTablePair.second.getDwarfVersion());
|
||||||
CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC);
|
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
|
} // namespace bolt
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
|
#include "llvm/Support/LEB128.h"
|
||||||
#include "llvm/Support/ThreadPool.h"
|
#include "llvm/Support/ThreadPool.h"
|
||||||
#include "llvm/Support/ToolOutputFile.h"
|
#include "llvm/Support/ToolOutputFile.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -72,6 +73,19 @@ static Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
|
||||||
return None;
|
return None;
|
||||||
return findAttributeInfo(DIE, AbbrevDecl, *Index);
|
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 bolt
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
|
@ -158,24 +172,40 @@ void DWARFRewriter::updateDebugInfo() {
|
||||||
static_cast<DebugInfoBinaryPatcher *>(DebugInfo->getPatcher());
|
static_cast<DebugInfoBinaryPatcher *>(DebugInfo->getPatcher());
|
||||||
|
|
||||||
ARangesSectionWriter = std::make_unique<DebugARangesSectionWriter>();
|
ARangesSectionWriter = std::make_unique<DebugARangesSectionWriter>();
|
||||||
RangesSectionWriter = std::make_unique<DebugRangesSectionWriter>();
|
|
||||||
StrWriter = std::make_unique<DebugStrWriter>(&BC);
|
StrWriter = std::make_unique<DebugStrWriter>(&BC);
|
||||||
AbbrevWriter = std::make_unique<DebugAbbrevWriter>(*BC.DwCtx);
|
AbbrevWriter = std::make_unique<DebugAbbrevWriter>(*BC.DwCtx);
|
||||||
|
|
||||||
AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
|
if (BC.isDWARF5Used()) {
|
||||||
DebugLoclistWriter::setAddressWriter(AddrWriter.get());
|
// Disabling none deterministic mode for dwarf5, to keep implementation
|
||||||
|
// simpler.
|
||||||
uint64_t NumCUs = BC.DwCtx->getNumCompileUnits();
|
opts::DeterministicDebugInfo = true;
|
||||||
if ((opts::NoThreads || opts::DeterministicDebugInfo) &&
|
AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
|
||||||
BC.getNumDWOCUs() == 0) {
|
RangesSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
|
||||||
// Use single entry for efficiency when running single-threaded
|
DebugRangeListsSectionWriter::setAddressWriter(AddrWriter.get());
|
||||||
NumCUs = 1;
|
} 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)
|
size_t CUIndex = 0;
|
||||||
LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>(&BC);
|
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
|
// Unordered maps to handle name collision if output DWO directory is
|
||||||
// specified.
|
// specified.
|
||||||
|
@ -185,8 +215,8 @@ void DWARFRewriter::updateDebugInfo() {
|
||||||
|
|
||||||
auto updateDWONameCompDir = [&](DWARFUnit &Unit) -> void {
|
auto updateDWONameCompDir = [&](DWARFUnit &Unit) -> void {
|
||||||
const DWARFDie &DIE = Unit.getUnitDIE();
|
const DWARFDie &DIE = Unit.getUnitDIE();
|
||||||
Optional<AttrInfo> AttrInfoVal =
|
Optional<AttrInfo> AttrInfoVal = findAttributeInfo(
|
||||||
findAttributeInfo(DIE, dwarf::DW_AT_GNU_dwo_name);
|
DIE, {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name});
|
||||||
(void)AttrInfoVal;
|
(void)AttrInfoVal;
|
||||||
assert(AttrInfoVal && "Skeleton CU doesn't have dwo_name.");
|
assert(AttrInfoVal && "Skeleton CU doesn't have dwo_name.");
|
||||||
|
|
||||||
|
@ -234,8 +264,8 @@ void DWARFRewriter::updateDebugInfo() {
|
||||||
std::lock_guard<std::mutex> Lock(AccessMutex);
|
std::lock_guard<std::mutex> Lock(AccessMutex);
|
||||||
DebugLocWriter =
|
DebugLocWriter =
|
||||||
LocListWritersByCU
|
LocListWritersByCU
|
||||||
.insert(
|
.insert({*DWOId, std::make_unique<DebugLoclistWriter>(
|
||||||
{*DWOId, std::make_unique<DebugLoclistWriter>(&BC, *DWOId)})
|
&BC, *DWOId, 0, Unit->getVersion(), true)})
|
||||||
.first->second.get();
|
.first->second.get();
|
||||||
}
|
}
|
||||||
DebugInfoBinaryPatcher *DwoDebugInfoPatcher =
|
DebugInfoBinaryPatcher *DwoDebugInfoPatcher =
|
||||||
|
@ -251,7 +281,7 @@ void DWARFRewriter::updateDebugInfo() {
|
||||||
DebugAbbrevWriter *DWOAbbrevWriter =
|
DebugAbbrevWriter *DWOAbbrevWriter =
|
||||||
createBinaryDWOAbbrevWriter((*SplitCU)->getContext(), *DWOId);
|
createBinaryDWOAbbrevWriter((*SplitCU)->getContext(), *DWOId);
|
||||||
updateUnitDebugInfo(*(*SplitCU), *DwoDebugInfoPatcher, *DWOAbbrevWriter,
|
updateUnitDebugInfo(*(*SplitCU), *DwoDebugInfoPatcher, *DWOAbbrevWriter,
|
||||||
*DebugLocWriter);
|
*DebugLocWriter, *RangesSectionWriter);
|
||||||
DwoDebugInfoPatcher->clearDestinationLabels();
|
DwoDebugInfoPatcher->clearDestinationLabels();
|
||||||
if (!DwoDebugInfoPatcher->getWasRangBasedUsed())
|
if (!DwoDebugInfoPatcher->getWasRangBasedUsed())
|
||||||
RangesBase = None;
|
RangesBase = None;
|
||||||
|
@ -261,18 +291,33 @@ void DWARFRewriter::updateDebugInfo() {
|
||||||
std::lock_guard<std::mutex> Lock(AccessMutex);
|
std::lock_guard<std::mutex> Lock(AccessMutex);
|
||||||
DebugLocWriter = LocListWritersByCU[CUIndex].get();
|
DebugLocWriter = LocListWritersByCU[CUIndex].get();
|
||||||
}
|
}
|
||||||
|
if (Unit->getVersion() >= 5) {
|
||||||
|
RangesBase = RangesSectionWriter->getSectionOffset() +
|
||||||
|
getDWARF5RngListLocListHeaderSize();
|
||||||
|
reinterpret_cast<DebugRangeListsSectionWriter *>(
|
||||||
|
RangesSectionWriter.get())
|
||||||
|
->initSection(Unit->getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
DebugInfoPatcher->addUnitBaseOffsetLabel(Unit->getOffset());
|
DebugInfoPatcher->addUnitBaseOffsetLabel(Unit->getOffset());
|
||||||
updateUnitDebugInfo(*Unit, *DebugInfoPatcher, *AbbrevWriter,
|
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) {
|
if (opts::NoThreads || opts::DeterministicDebugInfo) {
|
||||||
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units())
|
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
|
||||||
processUnitDIE(0, CU.get());
|
processUnitDIE(CUIndex, CU.get());
|
||||||
|
if (CU->getVersion() >= 5)
|
||||||
|
++CUIndex;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Update unit debug info in parallel
|
// Update unit debug info in parallel
|
||||||
ThreadPool &ThreadPool = ParallelUtilities::getThreadPool();
|
ThreadPool &ThreadPool = ParallelUtilities::getThreadPool();
|
||||||
size_t CUIndex = 0;
|
|
||||||
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
|
for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
|
||||||
ThreadPool.async(processUnitDIE, CUIndex, CU.get());
|
ThreadPool.async(processUnitDIE, CUIndex, CU.get());
|
||||||
CUIndex++;
|
CUIndex++;
|
||||||
|
@ -291,9 +336,18 @@ void DWARFRewriter::updateDebugInfo() {
|
||||||
updateGdbIndexSection(OffsetMap);
|
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(
|
void DWARFRewriter::updateUnitDebugInfo(
|
||||||
DWARFUnit &Unit, DebugInfoBinaryPatcher &DebugInfoPatcher,
|
DWARFUnit &Unit, DebugInfoBinaryPatcher &DebugInfoPatcher,
|
||||||
DebugAbbrevWriter &AbbrevWriter, DebugLocWriter &DebugLocWriter,
|
DebugAbbrevWriter &AbbrevWriter, DebugLocWriter &DebugLocWriter,
|
||||||
|
DebugRangesSectionWriter &RangesSectionWriter,
|
||||||
Optional<uint64_t> RangesBase) {
|
Optional<uint64_t> RangesBase) {
|
||||||
// Cache debug ranges so that the offset for identical ranges could be reused.
|
// Cache debug ranges so that the offset for identical ranges could be reused.
|
||||||
std::map<DebugAddressRangesVector, uint64_t> CachedRanges;
|
std::map<DebugAddressRangesVector, uint64_t> CachedRanges;
|
||||||
|
@ -332,7 +386,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
DebugAddressRangesVector OutputRanges =
|
DebugAddressRangesVector OutputRanges =
|
||||||
BC.translateModuleAddressRanges(ModuleRanges);
|
BC.translateModuleAddressRanges(ModuleRanges);
|
||||||
const uint64_t RangesSectionOffset =
|
const uint64_t RangesSectionOffset =
|
||||||
RangesSectionWriter->addRanges(OutputRanges);
|
RangesSectionWriter.addRanges(OutputRanges);
|
||||||
if (!Unit.isDWOUnit())
|
if (!Unit.isDWOUnit())
|
||||||
ARangesSectionWriter->addCURanges(Unit.getOffset(),
|
ARangesSectionWriter->addCURanges(Unit.getOffset(),
|
||||||
std::move(OutputRanges));
|
std::move(OutputRanges));
|
||||||
|
@ -371,7 +425,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
FunctionRanges.push_back({0, 0});
|
FunctionRanges.push_back({0, 0});
|
||||||
|
|
||||||
updateDWARFObjectAddressRanges(
|
updateDWARFObjectAddressRanges(
|
||||||
DIE, RangesSectionWriter->addRanges(FunctionRanges), DebugInfoPatcher,
|
DIE, RangesSectionWriter.addRanges(FunctionRanges), DebugInfoPatcher,
|
||||||
AbbrevWriter);
|
AbbrevWriter);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -380,8 +434,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
case dwarf::DW_TAG_inlined_subroutine:
|
case dwarf::DW_TAG_inlined_subroutine:
|
||||||
case dwarf::DW_TAG_try_block:
|
case dwarf::DW_TAG_try_block:
|
||||||
case dwarf::DW_TAG_catch_block: {
|
case dwarf::DW_TAG_catch_block: {
|
||||||
uint64_t RangesSectionOffset =
|
uint64_t RangesSectionOffset = RangesSectionWriter.getEmptyRangesOffset();
|
||||||
RangesSectionWriter->getEmptyRangesOffset();
|
|
||||||
Expected<DWARFAddressRangesVector> RangesOrError = DIE.getAddressRanges();
|
Expected<DWARFAddressRangesVector> RangesOrError = DIE.getAddressRanges();
|
||||||
const BinaryFunction *Function =
|
const BinaryFunction *Function =
|
||||||
RangesOrError && !RangesOrError->empty()
|
RangesOrError && !RangesOrError->empty()
|
||||||
|
@ -396,7 +449,7 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
<< Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
|
<< Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
|
||||||
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
||||||
});
|
});
|
||||||
RangesSectionOffset = RangesSectionWriter->addRanges(
|
RangesSectionOffset = RangesSectionWriter.addRanges(
|
||||||
std::move(OutputRanges), CachedRanges);
|
std::move(OutputRanges), CachedRanges);
|
||||||
} else if (!RangesOrError) {
|
} else if (!RangesOrError) {
|
||||||
consumeError(RangesOrError.takeError());
|
consumeError(RangesOrError.takeError());
|
||||||
|
@ -426,6 +479,12 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
if (SectionAddress)
|
if (SectionAddress)
|
||||||
BaseAddress = SectionAddress->Address;
|
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(
|
Error E = Unit.getLocationTable().visitLocationList(
|
||||||
&Offset, [&](const DWARFLocationEntry &Entry) {
|
&Offset, [&](const DWARFLocationEntry &Entry) {
|
||||||
switch (Entry.Kind) {
|
switch (Entry.Kind) {
|
||||||
|
@ -433,11 +492,12 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
llvm_unreachable("Unsupported DWARFLocationEntry Kind.");
|
llvm_unreachable("Unsupported DWARFLocationEntry Kind.");
|
||||||
case dwarf::DW_LLE_end_of_list:
|
case dwarf::DW_LLE_end_of_list:
|
||||||
return false;
|
return false;
|
||||||
case dwarf::DW_LLE_base_address:
|
case dwarf::DW_LLE_base_address: {
|
||||||
assert(Entry.SectionIndex == SectionedAddress::UndefSection &&
|
assert(Entry.SectionIndex == SectionedAddress::UndefSection &&
|
||||||
"absolute address expected");
|
"absolute address expected");
|
||||||
BaseAddress = Entry.Value0;
|
BaseAddress = Entry.Value0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case dwarf::DW_LLE_offset_pair:
|
case dwarf::DW_LLE_offset_pair:
|
||||||
assert(
|
assert(
|
||||||
(Entry.SectionIndex == SectionedAddress::UndefSection &&
|
(Entry.SectionIndex == SectionedAddress::UndefSection &&
|
||||||
|
@ -447,9 +507,18 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
BaseAddress + Entry.Value0, BaseAddress + Entry.Value1,
|
BaseAddress + Entry.Value0, BaseAddress + Entry.Value1,
|
||||||
Entry.Loc});
|
Entry.Loc});
|
||||||
break;
|
break;
|
||||||
case dwarf::DW_LLE_startx_length:
|
case dwarf::DW_RLE_start_length:
|
||||||
assert(Unit.isDWOUnit() &&
|
InputLL.emplace_back(DebugLocationEntry{
|
||||||
"None DWO Unit with DW_LLE_startx_length encoding.");
|
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 =
|
Optional<object::SectionedAddress> EntryAddress =
|
||||||
Unit.getAddrOffsetSectionItem(Entry.Value0);
|
Unit.getAddrOffsetSectionItem(Entry.Value0);
|
||||||
assert(EntryAddress && "Address does not exist.");
|
assert(EntryAddress && "Address does not exist.");
|
||||||
|
@ -458,6 +527,18 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
EntryAddress->Address + Entry.Value1, Entry.Loc});
|
EntryAddress->Address + Entry.Value1, Entry.Loc});
|
||||||
break;
|
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;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -469,42 +550,90 @@ void DWARFRewriter::updateUnitDebugInfo(
|
||||||
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
||||||
} else {
|
} else {
|
||||||
const uint64_t Address = InputLL.front().LowPC;
|
const uint64_t Address = InputLL.front().LowPC;
|
||||||
|
DebugLocationsVector OutputLL;
|
||||||
if (const BinaryFunction *Function =
|
if (const BinaryFunction *Function =
|
||||||
BC.getBinaryFunctionContainingAddress(Address)) {
|
BC.getBinaryFunctionContainingAddress(Address)) {
|
||||||
DebugLocationsVector OutputLL =
|
OutputLL = Function->translateInputToOutputLocationList(InputLL);
|
||||||
Function->translateInputToOutputLocationList(InputLL);
|
|
||||||
LLVM_DEBUG(if (OutputLL.empty()) {
|
LLVM_DEBUG(if (OutputLL.empty()) {
|
||||||
dbgs() << "BOLT-DEBUG: location list translated to an empty "
|
dbgs() << "BOLT-DEBUG: location list translated to an empty "
|
||||||
"one at 0x"
|
"one at 0x"
|
||||||
<< Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
|
<< Twine::utohexstr(DIE.getOffset()) << " in CU at 0x"
|
||||||
<< Twine::utohexstr(Unit.getOffset()) << '\n';
|
<< 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 {
|
} else {
|
||||||
assert((Value.isFormClass(DWARFFormValue::FC_Exprloc) ||
|
assert((Value.isFormClass(DWARFFormValue::FC_Exprloc) ||
|
||||||
Value.isFormClass(DWARFFormValue::FC_Block)) &&
|
Value.isFormClass(DWARFFormValue::FC_Block)) &&
|
||||||
"unexpected DW_AT_location form");
|
"unexpected DW_AT_location form");
|
||||||
if (Unit.isDWOUnit()) {
|
if (Unit.isDWOUnit() || Unit.getVersion() >= 5) {
|
||||||
ArrayRef<uint8_t> Expr = *Value.getAsBlock();
|
ArrayRef<uint8_t> Expr = *Value.getAsBlock();
|
||||||
DataExtractor Data(
|
DataExtractor Data(
|
||||||
StringRef((const char *)Expr.data(), Expr.size()),
|
StringRef((const char *)Expr.data(), Expr.size()),
|
||||||
Unit.getContext().isLittleEndian(), 0);
|
Unit.getContext().isLittleEndian(), 0);
|
||||||
DWARFExpression LocExpr(Data, Unit.getAddressByteSize(),
|
DWARFExpression LocExpr(Data, Unit.getAddressByteSize(),
|
||||||
Unit.getFormParams().Format);
|
Unit.getFormParams().Format);
|
||||||
|
uint32_t PrevOffset = 0;
|
||||||
|
constexpr uint32_t SizeOfOpcode = 1;
|
||||||
|
constexpr uint32_t SizeOfForm = 1;
|
||||||
for (auto &Expr : LocExpr) {
|
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;
|
continue;
|
||||||
uint64_t Index = Expr.getRawOperand(0);
|
|
||||||
|
const uint64_t Index = Expr.getRawOperand(0);
|
||||||
Optional<object::SectionedAddress> EntryAddress =
|
Optional<object::SectionedAddress> EntryAddress =
|
||||||
Unit.getAddrOffsetSectionItem(Index);
|
Unit.getAddrOffsetSectionItem(Index);
|
||||||
assert(EntryAddress && "Address is not found.");
|
assert(EntryAddress && "Address is not found.");
|
||||||
assert(Index <= std::numeric_limits<uint32_t>::max() &&
|
assert(Index <= std::numeric_limits<uint32_t>::max() &&
|
||||||
"Invalid Operand Index.");
|
"Invalid Operand Index.");
|
||||||
AddrWriter->addIndexAddress(EntryAddress->Address,
|
if (Expr.getCode() == dwarf::DW_OP_addrx) {
|
||||||
static_cast<uint32_t>(Index),
|
const uint32_t EncodingSize =
|
||||||
*Unit.getDWOId());
|
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");
|
"DW_FORM_LLVM_addrx_offset is not supported");
|
||||||
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
||||||
if (Form == dwarf::DW_FORM_GNU_addr_index) {
|
if (Form == dwarf::DW_FORM_GNU_addr_index) {
|
||||||
assert(Unit.isDWOUnit() &&
|
const uint64_t Index = Value.getRawUValue();
|
||||||
"DW_FORM_GNU_addr_index in Non DWO unit.");
|
|
||||||
uint64_t Index = Value.getRawUValue();
|
|
||||||
// If there is no new address, storing old address.
|
// If there is no new address, storing old address.
|
||||||
// Re-using Index to make implementation easier.
|
// Re-using Index to make implementation easier.
|
||||||
// DW_FORM_GNU_addr_index is variable lenght encoding so we either
|
// DW_FORM_GNU_addr_index is variable lenght encoding
|
||||||
// have to create indices of same sizes, or use same index.
|
// 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,
|
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 {
|
} else {
|
||||||
DebugInfoPatcher.addLE64Patch(AttrOffset, NewAddress);
|
DebugInfoPatcher.addLE64Patch(AttrOffset, NewAddress);
|
||||||
}
|
}
|
||||||
|
@ -613,6 +747,9 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
|
||||||
// are needed for ranges base.
|
// are needed for ranges base.
|
||||||
Optional<AttrInfo> RangesBaseAttrInfo =
|
Optional<AttrInfo> RangesBaseAttrInfo =
|
||||||
findAttributeInfo(DIE, dwarf::DW_AT_GNU_ranges_base);
|
findAttributeInfo(DIE, dwarf::DW_AT_GNU_ranges_base);
|
||||||
|
if (!RangesBaseAttrInfo)
|
||||||
|
RangesBaseAttrInfo = findAttributeInfo(DIE, dwarf::DW_AT_rnglists_base);
|
||||||
|
|
||||||
if (RangesBaseAttrInfo) {
|
if (RangesBaseAttrInfo) {
|
||||||
DebugInfoPatcher.addLE32Patch(RangesBaseAttrInfo->Offset,
|
DebugInfoPatcher.addLE32Patch(RangesBaseAttrInfo->Offset,
|
||||||
static_cast<uint32_t>(*RangesBase),
|
static_cast<uint32_t>(*RangesBase),
|
||||||
|
@ -623,15 +760,28 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
|
||||||
|
|
||||||
Optional<AttrInfo> LowPCAttrInfo =
|
Optional<AttrInfo> LowPCAttrInfo =
|
||||||
findAttributeInfo(DIE, dwarf::DW_AT_low_pc);
|
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.
|
// 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
|
// In this case we simply need to update the value of DW_AT_ranges
|
||||||
// and introduce DW_AT_GNU_ranges_base if required.
|
// 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);
|
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
||||||
DebugInfoPatcher.addLE32Patch(
|
// For DWARF5 converting all of DW_AT_ranges into DW_FORM_rnglistx
|
||||||
AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(),
|
bool Converted = false;
|
||||||
AttrVal->Size);
|
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 (!RangesBase) {
|
||||||
if (LowPCAttrInfo &&
|
if (LowPCAttrInfo &&
|
||||||
|
@ -766,15 +916,27 @@ DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
||||||
|
|
||||||
std::unique_ptr<DebugBufferVector> RangesSectionContents =
|
std::unique_ptr<DebugBufferVector> RangesSectionContents =
|
||||||
RangesSectionWriter->finalize();
|
RangesSectionWriter->finalize();
|
||||||
BC.registerOrUpdateNoteSection(".debug_ranges",
|
BC.registerOrUpdateNoteSection(
|
||||||
copyByteArray(*RangesSectionContents),
|
llvm::isa<DebugRangeListsSectionWriter>(*RangesSectionWriter)
|
||||||
RangesSectionContents->size());
|
? ".debug_rnglists"
|
||||||
|
: ".debug_ranges",
|
||||||
|
copyByteArray(*RangesSectionContents), RangesSectionContents->size());
|
||||||
|
|
||||||
std::unique_ptr<DebugBufferVector> LocationListSectionContents =
|
if (BC.isDWARF5Used()) {
|
||||||
makeFinalLocListsSection(DebugInfoPatcher);
|
std::unique_ptr<DebugBufferVector> LocationListSectionContents =
|
||||||
BC.registerOrUpdateNoteSection(".debug_loc",
|
makeFinalLocListsSection(DebugInfoPatcher, DWARFVersion::DWARF5);
|
||||||
copyByteArray(*LocationListSectionContents),
|
BC.registerOrUpdateNoteSection(".debug_loclists",
|
||||||
LocationListSectionContents->size());
|
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
|
// AddrWriter should be finalized after debug_loc since more addresses can be
|
||||||
// added there.
|
// added there.
|
||||||
|
@ -785,12 +947,39 @@ DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
||||||
AddressSectionContents.size());
|
AddressSectionContents.size());
|
||||||
for (auto &CU : BC.DwCtx->compile_units()) {
|
for (auto &CU : BC.DwCtx->compile_units()) {
|
||||||
DWARFDie DIE = CU->getUnitDIE();
|
DWARFDie DIE = CU->getUnitDIE();
|
||||||
if (Optional<AttrInfo> AttrVal =
|
uint64_t Offset = 0;
|
||||||
findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base)) {
|
uint64_t AttrOffset = 0;
|
||||||
uint64_t Offset = AddrWriter->getOffset(*CU->getDWOId());
|
uint32_t Size = 0;
|
||||||
DebugInfoPatcher.addLE32Patch(
|
Optional<AttrInfo> AttrValGnu =
|
||||||
AttrVal->Offset, static_cast<int32_t>(Offset), AttrVal->Size);
|
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)
|
if (Unit->getAbbreviationsOffset() == NewAbbrevOffset)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// DWARFv4
|
// DWARFv4 or earlier
|
||||||
// unit_length - 4 bytes
|
// unit_length - 4 bytes
|
||||||
// version - 2 bytes
|
// version - 2 bytes
|
||||||
// So + 6 to patch debug_abbrev_offset
|
// So + 6 to patch debug_abbrev_offset
|
||||||
constexpr uint64_t AbbrevFieldOffset = 6;
|
constexpr uint64_t AbbrevFieldOffsetLegacy = 6;
|
||||||
if (!Unit->isTypeUnit()) {
|
// DWARFv5
|
||||||
DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevFieldOffset,
|
// 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));
|
static_cast<uint32_t>(NewAbbrevOffset));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -826,7 +1024,7 @@ DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
||||||
DebugTypesPatcher =
|
DebugTypesPatcher =
|
||||||
static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher());
|
static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher());
|
||||||
}
|
}
|
||||||
DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevFieldOffset,
|
DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevOffset,
|
||||||
static_cast<uint32_t>(NewAbbrevOffset));
|
static_cast<uint32_t>(NewAbbrevOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,7 +1231,7 @@ void DWARFRewriter::writeDWP(
|
||||||
if (!DWOCU)
|
if (!DWOCU)
|
||||||
continue;
|
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 = {};
|
UnitIndexEntry CurEntry = {};
|
||||||
CurEntry.DWOName =
|
CurEntry.DWOName =
|
||||||
dwarf::toString(CU->getUnitDIE().find(
|
dwarf::toString(CU->getUnitDIE().find(
|
||||||
|
@ -1292,25 +1490,40 @@ void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DebugBufferVector>
|
std::unique_ptr<DebugBufferVector>
|
||||||
DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher) {
|
DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher,
|
||||||
|
DWARFVersion Version) {
|
||||||
auto LocBuffer = std::make_unique<DebugBufferVector>();
|
auto LocBuffer = std::make_unique<DebugBufferVector>();
|
||||||
auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
|
auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
|
||||||
auto Writer =
|
auto Writer =
|
||||||
std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream));
|
std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream));
|
||||||
|
|
||||||
uint64_t SectionOffset = 0;
|
uint64_t SectionOffset = 0;
|
||||||
|
|
||||||
// Add an empty list as the first entry;
|
// Add an empty list as the first entry;
|
||||||
const char Zeroes[16] = {0};
|
if (LocListWritersByCU.empty() ||
|
||||||
*LocStream << StringRef(Zeroes, 16);
|
LocListWritersByCU.begin()->second.get()->getDwarfVersion() < 5) {
|
||||||
SectionOffset += 2 * 8;
|
// 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 :
|
for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc :
|
||||||
LocListWritersByCU) {
|
LocListWritersByCU) {
|
||||||
DebugLocWriter *LocWriter = Loc.second.get();
|
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 =
|
SimpleBinaryPatcher *Patcher =
|
||||||
getBinaryDWODebugInfoPatcher(LocListWriter->getDWOID());
|
getBinaryDWODebugInfoPatcher(LocListWriter->getCUID());
|
||||||
LocListWriter->finalize(0, *Patcher);
|
LocListWriter->finalize(0, *Patcher);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1336,7 +1549,8 @@ void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
|
||||||
dwarf::Form HighPCForm = HighPCVal->V.getForm();
|
dwarf::Form HighPCForm = HighPCVal->V.getForm();
|
||||||
|
|
||||||
if (LowPCForm != dwarf::DW_FORM_addr &&
|
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 "
|
errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE "
|
||||||
<< "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n";
|
<< "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n";
|
||||||
return;
|
return;
|
||||||
|
@ -1351,7 +1565,8 @@ void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) &&
|
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. "
|
errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. "
|
||||||
<< "Cannot update DIE at offset 0x"
|
<< "Cannot update DIE at offset 0x"
|
||||||
<< Twine::utohexstr(DIE.getOffset()) << '\n';
|
<< Twine::utohexstr(DIE.getOffset()) << '\n';
|
||||||
|
@ -1364,24 +1579,27 @@ void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal,
|
||||||
void DWARFRewriter::convertToRangesPatchAbbrev(
|
void DWARFRewriter::convertToRangesPatchAbbrev(
|
||||||
const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev,
|
const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev,
|
||||||
DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) {
|
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
|
dwarf::Attribute RangeBaseAttribute = dwarf::DW_AT_GNU_ranges_base;
|
||||||
// there.
|
dwarf::Form RangesForm = dwarf::DW_FORM_sec_offset;
|
||||||
if (RangesBase) {
|
|
||||||
assert(LowPCForm != dwarf::DW_FORM_GNU_addr_index);
|
if (Unit.getVersion() >= 5) {
|
||||||
AbbrevWriter.addAttribute(Unit, Abbrev, dwarf::DW_AT_GNU_ranges_base,
|
RangeBaseAttribute = dwarf::DW_AT_rnglists_base;
|
||||||
dwarf::DW_FORM_sec_offset);
|
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,
|
AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc,
|
||||||
dwarf::DW_AT_ranges,
|
dwarf::DW_AT_ranges, RangesForm);
|
||||||
dwarf::DW_FORM_sec_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DWARFRewriter::convertToRangesPatchDebugInfo(
|
void DWARFRewriter::convertToRangesPatchDebugInfo(
|
||||||
|
@ -1395,19 +1613,42 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
|
||||||
|
|
||||||
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
||||||
uint32_t BaseOffset = 0;
|
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.
|
// Use ULEB128 for the value.
|
||||||
DebugInfoPatcher.addUDataPatch(LowPCOffset, 0,
|
DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, LowPCVal->Size);
|
||||||
std::abs(int(HighPCOffset - LowPCOffset)));
|
|
||||||
// Ranges are relative to DW_AT_GNU_ranges_base.
|
// Ranges are relative to DW_AT_GNU_ranges_base.
|
||||||
BaseOffset = DebugInfoPatcher.getRangeBase();
|
BaseOffset = DebugInfoPatcher.getRangeBase();
|
||||||
} else {
|
} else {
|
||||||
DebugInfoPatcher.addLE64Patch(LowPCOffset, 0);
|
// In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or
|
||||||
// If DW_AT_GNU_ranges_base was inserted.
|
// 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)
|
if (RangesBase)
|
||||||
reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher)
|
reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher)
|
||||||
.insertNewEntry(DIE, *RangesBase);
|
.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[];
|
constexpr const char *RewriteInstance::SectionsToOverwrite[];
|
||||||
std::vector<std::string> RewriteInstance::DebugSectionsToOverwrite = {
|
std::vector<std::string> RewriteInstance::DebugSectionsToOverwrite = {
|
||||||
".debug_abbrev", ".debug_aranges", ".debug_line", ".debug_loc",
|
".debug_abbrev", ".debug_aranges", ".debug_line", ".debug_line_str",
|
||||||
".debug_ranges", ".gdb_index", ".debug_addr"};
|
".debug_loc", ".debug_loclists", ".debug_ranges", ".debug_rnglists",
|
||||||
|
".gdb_index", ".debug_addr"};
|
||||||
|
|
||||||
const char RewriteInstance::TimerGroupName[] = "rewrite";
|
const char RewriteInstance::TimerGroupName[] = "rewrite";
|
||||||
const char RewriteInstance::TimerGroupDesc[] = "Rewrite passes";
|
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
|
# 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).
|
# not where the DW_AT_abstract_origin is located).
|
||||||
# DW_TAG_variable in CU 1 is using DW_AT_decl_file 3.
|
# 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[ 1]: name: "inlinevarother.h"
|
||||||
# file_names[ 2]: name: "inlinevar1.c"
|
# file_names[ 2]: name: "inlinevar1.c"
|
||||||
# file_names[ 3]: name: "inlinevar.h"
|
# file_names[ 3]: name: "inlinevar.h"
|
||||||
# CU 2 has files:
|
# CU 2 has files:
|
||||||
# file_names[ 1]: name: "inlinevar2.c"
|
# file_names[ 1]: name: "inlinevar2.c"
|
||||||
# file_names[ 2]: name: "inlinevar.h"
|
# file_names[ 2]: name: "inlinevar.h"
|
||||||
|
|
||||||
# UNSUPPORTED: system-darwin, system-windows
|
# UNSUPPORTED: system-darwin, system-windows
|
||||||
# REQUIRES: target-x86_64
|
# 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: %S/Inputs/DW_TAG_variable-DW_AT_decl_file-DW_AT_abstract_origin-crosscu2.s
|
||||||
|
|
||||||
# RUN: %lldb %t \
|
# RUN: %lldb %t \
|
||||||
|
@ -36,7 +36,7 @@ main: # @main
|
||||||
.Ltmp2:
|
.Ltmp2:
|
||||||
.file 3 "" "./inlinevar.h"
|
.file 3 "" "./inlinevar.h"
|
||||||
.loc 3 2 16 prologue_end # ./inlinevar.h:2:16
|
.loc 3 2 16 prologue_end # ./inlinevar.h:2:16
|
||||||
movl $42, %eax
|
movl $42, %eax
|
||||||
pushq %rax
|
pushq %rax
|
||||||
.loc 3 3 10 # ./inlinevar.h:3:10
|
.loc 3 3 10 # ./inlinevar.h:3:10
|
||||||
.Ltmp3:
|
.Ltmp3:
|
||||||
|
|
Loading…
Reference in New Issue