Disassemble global variables with initialisers properly

This commit is contained in:
baldurk committed 2020-06-18 17:22:41 +01:00
1 parent c8742a1456
commit 8b57989b3f
3 files changed
+66 -23

No files matched your search

@@ -419,7 +419,19 @@ Program::Program(const byte *bytes, size_t length)
GlobalVar g;
g.type = &m_Types[(size_t)rootchild.ops[0]];
g.isconst = (rootchild.ops[1] & 0x1);
if(rootchild.ops[1] & 0x1)
g.flags |= GlobalFlags::IsConst;
if(rootchild.ops.size() > 8)
{
if(rootchild.ops[8] == 1)
g.flags |= GlobalFlags::GlobalUnnamedAddr;
else if(rootchild.ops[8] == 2)
g.flags |= GlobalFlags::LocalUnnamedAddr;
}
if(rootchild.ops[2])
g.initialiser = Symbol(SymbolType::Constant, rootchild.ops[2] - 1);
switch(rootchild.ops[3])
{
@@ -427,8 +439,8 @@ Program::Program(const byte *bytes, size_t length)
case 5:
case 6:
case 7:
case 15: g.external = true; break;
default: g.external = false; break;
case 15: g.flags |= GlobalFlags::IsExternal; break;
default: break;
}
g.align = (1U << rootchild.ops[4]) >> 1;
@@ -454,6 +466,8 @@ Program::Program(const byte *bytes, size_t length)
if(v.type == g.type)
RDCERR("Expected to find pointer type for global variable");
g.type = v.type;
m_Values.push_back(v);
m_GlobalVars.push_back(g);
}
+26 -15
View File
@@ -78,20 +78,6 @@ struct Type
rdcarray<const Type *> members; // the members for a struct, the parameters for functions
};
struct GlobalVar
{
rdcstr name;
const Type *type = NULL;
bool isconst = false;
bool external = false;
uint64_t align = 0;
};
struct Alias
{
rdcstr name;
};
enum class SymbolType
{
Unknown,
@@ -112,6 +98,31 @@ struct Symbol
uint64_t idx;
};
enum class GlobalFlags : uint32_t
{
NoFlags = 0,
IsConst = 0x1,
IsExternal = 0x2,
LocalUnnamedAddr = 0x4,
GlobalUnnamedAddr = 0x8,
};
BITMASK_OPERATORS(GlobalFlags);
struct GlobalVar
{
rdcstr name;
const Type *type = NULL;
uint64_t align = 0;
GlobalFlags flags = GlobalFlags::NoFlags;
Symbol initialiser;
};
struct Alias
{
rdcstr name;
};
// this enum is ordered to match the serialised order of these attributes
enum class Attribute : uint64_t
{
@@ -183,7 +194,7 @@ struct Value
ShaderValue val = {};
rdcarray<Value> members;
rdcstr str;
bool undef = false, nullconst = true, symbol = false;
bool undef = false, nullconst = false, symbol = false;
rdcstr toString(bool withType = false) const;
};
@@ -336,11 +336,21 @@ void Program::MakeDisassemblyString()
const GlobalVar &g = m_GlobalVars[i];
m_Disassembly += StringFormat::Fmt("@%s = ", escapeStringIfNeeded(g.name).c_str());
if(g.external)
if(g.flags & GlobalFlags::IsExternal)
m_Disassembly += "external ";
if(g.isconst)
else
m_Disassembly += "internal ";
if(g.flags & GlobalFlags::LocalUnnamedAddr)
m_Disassembly += "local_unnamed_addr ";
else if(g.flags & GlobalFlags::GlobalUnnamedAddr)
m_Disassembly += "unnamed_addr ";
if(g.flags & GlobalFlags::IsConst)
m_Disassembly += "constant ";
m_Disassembly += g.type->toString();
if(g.initialiser.type == SymbolType::Constant)
m_Disassembly += m_Values[g.initialiser.idx].toString(true);
else
m_Disassembly += g.type->inner->toString();
if(g.align > 0)
m_Disassembly += StringFormat::Fmt(", align %u", g.align);
@@ -395,6 +405,8 @@ void Program::MakeDisassemblyString()
Metadata &m = m_Metadata[s.idx];
if(m.value && m.val && m.val->nullconst)
ret += StringFormat::Fmt("%s zeroinitializer", m.val->type->toString());
else if(m.value && m.val && m.val->symbol)
ret += m.val->toString(true);
else
ret += StringFormat::Fmt("!%u", GetOrAssignMetaID(&m));
}
@@ -405,10 +417,16 @@ void Program::MakeDisassemblyString()
break;
case SymbolType::Function: ret = "@" + escapeStringIfNeeded(m_Functions[s.idx].name); break;
case SymbolType::GlobalVar:
ret = "@" + escapeStringIfNeeded(m_GlobalVars[s.idx].name);
if(withTypes)
ret = m_GlobalVars[s.idx].type->toString() + " ";
ret += "@" + escapeStringIfNeeded(m_GlobalVars[s.idx].name);
break;
case SymbolType::Constant: ret = GetFunctionValue(func, s.idx)->toString(withTypes); break;
case SymbolType::Argument: ret = "%" + escapeStringIfNeeded(func.args[s.idx].name); break;
case SymbolType::Argument:
if(withTypes)
ret = func.args[s.idx].type->toString() + " ";
ret += "%" + escapeStringIfNeeded(func.args[s.idx].name);
break;
case SymbolType::Instruction:
{
const Instruction &refinst = func.instructions[s.idx];