Handle explicit debug info

* Some locations are given as metadata even though most appear through
  DEBUG_LOC, so ensure we handle these.
This commit is contained in:
baldurk
2020-06-09 14:51:09 +01:00
parent 8b57989b3f
commit 08cd7ae0e0
5 changed files with 64 additions and 30 deletions
@@ -1804,6 +1804,11 @@ uint32_t Program::GetOrAssignMetaID(DebugLocation &l)
l.id = m_NextMetaID++;
if(l.scope)
GetOrAssignMetaID(l.scope);
if(l.inlinedAt)
GetOrAssignMetaID(l.inlinedAt);
return l.id;
}
@@ -1886,6 +1891,6 @@ const DXIL::Type *Program::GetBoolType()
Metadata::~Metadata()
{
SAFE_DELETE(dwarf);
SAFE_DELETE(debugLoc);
}
}; // namespace DXIL
+21 -16
View File
@@ -222,7 +222,7 @@ struct DIBase
DIBase(Type t) : type(t) {}
virtual ~DIBase() = default;
virtual rdcstr toString() const = 0;
virtual void setID(uint32_t ID) {}
template <typename Derived>
const Derived *As() const
{
@@ -233,6 +233,25 @@ struct DIBase
struct Function;
struct Metadata;
struct DebugLocation
{
uint32_t id = ~0U;
uint64_t line = 0;
uint64_t col = 0;
Metadata *scope = NULL;
Metadata *inlinedAt = NULL;
bool operator==(const DebugLocation &o) const
{
return line == o.line && col == o.col && scope == o.scope && inlinedAt == o.inlinedAt;
}
rdcstr toString() const;
};
struct Metadata
{
~Metadata();
@@ -249,6 +268,7 @@ struct Metadata
rdcstr str;
rdcarray<Metadata *> children;
DIBase *dwarf = NULL;
DebugLocation *debugLoc = NULL;
rdcstr refString() const;
rdcstr valString() const;
@@ -259,21 +279,6 @@ struct NamedMetadata : public Metadata
rdcstr name;
};
struct DebugLocation
{
uint32_t id = ~0U;
uint64_t line = 0;
uint64_t col = 0;
const Metadata *scope = NULL;
const Metadata *inlinedAt = NULL;
bool operator==(const DebugLocation &o) const
{
return line == o.line && col == o.col && scope == o.scope && inlinedAt == o.inlinedAt;
}
};
struct Function;
enum class InstructionFlags : uint32_t
@@ -77,6 +77,7 @@ bool Program::ParseDebugMetaRecord(const LLVMBC::BlockOrRecord &metaRecord, Meta
{
MetaDataRecord id = (MetaDataRecord)metaRecord.id;
auto getNonNullMeta = [this](uint64_t id) { return &m_Metadata[size_t(id)]; };
auto getMeta = [this](uint64_t id) { return id ? &m_Metadata[size_t(id - 1)] : NULL; };
auto getMetaString = [this](uint64_t id) { return id ? &m_Metadata[size_t(id - 1)].str : NULL; };
@@ -211,7 +212,15 @@ bool Program::ParseDebugMetaRecord(const LLVMBC::BlockOrRecord &metaRecord, Meta
}
else if(id == MetaDataRecord::LOCATION)
{
RDCWARN("Unexpected location metadata record, ignoring");
meta.distinct = (metaRecord.ops[0] & 0x1);
meta.debugLoc = new DebugLocation;
meta.debugLoc->line = metaRecord.ops[1];
meta.debugLoc->col = metaRecord.ops[2];
meta.debugLoc->scope = getNonNullMeta(metaRecord.ops[3]);
meta.debugLoc->inlinedAt = getMeta(metaRecord.ops[4]);
meta.children = {getNonNullMeta(metaRecord.ops[3]), getMeta(metaRecord.ops[4])};
}
else if(id == MetaDataRecord::LOCAL_VAR)
{
@@ -540,8 +540,8 @@ struct DISubprogram : public DIBase
const Metadata *file, uint64_t line, const Metadata *type, bool isLocal,
bool isDefinition, uint64_t scopeLine, const Metadata *containingType,
DW_VIRTUALITY virtuality, uint64_t virtualIndex, DIFlags flags, bool isOptimized,
const Metadata *function, const Metadata *templateParams,
const Metadata *declaration, const Metadata *variables)
Metadata *function, const Metadata *templateParams, const Metadata *declaration,
const Metadata *variables)
: DIBase(DIType),
scope(scope),
name(name),
@@ -578,11 +578,17 @@ struct DISubprogram : public DIBase
uint64_t virtualIndex;
DIFlags flags;
bool isOptimized;
const Metadata *function;
Metadata *function;
const Metadata *templateParams;
const Metadata *declaration;
const Metadata *variables;
virtual void setID(uint32_t ID)
{
if(function && function->id == ~0U)
function->id = ID;
}
virtual rdcstr toString() const;
};
@@ -891,19 +891,14 @@ void Program::MakeDisassemblyString()
m_Disassembly +=
StringFormat::Fmt("!%u = %s%s\n", i, m_NumberedMeta[numIdx]->distinct ? "distinct " : "",
m_NumberedMeta[numIdx]->valString().c_str());
if(m_NumberedMeta[numIdx]->dwarf)
m_NumberedMeta[numIdx]->dwarf->setID(i);
numIdx++;
}
else if(dbgIdx < m_DebugLocations.size() && m_DebugLocations[dbgIdx].id == i)
{
m_Disassembly += StringFormat::Fmt("!%u = !DILocation(line: %llu, column: %llu, scope: %s", i,
m_DebugLocations[dbgIdx].line, m_DebugLocations[dbgIdx].col,
m_DebugLocations[dbgIdx].scope
? m_DebugLocations[dbgIdx].scope->refString().c_str()
: "null");
if(m_DebugLocations[dbgIdx].inlinedAt)
m_Disassembly +=
StringFormat::Fmt(", inlinedAt: %s", m_DebugLocations[dbgIdx].inlinedAt->refString());
m_Disassembly += ")\n";
m_Disassembly +=
StringFormat::Fmt("!%u = %s\n", i, m_DebugLocations[dbgIdx].toString().c_str());
dbgIdx++;
}
else
@@ -1035,12 +1030,26 @@ rdcstr Metadata::refString() const
return StringFormat::Fmt("!%u", id);
}
rdcstr DebugLocation::toString() const
{
rdcstr ret = StringFormat::Fmt("!DILocation(line: %llu, column: %llu, scope: %s", line, col,
scope ? scope->refString().c_str() : "null");
if(inlinedAt)
ret += StringFormat::Fmt(", inlinedAt: %s", inlinedAt->refString());
ret += ")";
return ret;
}
rdcstr Metadata::valString() const
{
if(dwarf)
{
return dwarf->toString();
}
else if(debugLoc)
{
return debugLoc->toString();
}
else if(value)
{
if(type == NULL)