[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:
parent
5bf653ca42
commit
99fad7ebd8
@ -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
|
||||
|
@ -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 };
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
198
bolt/test/X86/dwarf5-df-types-modify-dwo-name-mixed.test
Normal file
198
bolt/test/X86/dwarf5-df-types-modify-dwo-name-mixed.test
Normal 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"
|
175
bolt/test/X86/dwarf5-df-types-modify-dwo-name.test
Normal file
175
bolt/test/X86/dwarf5-df-types-modify-dwo-name.test
Normal 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"
|
Loading…
x
Reference in New Issue
Block a user