[BOLT][DWARF] Update DW_AT_comp_dir/DW_AT_dwo_name for DWO TUs (#91486)

Type unit DIE generated by clang contains DW_AT_comp_dir/DW_AT_dwo_name.
This was added to clang to help LLDB to figure out where type unit come
from when accessing an entry in a .debug_names accelerator table and
type units in .dwp file.

When BOLT writes out .dwo files it changes the name of them. User can
also specify directory of where they can be written out. Added support
to BOLT to update those attributes.
This commit is contained in:
Alexander Yermolovich 2024-05-14 15:08:45 -07:00 committed by GitHub
parent 5bf653ca42
commit 99fad7ebd8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 575 additions and 120 deletions

View File

@ -129,6 +129,9 @@ private:
uint64_t UnitSize{0};
llvm::DenseSet<uint64_t> AllProcessed;
DWARF5AcceleratorTable &DebugNamesTable;
// Unordered map to handle name collision if output DWO directory is
// specified.
std::unordered_map<std::string, uint32_t> NameToIndexMap;
/// Returns current state of the DIEBuilder
State &getState() { return *BuilderState.get(); }
@ -384,6 +387,17 @@ public:
bool deleteValue(DIEValueList *Die, dwarf::Attribute Attribute) {
return Die->deleteValue(Attribute);
}
/// Updates DWO Name and Compilation directory for Skeleton CU \p Unit.
std::string updateDWONameCompDir(DebugStrOffsetsWriter &StrOffstsWriter,
DebugStrWriter &StrWriter,
DWARFUnit &SkeletonCU,
std::optional<StringRef> DwarfOutputPath,
std::optional<StringRef> DWONameToUse);
/// Updates DWO Name and Compilation directory for Type Units.
void updateDWONameCompDirForTypes(DebugStrOffsetsWriter &StrOffstsWriter,
DebugStrWriter &StrWriter, DWARFUnit &Unit,
std::optional<StringRef> DwarfOutputPath,
const StringRef DWOName);
};
} // namespace bolt
} // namespace llvm

View File

@ -430,7 +430,7 @@ protected:
using DebugStrOffsetsBufferVector = SmallVector<char, 16>;
class DebugStrOffsetsWriter {
public:
DebugStrOffsetsWriter() {
DebugStrOffsetsWriter(BinaryContext &BC) : BC(BC) {
StrOffsetsBuffer = std::make_unique<DebugStrOffsetsBufferVector>();
StrOffsetsStream = std::make_unique<raw_svector_ostream>(*StrOffsetsBuffer);
}
@ -460,6 +460,10 @@ public:
StrOffsets.clear();
}
bool isStrOffsetsSectionModified() const {
return StrOffsetSectionWasModified;
}
private:
std::unique_ptr<DebugStrOffsetsBufferVector> StrOffsetsBuffer;
std::unique_ptr<raw_svector_ostream> StrOffsetsStream;
@ -467,13 +471,16 @@ private:
SmallVector<uint32_t, 5> StrOffsets;
std::unordered_map<uint64_t, uint64_t> ProcessedBaseOffsets;
bool StrOffsetSectionWasModified = false;
BinaryContext &BC;
};
using DebugStrBufferVector = SmallVector<char, 16>;
class DebugStrWriter {
public:
DebugStrWriter() = delete;
DebugStrWriter(BinaryContext &BC) : BC(BC) { create(); }
DebugStrWriter(DWARFContext &DwCtx, bool IsDWO) : DwCtx(DwCtx), IsDWO(IsDWO) {
create();
}
std::unique_ptr<DebugStrBufferVector> releaseBuffer() {
return std::move(StrBuffer);
}
@ -495,7 +502,8 @@ private:
void create();
std::unique_ptr<DebugStrBufferVector> StrBuffer;
std::unique_ptr<raw_svector_ostream> StrStream;
BinaryContext &BC;
DWARFContext &DwCtx;
bool IsDWO;
};
enum class LocWriterKind { DebugLocWriter, DebugLoclistWriter };

View File

@ -203,13 +203,16 @@ public:
using OverriddenSectionsMap = std::unordered_map<DWARFSectionKind, StringRef>;
/// Output .dwo files.
void writeDWOFiles(DWARFUnit &, const OverriddenSectionsMap &,
const std::string &, DebugLocWriter &);
const std::string &, DebugLocWriter &,
DebugStrOffsetsWriter &, DebugStrWriter &);
using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>;
struct DWPState {
std::unique_ptr<ToolOutputFile> Out;
std::unique_ptr<BinaryContext> TmpBC;
std::unique_ptr<MCStreamer> Streamer;
std::unique_ptr<DWPStringPool> Strings;
/// Used to store String sections for .dwo files if they are being modified.
std::vector<std::unique_ptr<DebugBufferVector>> StrSections;
const MCObjectFileInfo *MCOFI = nullptr;
const DWARFUnitIndex *CUIndex = nullptr;
std::deque<SmallString<32>> UncompressedSections;
@ -230,7 +233,8 @@ public:
/// add content of dwo to .dwp file.
void updateDWP(DWARFUnit &, const OverriddenSectionsMap &, const UnitMeta &,
UnitMetaVectorType &, DWPState &, DebugLocWriter &);
UnitMetaVectorType &, DWPState &, DebugLocWriter &,
DebugStrOffsetsWriter &, DebugStrWriter &);
};
} // namespace bolt

View File

@ -22,6 +22,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LEB128.h"
#include <algorithm>
@ -41,6 +42,90 @@ extern cl::opt<unsigned> Verbosity;
namespace llvm {
namespace bolt {
/// Returns DWO Name to be used to update DW_AT_dwo_name/DW_AT_GNU_dwo_name
/// either in CU or TU unit die. Handles case where user specifies output DWO
/// directory, and there are duplicate names. Assumes DWO ID is unique.
static std::string
getDWOName(llvm::DWARFUnit &CU,
std::unordered_map<std::string, uint32_t> &NameToIndexMap,
std::optional<StringRef> &DwarfOutputPath) {
assert(CU.getDWOId() && "DWO ID not found.");
std::string DWOName = dwarf::toString(
CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
"");
assert(!DWOName.empty() &&
"DW_AT_dwo_name/DW_AT_GNU_dwo_name does not exist.");
if (DwarfOutputPath) {
DWOName = std::string(sys::path::filename(DWOName));
auto Iter = NameToIndexMap.find(DWOName);
if (Iter == NameToIndexMap.end())
Iter = NameToIndexMap.insert({DWOName, 0}).first;
DWOName.append(std::to_string(Iter->second));
++Iter->second;
}
DWOName.append(".dwo");
return DWOName;
}
/// Adds a \p Str to .debug_str section.
/// Uses \p AttrInfoVal to either update entry in a DIE for legacy DWARF using
/// \p DebugInfoPatcher, or for DWARF5 update an index in .debug_str_offsets
/// for this contribution of \p Unit.
static void addStringHelper(DebugStrOffsetsWriter &StrOffstsWriter,
DebugStrWriter &StrWriter, DIEBuilder &DIEBldr,
DIE &Die, const DWARFUnit &Unit,
DIEValue &DIEAttrInfo, StringRef Str) {
uint32_t NewOffset = StrWriter.addString(Str);
if (Unit.getVersion() >= 5) {
StrOffstsWriter.updateAddressMap(DIEAttrInfo.getDIEInteger().getValue(),
NewOffset);
return;
}
DIEBldr.replaceValue(&Die, DIEAttrInfo.getAttribute(), DIEAttrInfo.getForm(),
DIEInteger(NewOffset));
}
std::string DIEBuilder::updateDWONameCompDir(
DebugStrOffsetsWriter &StrOffstsWriter, DebugStrWriter &StrWriter,
DWARFUnit &SkeletonCU, std::optional<StringRef> DwarfOutputPath,
std::optional<StringRef> DWONameToUse) {
DIE &UnitDIE = *getUnitDIEbyUnit(SkeletonCU);
DIEValue DWONameAttrInfo = UnitDIE.findAttribute(dwarf::DW_AT_dwo_name);
if (!DWONameAttrInfo)
DWONameAttrInfo = UnitDIE.findAttribute(dwarf::DW_AT_GNU_dwo_name);
if (!DWONameAttrInfo)
return "";
std::string ObjectName;
if (DWONameToUse)
ObjectName = *DWONameToUse;
else
ObjectName = getDWOName(SkeletonCU, NameToIndexMap, DwarfOutputPath);
addStringHelper(StrOffstsWriter, StrWriter, *this, UnitDIE, SkeletonCU,
DWONameAttrInfo, ObjectName);
DIEValue CompDirAttrInfo = UnitDIE.findAttribute(dwarf::DW_AT_comp_dir);
assert(CompDirAttrInfo && "DW_AT_comp_dir is not in Skeleton CU.");
if (DwarfOutputPath) {
if (!sys::fs::exists(*DwarfOutputPath))
sys::fs::create_directory(*DwarfOutputPath);
addStringHelper(StrOffstsWriter, StrWriter, *this, UnitDIE, SkeletonCU,
CompDirAttrInfo, *DwarfOutputPath);
}
return ObjectName;
}
void DIEBuilder::updateDWONameCompDirForTypes(
DebugStrOffsetsWriter &StrOffstsWriter, DebugStrWriter &StrWriter,
DWARFUnit &Unit, std::optional<StringRef> DwarfOutputPath,
const StringRef DWOName) {
for (DWARFUnit *DU : getState().DWARF5TUVector)
updateDWONameCompDir(StrOffstsWriter, StrWriter, *DU, DwarfOutputPath,
DWOName);
if (StrOffstsWriter.isStrOffsetsSectionModified())
StrOffstsWriter.finalizeSection(Unit, *this);
}
void DIEBuilder::updateReferences() {
for (auto &[SrcDIEInfo, ReferenceInfo] : getState().AddrReferences) {
DIEInfo *DstDIEInfo = ReferenceInfo.Dst;

View File

@ -31,6 +31,7 @@
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <unordered_map>
#include <vector>
@ -867,10 +868,17 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit,
DIEBuilder &DIEBldr) {
std::optional<AttrInfo> AttrVal =
findAttributeInfo(Unit.getUnitDIE(), dwarf::DW_AT_str_offsets_base);
if (!AttrVal)
if (!AttrVal && !Unit.isDWOUnit())
return;
std::optional<uint64_t> Val = AttrVal->V.getAsSectionOffset();
assert(Val && "DW_AT_str_offsets_base Value not present.");
std::optional<uint64_t> Val = std::nullopt;
if (AttrVal) {
Val = AttrVal->V.getAsSectionOffset();
} else {
if (!Unit.isDWOUnit())
BC.errs() << "BOLT-WARNING: [internal-dwarf-error]: "
"DW_AT_str_offsets_base Value not present\n";
Val = 0;
}
DIE &Die = *DIEBldr.getUnitDIEbyUnit(Unit);
DIEValue StrListBaseAttrInfo =
Die.findAttribute(dwarf::DW_AT_str_offsets_base);
@ -915,7 +923,11 @@ void DebugStrWriter::create() {
}
void DebugStrWriter::initialize() {
auto StrSection = BC.DwCtx->getDWARFObj().getStrSection();
StringRef StrSection;
if (IsDWO)
StrSection = DwCtx.getDWARFObj().getStrDWOSection();
else
StrSection = DwCtx.getDWARFObj().getStrSection();
(*StrStream) << StrSection;
}

View File

@ -458,32 +458,6 @@ static std::optional<uint64_t> getAsAddress(const DWARFUnit &DU,
return std::nullopt;
}
/// Returns DWO Name to be used. Handles case where user specifies output DWO
/// directory, and there are duplicate names. Assumes DWO ID is unique.
static std::string
getDWOName(llvm::DWARFUnit &CU,
std::unordered_map<std::string, uint32_t> &NameToIndexMap) {
std::optional<uint64_t> DWOId = CU.getDWOId();
assert(DWOId && "DWO ID not found.");
(void)DWOId;
std::string DWOName = dwarf::toString(
CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
"");
assert(!DWOName.empty() &&
"DW_AT_dwo_name/DW_AT_GNU_dwo_name does not exists.");
if (!opts::DwarfOutputPath.empty()) {
DWOName = std::string(sys::path::filename(DWOName));
auto Iter = NameToIndexMap.find(DWOName);
if (Iter == NameToIndexMap.end())
Iter = NameToIndexMap.insert({DWOName, 0}).first;
DWOName.append(std::to_string(Iter->second));
++Iter->second;
}
DWOName.append(".dwo");
return DWOName;
}
static std::unique_ptr<DIEStreamer>
createDIEStreamer(const Triple &TheTriple, raw_pwrite_stream &OutFile,
StringRef Swift5ReflectionSegmentName, DIEBuilder &DIEBldr,
@ -515,7 +489,9 @@ static void emitDWOBuilder(const std::string &DWOName,
DIEBuilder &DWODIEBuilder, DWARFRewriter &Rewriter,
DWARFUnit &SplitCU, DWARFUnit &CU,
DWARFRewriter::DWPState &State,
DebugLocWriter &LocWriter) {
DebugLocWriter &LocWriter,
DebugStrOffsetsWriter &StrOffstsWriter,
DebugStrWriter &StrWriter) {
// Populate debug_info and debug_abbrev for current dwo into StringRef.
DWODIEBuilder.generateAbbrevs();
DWODIEBuilder.finish();
@ -577,54 +553,10 @@ static void emitDWOBuilder(const std::string &DWOName,
}
if (opts::WriteDWP)
Rewriter.updateDWP(CU, OverriddenSections, CUMI, TUMetaVector, State,
LocWriter);
LocWriter, StrOffstsWriter, StrWriter);
else
Rewriter.writeDWOFiles(CU, OverriddenSections, DWOName, LocWriter);
}
/// Adds a \p Str to .debug_str section.
/// Uses \p AttrInfoVal to either update entry in a DIE for legacy DWARF using
/// \p DebugInfoPatcher, or for DWARF5 update an index in .debug_str_offsets
/// for this contribution of \p Unit.
static void addStringHelper(DebugStrOffsetsWriter &StrOffstsWriter,
DebugStrWriter &StrWriter, DIEBuilder &DIEBldr,
DIE &Die, const DWARFUnit &Unit,
DIEValue &DIEAttrInfo, StringRef Str) {
uint32_t NewOffset = StrWriter.addString(Str);
if (Unit.getVersion() >= 5) {
StrOffstsWriter.updateAddressMap(DIEAttrInfo.getDIEInteger().getValue(),
NewOffset);
return;
}
DIEBldr.replaceValue(&Die, DIEAttrInfo.getAttribute(), DIEAttrInfo.getForm(),
DIEInteger(NewOffset));
}
static std::string
updateDWONameCompDir(DebugStrOffsetsWriter &StrOffstsWriter,
DebugStrWriter &StrWriter,
std::unordered_map<std::string, uint32_t> &NameToIndexMap,
DWARFUnit &Unit, DIEBuilder &DIEBldr, DIE &UnitDIE) {
DIEValue DWONameAttrInfo = UnitDIE.findAttribute(dwarf::DW_AT_dwo_name);
if (!DWONameAttrInfo)
DWONameAttrInfo = UnitDIE.findAttribute(dwarf::DW_AT_GNU_dwo_name);
assert(DWONameAttrInfo && "DW_AT_dwo_name is not in Skeleton CU.");
std::string ObjectName;
ObjectName = getDWOName(Unit, NameToIndexMap);
addStringHelper(StrOffstsWriter, StrWriter, DIEBldr, UnitDIE, Unit,
DWONameAttrInfo, ObjectName.c_str());
DIEValue CompDirAttrInfo = UnitDIE.findAttribute(dwarf::DW_AT_comp_dir);
assert(CompDirAttrInfo && "DW_AT_comp_dir is not in Skeleton CU.");
if (!opts::DwarfOutputPath.empty()) {
if (!sys::fs::exists(opts::DwarfOutputPath))
sys::fs::create_directory(opts::DwarfOutputPath);
addStringHelper(StrOffstsWriter, StrWriter, DIEBldr, UnitDIE, Unit,
CompDirAttrInfo, opts::DwarfOutputPath.c_str());
}
return ObjectName;
Rewriter.writeDWOFiles(CU, OverriddenSections, DWOName, LocWriter,
StrOffstsWriter, StrWriter);
}
using DWARFUnitVec = std::vector<DWARFUnit *>;
@ -673,9 +605,8 @@ void DWARFRewriter::updateDebugInfo() {
return;
ARangesSectionWriter = std::make_unique<DebugARangesSectionWriter>();
StrWriter = std::make_unique<DebugStrWriter>(BC);
StrOffstsWriter = std::make_unique<DebugStrOffsetsWriter>();
StrWriter = std::make_unique<DebugStrWriter>(*BC.DwCtx, false);
StrOffstsWriter = std::make_unique<DebugStrOffsetsWriter>(BC);
if (!opts::DeterministicDebugInfo) {
opts::DeterministicDebugInfo = true;
@ -720,10 +651,6 @@ void DWARFRewriter::updateDebugInfo() {
return LocListWritersByCU[CUIndex++].get();
};
// Unordered maps to handle name collision if output DWO directory is
// specified.
std::unordered_map<std::string, uint32_t> NameToIndexMap;
DWARF5AcceleratorTable DebugNamesTable(opts::CreateDebugNames, BC,
*StrWriter);
DWPState State;
@ -747,13 +674,20 @@ void DWARFRewriter::updateDebugInfo() {
Unit);
DWODIEBuilder.buildDWOUnit(**SplitCU);
std::string DWOName = "";
std::optional<std::string> DwarfOutputPath =
opts::DwarfOutputPath.empty()
? std::nullopt
: std::optional<std::string>(opts::DwarfOutputPath.c_str());
{
std::lock_guard<std::mutex> Lock(AccessMutex);
DWOName = updateDWONameCompDir(*StrOffstsWriter, *StrWriter,
NameToIndexMap, *Unit, *DIEBlder,
*DIEBlder->getUnitDIEbyUnit(*Unit));
DWOName = DIEBlder->updateDWONameCompDir(
*StrOffstsWriter, *StrWriter, *Unit, DwarfOutputPath, std::nullopt);
}
DebugStrOffsetsWriter DWOStrOffstsWriter(BC);
DebugStrWriter DWOStrWriter((*SplitCU)->getContext(), true);
DWODIEBuilder.updateDWONameCompDirForTypes(DWOStrOffstsWriter,
DWOStrWriter, **SplitCU,
DwarfOutputPath, DWOName);
DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true);
DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter;
if (Unit->getVersion() >= 5) {
@ -771,7 +705,7 @@ void DWARFRewriter::updateDebugInfo() {
TempRangesSectionWriter->finalizeSection();
emitDWOBuilder(DWOName, DWODIEBuilder, *this, **SplitCU, *Unit, State,
DebugLocDWoWriter);
DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter);
}
if (Unit->getVersion() >= 5) {
@ -1736,6 +1670,7 @@ std::optional<StringRef> updateDebugData(
const DWARFUnitIndex::Entry *CUDWOEntry, uint64_t DWOId,
std::unique_ptr<DebugBufferVector> &OutputBuffer,
DebugRangeListsSectionWriter *RangeListsWriter, DebugLocWriter &LocWriter,
DebugStrOffsetsWriter &StrOffstsWriter, DebugStrWriter &StrWriter,
const llvm::bolt::DWARFRewriter::OverriddenSectionsMap &OverridenSections) {
using DWOSectionContribution =
@ -1774,6 +1709,11 @@ std::optional<StringRef> updateDebugData(
if (SectionName != "debug_str.dwo")
errs() << "BOLT-WARNING: unsupported debug section: " << SectionName
<< "\n";
if (StrWriter.isInitialized()) {
OutputBuffer = StrWriter.releaseBuffer();
return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()),
OutputBuffer->size());
}
return SectionContents;
}
case DWARFSectionKind::DW_SECT_INFO: {
@ -1783,6 +1723,11 @@ std::optional<StringRef> updateDebugData(
return getOverridenSection(DWARFSectionKind::DW_SECT_EXT_TYPES);
}
case DWARFSectionKind::DW_SECT_STR_OFFSETS: {
if (StrOffstsWriter.isFinalized()) {
OutputBuffer = StrOffstsWriter.releaseBuffer();
return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()),
OutputBuffer->size());
}
return getSliceData(CUDWOEntry, SectionContents,
DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset);
}
@ -1884,7 +1829,9 @@ void DWARFRewriter::updateDWP(DWARFUnit &CU,
const OverriddenSectionsMap &OverridenSections,
const DWARFRewriter::UnitMeta &CUMI,
DWARFRewriter::UnitMetaVectorType &TUMetaVector,
DWPState &State, DebugLocWriter &LocWriter) {
DWPState &State, DebugLocWriter &LocWriter,
DebugStrOffsetsWriter &StrOffstsWriter,
DebugStrWriter &StrWriter) {
const uint64_t DWOId = *CU.getDWOId();
MCSection *const StrOffsetSection = State.MCOFI->getDwarfStrOffDWOSection();
assert(StrOffsetSection && "StrOffsetSection does not exist.");
@ -1941,15 +1888,18 @@ void DWARFRewriter::updateDWP(DWARFUnit &CU,
TUEntry.Contributions[Index].getLength32();
State.TypeIndexEntries.insert(std::make_pair(Hash, TUEntry));
};
std::unique_ptr<DebugBufferVector> StrOffsetsOutputData;
std::unique_ptr<DebugBufferVector> StrOutputData;
for (const SectionRef &Section : DWOFile->sections()) {
std::unique_ptr<DebugBufferVector> OutputData;
std::unique_ptr<DebugBufferVector> OutputData = nullptr;
StringRef SectionName = getSectionName(Section);
Expected<StringRef> ContentsExp = Section.getContents();
assert(ContentsExp && "Invalid contents.");
std::optional<StringRef> TOutData = updateDebugData(
(*DWOCU)->getContext(), SectionName, *ContentsExp, State.KnownSections,
*State.Streamer, *this, CUDWOEntry, DWOId, OutputData,
RangeListssWriter, LocWriter, OverridenSections);
std::optional<StringRef> TOutData =
updateDebugData((*DWOCU)->getContext(), SectionName, *ContentsExp,
State.KnownSections, *State.Streamer, *this, CUDWOEntry,
DWOId, OutputData, RangeListssWriter, LocWriter,
StrOffstsWriter, StrWriter, OverridenSections);
if (!TOutData)
continue;
@ -1961,14 +1911,17 @@ void DWARFRewriter::updateDWP(DWARFUnit &CU,
if (SectionName == "debug_str.dwo") {
CurStrSection = OutData;
StrOutputData = std::move(OutputData);
} else {
// Since handleDebugDataPatching returned true, we already know this is
// a known section.
auto SectionIter = State.KnownSections.find(SectionName);
if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS)
if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS) {
CurStrOffsetSection = OutData;
else
StrOffsetsOutputData = std::move(OutputData);
} else {
State.Streamer->emitBytes(OutData);
}
unsigned int Index =
getContributionIndex(SectionIter->second.second, State.IndexVersion);
uint64_t Offset = State.ContributionOffsets[Index];
@ -1992,6 +1945,10 @@ void DWARFRewriter::updateDWP(DWARFUnit &CU,
// based on hash.
if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() &&
!CurStrSection.empty()) {
// If debug_str.dwo section was modified storing it until dwp is written
// out. DWPStringPool stores raw pointers to strings.
if (StrOutputData)
State.StrSections.push_back(std::move(StrOutputData));
writeStringsAndOffsets(*State.Streamer.get(), *State.Strings.get(),
StrOffsetSection, CurStrSection,
CurStrOffsetSection, CU.getVersion());
@ -2017,7 +1974,8 @@ void DWARFRewriter::updateDWP(DWARFUnit &CU,
void DWARFRewriter::writeDWOFiles(
DWARFUnit &CU, const OverriddenSectionsMap &OverridenSections,
const std::string &DWOName, DebugLocWriter &LocWriter) {
const std::string &DWOName, DebugLocWriter &LocWriter,
DebugStrOffsetsWriter &StrOffstsWriter, DebugStrWriter &StrWriter) {
// Setup DWP code once.
DWARFContext *DWOCtx = BC.getDWOContext();
const uint64_t DWOId = *CU.getDWOId();
@ -2072,10 +2030,11 @@ void DWARFRewriter::writeDWOFiles(
// have .debug_rnglists so won't be part of the loop below.
if (!RangeListssWriter->empty()) {
std::unique_ptr<DebugBufferVector> OutputData;
if (std::optional<StringRef> OutData = updateDebugData(
(*DWOCU)->getContext(), "debug_rnglists.dwo", "", KnownSections,
*Streamer, *this, CUDWOEntry, DWOId, OutputData,
RangeListssWriter, LocWriter, OverridenSections))
if (std::optional<StringRef> OutData =
updateDebugData((*DWOCU)->getContext(), "debug_rnglists.dwo", "",
KnownSections, *Streamer, *this, CUDWOEntry,
DWOId, OutputData, RangeListssWriter, LocWriter,
StrOffstsWriter, StrWriter, OverridenSections))
Streamer->emitBytes(*OutData);
}
}
@ -2090,7 +2049,7 @@ void DWARFRewriter::writeDWOFiles(
if (std::optional<StringRef> OutData = updateDebugData(
(*DWOCU)->getContext(), SectionName, *ContentsExp, KnownSections,
*Streamer, *this, CUDWOEntry, DWOId, OutputData, RangeListssWriter,
LocWriter, OverridenSections))
LocWriter, StrOffstsWriter, StrWriter, OverridenSections))
Streamer->emitBytes(*OutData);
}
Streamer->finish();

View File

@ -207,7 +207,7 @@ main: # @main
.Linfo_string5:
.asciz "f2" # string offset=24
.Linfo_string6:
.asciz "/home/ayermolo/local/tasks/T138552329/typeDedupSplit" # string offset=27
.asciz "." # string offset=27
.Linfo_string7:
.asciz "main.dwo" # string offset=80
.Linfo_string8:
@ -234,15 +234,15 @@ main: # @main
.long 19
.long 24
.long 27
.long 80
.long 89
.long 92
.long 97
.long 100
.long 103
.long 106
.long 112
.long 220
.long 29
.long 38
.long 41
.long 46
.long 49
.long 52
.long 55
.long 61
.long 169
.section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end2-.Ldebug_info_dwo_start2 # Length of Unit
.Ldebug_info_dwo_start2:
@ -474,7 +474,7 @@ main: # @main
.byte 1
.byte 8
.byte 2
.ascii "/home/ayermolo/local/tasks/T138552329/typeDedupSplit"
.ascii "."
.byte 0
.byte 46
.byte 0

View File

@ -0,0 +1,198 @@
; RUN: rm -rf %t
; RUN: mkdir %t
; RUN: cd %t
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-debug-names-main.s \
; RUN: -split-dwarf-file=main.dwo -o main.o
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-dup-helper.s \
; RUN: -split-dwarf-file=helper.dwo -o helper.o
; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
; RUN: llvm-dwarfdump --debug-info -r 0 main.exe.bolt > log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 helper.dwo.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets main.dwo.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets helper.dwo.dwo >> log.txt
; RUN: cat log.txt | FileCheck -check-prefix=BOLT %s
;; Test is a mix of DWARF5 TUs where one has DW_AT_comp_dir/DW_AT_dwo_name, and another one doesn't.
;; Tests that BOLT correctly updates DW_AT_dwo_name for TUs.
; BOLT: DW_TAG_skeleton_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT: DW_TAG_skeleton_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("helper.dwo.dwo")
; BOLT: DW_TAG_type_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT: DW_TAG_type_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT: DW_TAG_type_unit
; BOLT-NOT: DW_AT_dwo_name
; BOLT: DW_TAG_type_unit
; BOLT-NOT: DW_AT_dwo_name
; BOLT: DW_TAG_compile_unit
; BOLT: .debug_str_offsets.dwo contents:
; BOLT-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5
; BOLT-NEXT: "main"
; BOLT-NEXT: "int"
; BOLT-NEXT: "argc"
; BOLT-NEXT: "argv"
; BOLT-NEXT: "char"
; BOLT-NEXT: "f2"
; BOLT-NEXT: "."
; BOLT-NEXT: "main.dwo.dwo"
; BOLT-NEXT: "c1"
; BOLT-NEXT: "Foo2"
; BOLT-NEXT: "f3"
; BOLT-NEXT: "c2"
; BOLT-NEXT: "c3"
; BOLT-NEXT: "Foo2a"
; BOLT-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
; BOLT-NEXT: "main.cpp"
; BOLT-NEXT: helper.dwo.dwo: file format elf64-x86-64
; BOLT: .debug_str_offsets.dwo contents:
; BOLT-NEXT: 0x00000000: Contribution size = 64, Format = DWARF32, Version = 5
; BOLT-NEXT: "fooint"
; BOLT-NEXT: "int"
; BOLT-NEXT: "_Z3foov"
; BOLT-NEXT: "foo"
; BOLT-NEXT: "fint"
; BOLT-NEXT: "c1"
; BOLT-NEXT: "c2"
; BOLT-NEXT: "Foo2Int"
; BOLT-NEXT: "f"
; BOLT-NEXT: "char"
; BOLT-NEXT: "c3"
; BOLT-NEXT: "Foo2a"
; BOLT-NEXT: "clang version 18.0.0"
; BOLT-NEXT: "helper.cpp"
; BOLT-NEXT: "helper.dwo"
;; Tests that BOLT correctly handles updating DW_AT_dwo_name when it outputs a DWP file.
;; Currently skipping one of Type units because it is not being de-dupped.
;; In the tu-index this TU is not present.
; RUN: rm main.exe.bolt
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp
; RUN: llvm-dwarfdump --debug-info -r 0 main.exe.bolt.dwp > logDWP.txt
; RUN: llvm-dwarfdump --debug-str-offsets main.exe.bolt.dwp >> logDWP.txt
; RUN: cat logDWP.txt | FileCheck -check-prefix=BOLT-DWP %s
; BOLT-DWP: DW_TAG_type_unit
; BOLT-DWP: DW_AT_comp_dir (".")
; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT-DWP: DW_TAG_type_unit
; BOLT-DWP: DW_AT_comp_dir (".")
; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT-DWP: DW_TAG_compile_unit
; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT-DWP: DW_TAG_type_unit
; BOLT-DW-NOT: DW_AT_dwo_name
; BOLT-DWP: Contribution size = 68, Format = DWARF32, Version = 5
; BOLT-DWP-NEXT: "main"
; BOLT-DWP-NEXT: "int"
; BOLT-DWP-NEXT: "argc"
; BOLT-DWP-NEXT: "argv"
; BOLT-DWP-NEXT: "char"
; BOLT-DWP-NEXT: "f2"
; BOLT-DWP-NEXT: "."
; BOLT-DWP-NEXT: "main.dwo.dwo"
; BOLT-DWP-NEXT: "c1"
; BOLT-DWP-NEXT: "Foo2"
; BOLT-DWP-NEXT: "f3"
; BOLT-DWP-NEXT: "c2"
; BOLT-DWP-NEXT: "c3"
; BOLT-DWP-NEXT: "Foo2a"
; BOLT-DWP-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
; BOLT-DWP-NEXT: "main.cpp"
; BOLT-DWP-NEXT: Contribution size = 64, Format = DWARF32, Version = 5
; BOLT-DWP-NEXT: "fooint"
; BOLT-DWP-NEXT: "int"
; BOLT-DWP-NEXT: "_Z3foov"
; BOLT-DWP-NEXT: "foo"
; BOLT-DWP-NEXT: "fint"
; BOLT-DWP-NEXT: "c1"
; BOLT-DWP-NEXT: "c2"
; BOLT-DWP-NEXT: "Foo2Int"
; BOLT-DWP-NEXT: "f"
; BOLT-DWP-NEXT: "char"
; BOLT-DWP-NEXT: "c3"
; BOLT-DWP-NEXT: "Foo2a"
; BOLT-DWP-NEXT: "clang version 18.0.0"
; BOLT-DWP-NEXT: "helper.cpp"
; BOLT-DWP-NEXT: "helper.dwo
;; Tests that BOLT correctly handles updating DW_AT_comp_dir/DW_AT_dwo_name when outptut directory is specified.
; RUN: mkdir DWOOut
; RUN: rm main.exe.bolt
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --dwarf-output-path=%t/DWOOut
; RUN: cd DWOOut
; RUN: llvm-dwarfdump --debug-info -r 0 ../main.exe.bolt > log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo0.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 helper.dwo0.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets main.dwo0.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets helper.dwo0.dwo >> log.txt
; RUN: cat log.txt | FileCheck -check-prefix=BOLT-PATH %s
; BOLT-PATH: DW_TAG_skeleton_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name-mixed.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("main.dwo0.dwo")
; BOLT-PATH: DW_TAG_skeleton_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name-mixed.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("helper.dwo0.dwo")
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name-mixed.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("main.dwo0.dwo")
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name-mixed.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("main.dwo0.dwo")
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH-NOT: DW_AT_comp_dir
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH-NOT: DW_AT_comp_dir
; BOLT-PATH: DW_TAG_compile_unit
; BOLT-PATH: .debug_str_offsets.dwo contents:
; BOLT-PATH-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5
; BOLT-PATH-NEXT: "main"
; BOLT-PATH-NEXT: "int"
; BOLT-PATH-NEXT: "argc"
; BOLT-PATH-NEXT: "argv"
; BOLT-PATH-NEXT: "char"
; BOLT-PATH-NEXT: "f2"
; BOLT-PATH-NEXT: dwarf5-df-types-modify-dwo-name-mixed.test.tmp/DWOOut"
; BOLT-PATH-NEXT: "main.dwo0.dwo"
; BOLT-PATH-NEXT: "c1"
; BOLT-PATH-NEXT: "Foo2"
; BOLT-PATH-NEXT: "f3"
; BOLT-PATH-NEXT: "c2"
; BOLT-PATH-NEXT: "c3"
; BOLT-PATH-NEXT: "Foo2a"
; BOLT-PATH-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
; BOLT-PATH-NEXT: "main.cpp"
; BOLT-PATH-NEXT: helper.dwo0.dwo: file format elf64-x86-64
; BOLT-PATH: .debug_str_offsets.dwo contents:
; BOLT-PATH-NEXT: Contribution size = 64, Format = DWARF32, Version = 5
; BOLT-PATH-NEXT: "fooint"
; BOLT-PATH-NEXT: "int"
; BOLT-PATH-NEXT: "_Z3foov"
; BOLT-PATH-NEXT: "foo"
; BOLT-PATH-NEXT: "fint"
; BOLT-PATH-NEXT: "c1"
; BOLT-PATH-NEXT: "c2"
; BOLT-PATH-NEXT: "Foo2Int"
; BOLT-PATH-NEXT: "f"
; BOLT-PATH-NEXT: "char"
; BOLT-PATH-NEXT: "c3"
; BOLT-PATH-NEXT: "Foo2a"
; BOLT-PATH-NEXT: "clang version 18.0.0"
; BOLT-PATH-NEXT: "helper.cpp"
; BOLT-PATH-NEXT: "helper.dwo"

View File

@ -0,0 +1,175 @@
; RUN: rm -rf %t
; RUN: mkdir %t
; RUN: cd %t
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-debug-names-main.s \
; RUN: -split-dwarf-file=main.dwo -o main.o
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-types-debug-names-helper.s \
; RUN: -split-dwarf-file=helper.dwo -o helper.o
; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
; RUN: llvm-dwarfdump --debug-info -r 0 main.exe.bolt > log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 helper.dwo.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets main.dwo.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets helper.dwo.dwo >> log.txt
; RUN: cat log.txt | FileCheck -check-prefix=BOLT %s
;; Tests that BOLT correctly updates DW_AT_dwo_name for TU Untis.
; BOLT: DW_TAG_skeleton_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT: DW_TAG_skeleton_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("helper.dwo.dwo")
; BOLT: DW_TAG_type_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT: DW_TAG_type_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT: DW_TAG_type_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("helper.dwo.dwo")
; BOLT: DW_TAG_type_unit
; BOLT: DW_AT_comp_dir (".")
; BOLT: DW_AT_dwo_name ("helper.dwo.dwo")
; BOLT: .debug_str_offsets.dwo contents:
; BOLT-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5
; BOLT-NEXT: "main"
; BOLT-NEXT: "int"
; BOLT-NEXT: "argc"
; BOLT-NEXT: "argv"
; BOLT-NEXT: "char"
; BOLT-NEXT: "f2"
; BOLT-NEXT: "."
; BOLT-NEXT: "main.dwo.dwo"
; BOLT-NEXT: "c1"
; BOLT-NEXT: "Foo2"
; BOLT-NEXT: "f3"
; BOLT-NEXT: "c2"
; BOLT-NEXT: "c3"
; BOLT-NEXT: "Foo2a"
; BOLT-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
; BOLT-NEXT: "main.cpp"
; BOLT-NEXT: helper.dwo.dwo: file format elf64-x86-64
; BOLT: .debug_str_offsets.dwo contents:
; BOLT-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5
; BOLT-NEXT: "fooint"
; BOLT-NEXT: "int"
; BOLT-NEXT: "_Z3foov"
; BOLT-NEXT: "foo"
; BOLT-NEXT: "fint"
; BOLT-NEXT: "."
; BOLT-NEXT: "helper.dwo.dwo"
; BOLT-NEXT: "c1"
; BOLT-NEXT: "c2"
; BOLT-NEXT: "Foo2Int"
; BOLT-NEXT: "f"
; BOLT-NEXT: "char"
; BOLT-NEXT: "c3"
; BOLT-NEXT: "Foo2a"
; BOLT-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
; BOLT-NEXT: "helper.cpp"
;; Tests that BOLT correctly handles updating DW_AT_dwo_name when it outputs a DWP file.
;; Currently skipping one of Type units because it is not being de-dupped.
;; In the tu-index this TU is not present.
; RUN: rm main.exe.bolt
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp
; RUN: llvm-dwarfdump --debug-info -r 0 main.exe.bolt.dwp > logDWP.txt
; RUN: llvm-dwarfdump --debug-str-offsets main.exe.bolt.dwp >> logDWP.txt
; RUN: cat logDWP.txt | FileCheck -check-prefix=BOLT-DWP %s
; BOLT-DWP: DW_TAG_type_unit
; BOLT-DWP: DW_AT_comp_dir (".")
; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT-DWP: DW_TAG_type_unit
; BOLT-DWP: DW_AT_comp_dir (".")
; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT-DWP: DW_TAG_compile_unit
; BOLT-DWP: DW_AT_dwo_name ("main.dwo.dwo")
; BOLT-DWP: DW_TAG_type_unit
; BOLT-DWP: DW_AT_comp_dir (".")
; BOLT-DWP: DW_AT_dwo_name ("helper.dwo.dwo")
; BOLT-DWP: DW_TAG_type_unit
; BOLT-DWP: DW_TAG_compile_unit
; BOLT-DWP: DW_AT_name ("helper.cpp")
; BOLT-DWP: DW_AT_dwo_name ("helper.dwo.dwo")
;; Tests that BOLT correctly handles updating DW_AT_comp_dir/DW_AT_dwo_name when outptut directory is specified.
; RUN: mkdir DWOOut
; RUN: rm main.exe.bolt
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --dwarf-output-path=%t/DWOOut
; RUN: cd DWOOut
; RUN: llvm-dwarfdump --debug-info -r 0 ../main.exe.bolt > log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo0.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-info -r 0 helper.dwo0.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets main.dwo0.dwo >> log.txt
; RUN: llvm-dwarfdump --debug-str-offsets helper.dwo0.dwo >> log.txt
; RUN: cat log.txt | FileCheck -check-prefix=BOLT-PATH %s
; BOLT-PATH: DW_TAG_skeleton_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("main.dwo0.dwo")
; BOLT-PATH: DW_TAG_skeleton_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("helper.dwo0.dwo")
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("main.dwo0.dwo")
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("main.dwo0.dwo")
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("helper.dwo0.dwo")
; BOLT-PATH: DW_TAG_type_unit
; BOLT-PATH: DW_AT_comp_dir ("
; BOLT-PATH-SAME: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut
; BOLT-PATH: DW_AT_dwo_name ("helper.dwo0.dwo")
; BOLT-PATH: .debug_str_offsets.dwo contents:
; BOLT-PATH-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5
; BOLT-PATH-NEXT: "main"
; BOLT-PATH-NEXT: "int"
; BOLT-PATH-NEXT: "argc"
; BOLT-PATH-NEXT: "argv"
; BOLT-PATH-NEXT: "char"
; BOLT-PATH-NEXT: "f2"
; BOLT-PATH-NEXT: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut"
; BOLT-PATH-NEXT: "main.dwo0.dwo"
; BOLT-PATH-NEXT: "c1"
; BOLT-PATH-NEXT: "Foo2"
; BOLT-PATH-NEXT: "f3"
; BOLT-PATH-NEXT: "c2"
; BOLT-PATH-NEXT: "c3"
; BOLT-PATH-NEXT: "Foo2a"
; BOLT-PATH-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
; BOLT-PATH-NEXT: "main.cpp"
; BOLT-PATH-NEXT: helper.dwo0.dwo: file format elf64-x86-64
; BOLT-PATH: .debug_str_offsets.dwo contents:
; BOLT-PATH-NEXT: 0x00000000: Contribution size = 68, Format = DWARF32, Version = 5
; BOLT-PATH-NEXT: "fooint"
; BOLT-PATH-NEXT: "int"
; BOLT-PATH-NEXT: "_Z3foov"
; BOLT-PATH-NEXT: "foo"
; BOLT-PATH-NEXT: "fint"
; BOLT-PATH-NEXT: dwarf5-df-types-modify-dwo-name.test.tmp/DWOOut"
; BOLT-PATH-NEXT: "helper.dwo0.dwo"
; BOLT-PATH-NEXT: "c1"
; BOLT-PATH-NEXT: "c2"
; BOLT-PATH-NEXT: "Foo2Int"
; BOLT-PATH-NEXT: "f"
; BOLT-PATH-NEXT: "char"
; BOLT-PATH-NEXT: "c3"
; BOLT-PATH-NEXT: "Foo2a"
; BOLT-PATH-NEXT: "clang version 18.0.0git (git@github.com:ayermolo/llvm-project.git db35fa8fc524127079662802c4735dbf397f86d0)"
; BOLT-PATH-NEXT: "helper.cpp"