forked from OSchip/llvm-project
[BOLT][DWARF] Fix gdb index section
Since we now re-write .debug_info the DWARF CU Offsets can change. Just like for .debug_aranges the GDB Index will need to be updated. Reviewed By: Amir, maksfb Differential Revision: https://reviews.llvm.org/D118273
This commit is contained in:
parent
1f26aa42ce
commit
612f0f4568
|
@ -107,6 +107,13 @@ struct DebugLineTableRowRef {
|
|||
/// Common buffer vector used for debug info handling.
|
||||
using DebugBufferVector = SmallVector<char, 16>;
|
||||
|
||||
/// Map of old CU offset to new offset and length.
|
||||
struct CUInfo {
|
||||
uint32_t Offset;
|
||||
uint32_t Length;
|
||||
};
|
||||
using CUOffsetMap = std::map<uint32_t, CUInfo>;
|
||||
|
||||
/// Serializes the .debug_ranges DWARF section.
|
||||
class DebugRangesSectionWriter {
|
||||
public:
|
||||
|
@ -155,9 +162,8 @@ public:
|
|||
/// Writes .debug_aranges with the added ranges to the MCObjectWriter.
|
||||
/// Takes in \p RangesStream to write into, and \p CUMap which maps CU
|
||||
/// original offsets to new ones.
|
||||
void
|
||||
writeARangesSection(raw_svector_ostream &RangesStream,
|
||||
const std::unordered_map<uint32_t, uint32_t> CUMap) const;
|
||||
void writeARangesSection(raw_svector_ostream &RangesStream,
|
||||
const CUOffsetMap &CUMap) const;
|
||||
|
||||
/// Resets the writer to a clear state.
|
||||
void reset() { CUAddressRanges.clear(); }
|
||||
|
@ -647,8 +653,8 @@ public:
|
|||
void setDWPOffset(uint64_t DWPOffset) { DWPUnitOffset = DWPOffset; }
|
||||
|
||||
/// When this function is invoked all of the DebugInfo Patches must be done.
|
||||
/// Returns a map of old CU offsets to new ones.
|
||||
std::unordered_map<uint32_t, uint32_t> computeNewOffsets();
|
||||
/// Returns a map of old CU offsets to new offsets and new sizes.
|
||||
CUOffsetMap computeNewOffsets(DWARFContext &DWCtx, bool IsDWOContext);
|
||||
|
||||
private:
|
||||
struct PatchDeleter {
|
||||
|
@ -685,7 +691,7 @@ private:
|
|||
using UniquePatchPtrType = std::unique_ptr<Patch, PatchDeleter>;
|
||||
|
||||
uint64_t DWPUnitOffset{0};
|
||||
uint32_t ChangeInSize{0};
|
||||
int32_t ChangeInSize{0};
|
||||
std::vector<UniquePatchPtrType> DebugPatches;
|
||||
/// Mutex used for parallel processing of debug info.
|
||||
std::mutex WriterMutex;
|
||||
|
|
|
@ -93,14 +93,14 @@ class DWARFRewriter {
|
|||
makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher);
|
||||
|
||||
/// Finalize debug sections in the main binary.
|
||||
void finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher);
|
||||
CUOffsetMap finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher);
|
||||
|
||||
/// Patches the binary for DWARF address ranges (e.g. in functions and lexical
|
||||
/// blocks) to be updated.
|
||||
void updateDebugAddressRanges();
|
||||
|
||||
/// Rewrite .gdb_index section if present.
|
||||
void updateGdbIndexSection();
|
||||
void updateGdbIndexSection(CUOffsetMap &CUMap);
|
||||
|
||||
/// Output .dwo files.
|
||||
void writeDWOFiles(std::unordered_map<uint64_t, std::string> &DWOIdToName);
|
||||
|
|
|
@ -121,8 +121,7 @@ void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
|
|||
}
|
||||
|
||||
void DebugARangesSectionWriter::writeARangesSection(
|
||||
raw_svector_ostream &RangesStream,
|
||||
const std::unordered_map<uint32_t, uint32_t> CUMap) const {
|
||||
raw_svector_ostream &RangesStream, const CUOffsetMap &CUMap) const {
|
||||
// For reference on the format of the .debug_aranges section, see the DWARF4
|
||||
// specification, section 6.1.4 Lookup by Address
|
||||
// http://www.dwarfstd.org/doc/DWARF4.pdf
|
||||
|
@ -148,9 +147,9 @@ void DebugARangesSectionWriter::writeARangesSection(
|
|||
|
||||
assert(CUMap.count(Offset) && "Original CU offset is not found in CU Map");
|
||||
// Header field #3: debug info offset of the correspondent compile unit.
|
||||
support::endian::write(RangesStream,
|
||||
static_cast<uint32_t>(CUMap.find(Offset)->second),
|
||||
support::little);
|
||||
support::endian::write(
|
||||
RangesStream, static_cast<uint32_t>(CUMap.find(Offset)->second.Offset),
|
||||
support::little);
|
||||
|
||||
// Header field #4: address size.
|
||||
// 8 since we only write ELF64 binaries for now.
|
||||
|
@ -473,23 +472,32 @@ std::string SimpleBinaryPatcher::patchBinary(StringRef BinaryContents) {
|
|||
return BinaryContentsStr;
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, uint32_t>
|
||||
DebugInfoBinaryPatcher::computeNewOffsets() {
|
||||
std::unordered_map<uint32_t, uint32_t> CUMap;
|
||||
CUOffsetMap DebugInfoBinaryPatcher::computeNewOffsets(DWARFContext &DWCtx,
|
||||
bool IsDWOContext) {
|
||||
CUOffsetMap CUMap;
|
||||
std::sort(DebugPatches.begin(), DebugPatches.end(),
|
||||
[](const UniquePatchPtrType &V1, const UniquePatchPtrType &V2) {
|
||||
return V1.get()->Offset < V2.get()->Offset;
|
||||
});
|
||||
|
||||
DWARFUnitVector::compile_unit_range CompileUnits =
|
||||
IsDWOContext ? DWCtx.dwo_compile_units() : DWCtx.compile_units();
|
||||
|
||||
for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits)
|
||||
CUMap[CU->getOffset()] = {static_cast<uint32_t>(CU->getOffset()),
|
||||
static_cast<uint32_t>(CU->getLength())};
|
||||
|
||||
// Calculating changes in .debug_info size from Patches to build a map of old
|
||||
// to updated reference destination offsets.
|
||||
uint32_t PreviousOffset = 0;
|
||||
int32_t PreviousChangeInSize = 0;
|
||||
for (UniquePatchPtrType &PatchBase : DebugPatches) {
|
||||
Patch *P = PatchBase.get();
|
||||
switch (P->Kind) {
|
||||
default:
|
||||
continue;
|
||||
case DebugPatchKind::PatchValue64to32: {
|
||||
ChangeInSize -= 4;
|
||||
PreviousChangeInSize -= 4;
|
||||
break;
|
||||
}
|
||||
case DebugPatchKind::PatchValueVariable: {
|
||||
|
@ -498,13 +506,14 @@ DebugInfoBinaryPatcher::computeNewOffsets() {
|
|||
std::string Temp;
|
||||
raw_string_ostream OS(Temp);
|
||||
encodeULEB128(DPV->Value, OS);
|
||||
ChangeInSize += Temp.size() - DPV->OldValueSize;
|
||||
PreviousChangeInSize += Temp.size() - DPV->OldValueSize;
|
||||
break;
|
||||
}
|
||||
case DebugPatchKind::DestinationReferenceLabel: {
|
||||
DestinationReferenceLabel *DRL =
|
||||
reinterpret_cast<DestinationReferenceLabel *>(P);
|
||||
OldToNewOffset[DRL->Offset] = DRL->Offset + ChangeInSize;
|
||||
OldToNewOffset[DRL->Offset] =
|
||||
DRL->Offset + ChangeInSize + PreviousChangeInSize;
|
||||
break;
|
||||
}
|
||||
case DebugPatchKind::ReferencePatchValue: {
|
||||
|
@ -512,7 +521,7 @@ DebugInfoBinaryPatcher::computeNewOffsets() {
|
|||
// to reduce algorithmic complexity.
|
||||
DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P);
|
||||
if (RDP->PatchInfo.IndirectRelative) {
|
||||
ChangeInSize += 4 - RDP->PatchInfo.OldValueSize;
|
||||
PreviousChangeInSize += 4 - RDP->PatchInfo.OldValueSize;
|
||||
assert(RDP->PatchInfo.OldValueSize <= 4 &&
|
||||
"Variable encoding reference greater than 4 bytes.");
|
||||
}
|
||||
|
@ -522,11 +531,16 @@ DebugInfoBinaryPatcher::computeNewOffsets() {
|
|||
DWARFUnitOffsetBaseLabel *BaseLabel =
|
||||
reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P);
|
||||
uint32_t CUOffset = BaseLabel->Offset;
|
||||
ChangeInSize += PreviousChangeInSize;
|
||||
uint32_t CUOffsetUpdate = CUOffset + ChangeInSize;
|
||||
CUMap[CUOffset] = CUOffsetUpdate;
|
||||
CUMap[CUOffset].Offset = CUOffsetUpdate;
|
||||
CUMap[PreviousOffset].Length += PreviousChangeInSize;
|
||||
PreviousChangeInSize = 0;
|
||||
PreviousOffset = CUOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
CUMap[PreviousOffset].Length += PreviousChangeInSize;
|
||||
return CUMap;
|
||||
}
|
||||
|
||||
|
|
|
@ -323,14 +323,14 @@ void DWARFRewriter::updateDebugInfo() {
|
|||
DebugInfoPatcher->clearDestinationLabels();
|
||||
flushPendingRanges(*DebugInfoPatcher);
|
||||
|
||||
finalizeDebugSections(*DebugInfoPatcher);
|
||||
CUOffsetMap OffsetMap = finalizeDebugSections(*DebugInfoPatcher);
|
||||
|
||||
if (opts::WriteDWP)
|
||||
writeDWP(DWOIdToName);
|
||||
else
|
||||
writeDWOFiles(DWOIdToName);
|
||||
|
||||
updateGdbIndexSection();
|
||||
updateGdbIndexSection(OffsetMap);
|
||||
}
|
||||
|
||||
void DWARFRewriter::updateUnitDebugInfo(
|
||||
|
@ -820,8 +820,8 @@ void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) {
|
|||
TypeInfoSection->setIsFinalized();
|
||||
}
|
||||
|
||||
void DWARFRewriter::finalizeDebugSections(
|
||||
DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
||||
CUOffsetMap
|
||||
DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) {
|
||||
if (StrWriter->isInitialized()) {
|
||||
RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
|
||||
std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents =
|
||||
|
@ -898,8 +898,8 @@ void DWARFRewriter::finalizeDebugSections(
|
|||
}
|
||||
|
||||
// No more creating new DebugInfoPatches.
|
||||
std::unordered_map<uint32_t, uint32_t> CUMap =
|
||||
DebugInfoPatcher.computeNewOffsets();
|
||||
CUOffsetMap CUMap =
|
||||
DebugInfoPatcher.computeNewOffsets(*BC.DwCtx.get(), false);
|
||||
|
||||
// Skip .debug_aranges if we are re-generating .gdb_index.
|
||||
if (opts::KeepARanges || !BC.getGdbIndexSection()) {
|
||||
|
@ -916,6 +916,7 @@ void DWARFRewriter::finalizeDebugSections(
|
|||
copyByteArray(ARangesContents),
|
||||
ARangesContents.size());
|
||||
}
|
||||
return CUMap;
|
||||
}
|
||||
|
||||
// Creates all the data structures necessary for creating MCStreamer.
|
||||
|
@ -958,15 +959,14 @@ StringRef getSectionName(const SectionRef &Section) {
|
|||
|
||||
// Exctracts an appropriate slice if input is DWP.
|
||||
// Applies patches or overwrites the section.
|
||||
Optional<StringRef>
|
||||
updateDebugData(std::string &Storage, const SectionRef &Section,
|
||||
const StringMap<KnownSectionsEntry> &KnownSections,
|
||||
MCStreamer &Streamer, DWARFRewriter &Writer,
|
||||
const DWARFUnitIndex::Entry *DWOEntry, uint64_t DWOId,
|
||||
std::unique_ptr<DebugBufferVector> &OutputBuffer) {
|
||||
Optional<StringRef> updateDebugData(
|
||||
DWARFContext &DWCtx, std::string &Storage, const SectionRef &Section,
|
||||
const StringMap<KnownSectionsEntry> &KnownSections, MCStreamer &Streamer,
|
||||
DWARFRewriter &Writer, const DWARFUnitIndex::Entry *DWOEntry,
|
||||
uint64_t DWOId, std::unique_ptr<DebugBufferVector> &OutputBuffer) {
|
||||
auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher,
|
||||
StringRef Data) -> StringRef {
|
||||
Patcher->computeNewOffsets();
|
||||
Patcher->computeNewOffsets(DWCtx, true);
|
||||
Storage = Patcher->patchBinary(Data);
|
||||
return StringRef(Storage.c_str(), Storage.size());
|
||||
};
|
||||
|
@ -1127,9 +1127,9 @@ void DWARFRewriter::writeDWP(
|
|||
for (const SectionRef &Section : DWOFile->sections()) {
|
||||
std::string Storage = "";
|
||||
std::unique_ptr<DebugBufferVector> OutputData;
|
||||
Optional<StringRef> TOutData =
|
||||
updateDebugData(Storage, Section, KnownSections, *Streamer, *this,
|
||||
DWOEntry, *DWOId, OutputData);
|
||||
Optional<StringRef> TOutData = updateDebugData(
|
||||
(*DWOCU)->getContext(), Storage, Section, KnownSections, *Streamer,
|
||||
*this, DWOEntry, *DWOId, OutputData);
|
||||
if (!TOutData)
|
||||
continue;
|
||||
|
||||
|
@ -1227,9 +1227,9 @@ void DWARFRewriter::writeDWOFiles(
|
|||
for (const SectionRef &Section : File->sections()) {
|
||||
std::string Storage = "";
|
||||
std::unique_ptr<DebugBufferVector> OutputData;
|
||||
if (Optional<StringRef> OutData =
|
||||
updateDebugData(Storage, Section, KnownSections, *Streamer, *this,
|
||||
DWOEntry, *DWOId, OutputData))
|
||||
if (Optional<StringRef> OutData = updateDebugData(
|
||||
(*DWOCU)->getContext(), Storage, Section, KnownSections,
|
||||
*Streamer, *this, DWOEntry, *DWOId, OutputData))
|
||||
Streamer->emitBytes(*OutData);
|
||||
}
|
||||
Streamer->Finish();
|
||||
|
@ -1237,7 +1237,7 @@ void DWARFRewriter::writeDWOFiles(
|
|||
}
|
||||
}
|
||||
|
||||
void DWARFRewriter::updateGdbIndexSection() {
|
||||
void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap) {
|
||||
if (!BC.getGdbIndexSection())
|
||||
return;
|
||||
|
||||
|
@ -1314,10 +1314,23 @@ void DWARFRewriter::updateGdbIndexSection() {
|
|||
write32le(Buffer + 20, ConstantPoolOffset + Delta);
|
||||
Buffer += 24;
|
||||
|
||||
// Copy over CU list and types CU list.
|
||||
memcpy(Buffer, GdbIndexContents.data() + 24,
|
||||
AddressTableOffset - CUListOffset);
|
||||
Buffer += AddressTableOffset - CUListOffset;
|
||||
// Writing out CU List <Offset, Size>
|
||||
for (auto &CUInfo : CUMap) {
|
||||
write64le(Buffer, CUInfo.second.Offset);
|
||||
// Length encoded in CU doesn't contain first 4 bytes that encode length.
|
||||
write64le(Buffer + 8, CUInfo.second.Length + 4);
|
||||
Buffer += 16;
|
||||
}
|
||||
|
||||
// Copy over types CU list
|
||||
// Spec says " triplet, the first value is the CU offset, the second value is
|
||||
// the type offset in the CU, and the third value is the type signature"
|
||||
// Looking at what is being generated by gdb-add-index. The first entry is TU
|
||||
// offset, second entry is offset from it, and third entry is the type
|
||||
// signature.
|
||||
memcpy(Buffer, GdbIndexContents.data() + CUTypesOffset,
|
||||
AddressTableOffset - CUTypesOffset);
|
||||
Buffer += AddressTableOffset - CUTypesOffset;
|
||||
|
||||
// Generate new address table.
|
||||
for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair :
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
.file "test.cpp"
|
||||
.text
|
||||
.Ltext0:
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB0:
|
||||
.file 1 "test.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 1 21
|
||||
movl $0, %eax
|
||||
.loc 1 1 24
|
||||
popq %rbp
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size main, .-main
|
||||
.Letext0:
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0x4f
|
||||
.value 0x4
|
||||
.long .Ldebug_abbrev0
|
||||
.byte 0x8
|
||||
.uleb128 0x1
|
||||
.long .LASF0
|
||||
.byte 0x4
|
||||
.long .LASF1
|
||||
.long .LASF2
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.long .Ldebug_line0
|
||||
.uleb128 0x2
|
||||
.long .LASF3
|
||||
.byte 0x1
|
||||
.byte 0x1
|
||||
.byte 0x5
|
||||
.long 0x4b
|
||||
.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 0x2117
|
||||
.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
|
||||
.LASF1:
|
||||
.string "test.cpp"
|
||||
.LASF0:
|
||||
.string "GNU C++14 8.5.0 20210514 (Red Hat 8.5.0-3) -mtune=generic -march=x86-64 -g2"
|
||||
.LASF2:
|
||||
.string ""
|
||||
.LASF3:
|
||||
.string "main"
|
||||
.ident "GCC: (GNU) 8.5.0 20210514 (Red Hat 8.5.0-3)"
|
||||
.section .note.GNU-stack,"",@progbits
|
|
@ -0,0 +1,142 @@
|
|||
.file "test2.cpp"
|
||||
.text
|
||||
.Ltext0:
|
||||
.globl _Z5main2v
|
||||
.type _Z5main2v, @function
|
||||
_Z5main2v:
|
||||
.LFB0:
|
||||
.file 1 "test2.cpp"
|
||||
.loc 1 1 13
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
.loc 1 1 22
|
||||
movl $0, %eax
|
||||
.loc 1 1 25
|
||||
popq %rbp
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size _Z5main2v, .-_Z5main2v
|
||||
.Letext0:
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0x53
|
||||
.value 0x4
|
||||
.long .Ldebug_abbrev0
|
||||
.byte 0x8
|
||||
.uleb128 0x1
|
||||
.long .LASF0
|
||||
.byte 0x4
|
||||
.long .LASF1
|
||||
.long .LASF2
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.long .Ldebug_line0
|
||||
.uleb128 0x2
|
||||
.long .LASF3
|
||||
.byte 0x1
|
||||
.byte 0x1
|
||||
.byte 0x5
|
||||
.long .LASF4
|
||||
.long 0x4f
|
||||
.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 0x6e
|
||||
.uleb128 0xe
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x40
|
||||
.uleb128 0x18
|
||||
.uleb128 0x2117
|
||||
.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
|
||||
.LASF3:
|
||||
.string "main2"
|
||||
.LASF2:
|
||||
.string ""
|
||||
.LASF0:
|
||||
.string "GNU C++14 8.5.0 20210514 (Red Hat 8.5.0-3) -mtune=generic -march=x86-64 -g2"
|
||||
.LASF4:
|
||||
.string "_Z5main2v"
|
||||
.LASF1:
|
||||
.string "test2.cpp"
|
||||
.ident "GCC: (GNU) 8.5.0 20210514 (Red Hat 8.5.0-3)"
|
||||
.section .note.GNU-stack,"",@progbits
|
|
@ -0,0 +1,32 @@
|
|||
RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %p/Inputs/dwarfdump-gdbindex.s -o %t.o
|
||||
RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %p/Inputs/dwarfdump-gdbindex2.s -o %t2.o
|
||||
RUN: ld.lld --gdb-index %t.o %t2.o -o %tfile.exe
|
||||
RUN: llvm-bolt %tfile.exe -o %tfile.exe.bolt -update-debug-sections
|
||||
RUN: llvm-dwarfdump -gdb-index %tfile.exe.bolt | FileCheck %s
|
||||
|
||||
; test.cpp:
|
||||
; int main() { return 0; }
|
||||
; test2.cpp:
|
||||
; int main2() { return 0; }
|
||||
; Compiled with:
|
||||
; gcc -gsplit-dwarf -c test.cpp test2.cpp
|
||||
; gold --gdb-index test.o test2.o -o dwarfdump-gdbindex-v7.elf-x86-64
|
||||
; gcc version 5.3.1 20160413, GNU gold (GNU Binutils for Ubuntu 2.26) 1.11
|
||||
; Info about gdb-index: https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
|
||||
|
||||
; CHECK-LABEL: .gdb_index contents:
|
||||
; CHECK: Version = 7
|
||||
|
||||
; CHECK: CU list offset = 0x18, has 2 entries:
|
||||
; CHECK-NEXT: 0: Offset = 0x0, Length = 0x4f
|
||||
; CHECK-NEXT: 1: Offset = 0x4f, Length = 0x53
|
||||
|
||||
; CHECK: Types CU list offset = 0x38, has 0 entries:
|
||||
|
||||
; CHECK: Address area offset = 0x38, has 2 entries:
|
||||
; CHECK-NEXT: Low/High address = [0x20117c, 0x201187) (Size: 0xb), CU id = 0
|
||||
; CHECK-NEXT: Low/High address = [0x201188, 0x201193) (Size: 0xb), CU id = 1
|
||||
|
||||
; CHECK: Symbol table offset = 0x60, size = 1024, filled slots:
|
||||
|
||||
; CHECK: Constant pool offset = 0x2060, has 0 CU vectors:
|
Loading…
Reference in New Issue