From 0869f338bc199de0745ad97340ac7776a8fd7638 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 3 Jun 2020 17:01:33 +0100 Subject: [PATCH] Handle local debug information metadata --- renderdoc/driver/shaders/dxil/dxil_bytecode.h | 1 + .../driver/shaders/dxil/dxil_debuginfo.cpp | 106 +++++++- .../driver/shaders/dxil/dxil_debuginfo.h | 228 ++++++++++++++++++ 3 files changed, 331 insertions(+), 4 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index 39420171b..c0bef610e 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -206,6 +206,7 @@ struct DIBase LocalVariable, Location, Expression, + LexicalBlock, } type; DIBase(Type t) : type(t) {} diff --git a/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp b/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp index 742aa3b34..e07da157e 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp @@ -214,18 +214,51 @@ bool Program::ParseDebugMetaRecord(const LLVMBC::BlockOrRecord &metaRecord, Meta } else if(id == MetaDataRecord::LOCATION) { - meta.distinct = (metaRecord.ops[0] & 0x1); - // metastr += "!DILocation()"; + RDCWARN("Unexpected location metadata record, ignoring"); } else if(id == MetaDataRecord::LOCAL_VAR) { meta.distinct = (metaRecord.ops[0] & 0x1); - // metastr += "!DILocalVariable()"; + + meta.dwarf = new DILocalVariable( + DW_TAG(metaRecord.ops[1]), getMeta(metaRecord.ops[2]), getMetaString(metaRecord.ops[3]), + getMeta(metaRecord.ops[4]), metaRecord.ops[5], getMeta(metaRecord.ops[6]), + metaRecord.ops[7], DIFlags(metaRecord.ops[8]), metaRecord.ops[8]); + + meta.children = {getMeta(metaRecord.ops[2]), getMeta(metaRecord.ops[4]), + getMeta(metaRecord.ops[6])}; + } + else if(id == MetaDataRecord::LEXICAL_BLOCK) + { + meta.distinct = (metaRecord.ops[0] & 0x1); + + meta.dwarf = new DILexicalBlock(getMeta(metaRecord.ops[1]), getMeta(metaRecord.ops[2]), + metaRecord.ops[3], metaRecord.ops[4]); + + meta.children = {getMeta(metaRecord.ops[1]), getMeta(metaRecord.ops[2])}; } else if(id == MetaDataRecord::EXPRESSION) { + DIExpression *expr = new DIExpression; + meta.distinct = (metaRecord.ops[0] & 0x1); - // DIExpression + + expr->op = DW_OP_none; + + if(metaRecord.ops.size() > 1) + expr->op = DW_OP(metaRecord.ops[1]); + + if(expr->op == DW_OP_bit_piece && metaRecord.ops.size() == 4) + { + expr->evaluated.bit_piece.offset = metaRecord.ops[2]; + expr->evaluated.bit_piece.size = metaRecord.ops[3]; + } + else + { + expr->expr.assign(metaRecord.ops.data() + 1, metaRecord.ops.size() - 1); + } + + meta.dwarf = expr; } else { @@ -440,6 +473,71 @@ rdcstr DIGlobalVariable::toString() const ret += ")"; return ret; } + +rdcstr DILocalVariable::toString() const +{ + rdcstr ret = StringFormat::Fmt("!DILocalVariable(tag: %s, name: %s", ToStr(tag).c_str(), + escapeString(name ? *name : rdcstr()).c_str()); + if(arg) + ret += StringFormat::Fmt(", arg: %llu", arg); + if(scope) + ret += StringFormat::Fmt(", scope: %s", scope->refString().c_str()); + if(file) + ret += StringFormat::Fmt(", file: %s", file->refString().c_str()); + else + ret += ", file: null"; + if(line) + ret += StringFormat::Fmt(", line: %llu", line); + if(type) + ret += StringFormat::Fmt(", type: %s", type->refString().c_str()); + if(flags) + ret += StringFormat::Fmt(", flags: %s", ToStr(flags).c_str()); + if(alignInBits) + ret += StringFormat::Fmt(", align: %llu", alignInBits); + ret += ")"; + return ret; +} + +rdcstr DIExpression::toString() const +{ + if(op == DW_OP_bit_piece) + return StringFormat::Fmt("!DIExpression(DW_OP_bit_piece, %llu, %llu)", + evaluated.bit_piece.offset, evaluated.bit_piece.size); + + if(op == DW_OP_none) + return "!DIExpression()"; + + if(op == DW_OP_deref) + return "!DIExpression(DW_OP_deref)"; + + rdcstr ret = "!DIExpression("; + for(size_t i = 0; i < expr.size(); i++) + { + if(i > 0) + ret += ", "; + ret += ToStr(expr[i]); + } + ret += ")"; + return ret; +} + +rdcstr DILexicalBlock::toString() const +{ + rdcstr ret = "!DILexicalBlock("; + if(scope) + ret += StringFormat::Fmt(", scope: %s", scope->refString().c_str()); + else + ret += ", scope: null"; + if(file) + ret += StringFormat::Fmt(", file: %s", file->refString().c_str()); + if(line) + ret += StringFormat::Fmt(", line: %llu", line); + if(column) + ret += StringFormat::Fmt(", column: %llu", column); + ret += ")"; + return ret; +} + }; // namespace DXIL template <> diff --git a/renderdoc/driver/shaders/dxil/dxil_debuginfo.h b/renderdoc/driver/shaders/dxil/dxil_debuginfo.h index ccdbd838f..9d0abe316 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debuginfo.h +++ b/renderdoc/driver/shaders/dxil/dxil_debuginfo.h @@ -173,6 +173,168 @@ enum DW_VIRTUALITY DW_VIRTUALITY_pure_virtual = 0x02, }; +enum DW_OP +{ + DW_OP_none = 0x0, + DW_OP_addr = 0x03, + DW_OP_deref = 0x06, + DW_OP_const1u = 0x08, + DW_OP_const1s = 0x09, + DW_OP_const2u = 0x0a, + DW_OP_const2s = 0x0b, + DW_OP_const4u = 0x0c, + DW_OP_const4s = 0x0d, + DW_OP_const8u = 0x0e, + DW_OP_const8s = 0x0f, + DW_OP_constu = 0x10, + DW_OP_consts = 0x11, + DW_OP_dup = 0x12, + DW_OP_drop = 0x13, + DW_OP_over = 0x14, + DW_OP_pick = 0x15, + DW_OP_swap = 0x16, + DW_OP_rot = 0x17, + DW_OP_xderef = 0x18, + DW_OP_abs = 0x19, + DW_OP_and = 0x1a, + DW_OP_div = 0x1b, + DW_OP_minus = 0x1c, + DW_OP_mod = 0x1d, + DW_OP_mul = 0x1e, + DW_OP_neg = 0x1f, + DW_OP_not = 0x20, + DW_OP_or = 0x21, + DW_OP_plus = 0x22, + DW_OP_plus_uconst = 0x23, + DW_OP_shl = 0x24, + DW_OP_shr = 0x25, + DW_OP_shra = 0x26, + DW_OP_xor = 0x27, + DW_OP_skip = 0x2f, + DW_OP_bra = 0x28, + DW_OP_eq = 0x29, + DW_OP_ge = 0x2a, + DW_OP_gt = 0x2b, + DW_OP_le = 0x2c, + DW_OP_lt = 0x2d, + DW_OP_ne = 0x2e, + DW_OP_lit0 = 0x30, + DW_OP_lit1 = 0x31, + DW_OP_lit2 = 0x32, + DW_OP_lit3 = 0x33, + DW_OP_lit4 = 0x34, + DW_OP_lit5 = 0x35, + DW_OP_lit6 = 0x36, + DW_OP_lit7 = 0x37, + DW_OP_lit8 = 0x38, + DW_OP_lit9 = 0x39, + DW_OP_lit10 = 0x3a, + DW_OP_lit11 = 0x3b, + DW_OP_lit12 = 0x3c, + DW_OP_lit13 = 0x3d, + DW_OP_lit14 = 0x3e, + DW_OP_lit15 = 0x3f, + DW_OP_lit16 = 0x40, + DW_OP_lit17 = 0x41, + DW_OP_lit18 = 0x42, + DW_OP_lit19 = 0x43, + DW_OP_lit20 = 0x44, + DW_OP_lit21 = 0x45, + DW_OP_lit22 = 0x46, + DW_OP_lit23 = 0x47, + DW_OP_lit24 = 0x48, + DW_OP_lit25 = 0x49, + DW_OP_lit26 = 0x4a, + DW_OP_lit27 = 0x4b, + DW_OP_lit28 = 0x4c, + DW_OP_lit29 = 0x4d, + DW_OP_lit30 = 0x4e, + DW_OP_lit31 = 0x4f, + DW_OP_reg0 = 0x50, + DW_OP_reg1 = 0x51, + DW_OP_reg2 = 0x52, + DW_OP_reg3 = 0x53, + DW_OP_reg4 = 0x54, + DW_OP_reg5 = 0x55, + DW_OP_reg6 = 0x56, + DW_OP_reg7 = 0x57, + DW_OP_reg8 = 0x58, + DW_OP_reg9 = 0x59, + DW_OP_reg10 = 0x5a, + DW_OP_reg11 = 0x5b, + DW_OP_reg12 = 0x5c, + DW_OP_reg13 = 0x5d, + DW_OP_reg14 = 0x5e, + DW_OP_reg15 = 0x5f, + DW_OP_reg16 = 0x60, + DW_OP_reg17 = 0x61, + DW_OP_reg18 = 0x62, + DW_OP_reg19 = 0x63, + DW_OP_reg20 = 0x64, + DW_OP_reg21 = 0x65, + DW_OP_reg22 = 0x66, + DW_OP_reg23 = 0x67, + DW_OP_reg24 = 0x68, + DW_OP_reg25 = 0x69, + DW_OP_reg26 = 0x6a, + DW_OP_reg27 = 0x6b, + DW_OP_reg28 = 0x6c, + DW_OP_reg29 = 0x6d, + DW_OP_reg30 = 0x6e, + DW_OP_reg31 = 0x6f, + DW_OP_breg0 = 0x70, + DW_OP_breg1 = 0x71, + DW_OP_breg2 = 0x72, + DW_OP_breg3 = 0x73, + DW_OP_breg4 = 0x74, + DW_OP_breg5 = 0x75, + DW_OP_breg6 = 0x76, + DW_OP_breg7 = 0x77, + DW_OP_breg8 = 0x78, + DW_OP_breg9 = 0x79, + DW_OP_breg10 = 0x7a, + DW_OP_breg11 = 0x7b, + DW_OP_breg12 = 0x7c, + DW_OP_breg13 = 0x7d, + DW_OP_breg14 = 0x7e, + DW_OP_breg15 = 0x7f, + DW_OP_breg16 = 0x80, + DW_OP_breg17 = 0x81, + DW_OP_breg18 = 0x82, + DW_OP_breg19 = 0x83, + DW_OP_breg20 = 0x84, + DW_OP_breg21 = 0x85, + DW_OP_breg22 = 0x86, + DW_OP_breg23 = 0x87, + DW_OP_breg24 = 0x88, + DW_OP_breg25 = 0x89, + DW_OP_breg26 = 0x8a, + DW_OP_breg27 = 0x8b, + DW_OP_breg28 = 0x8c, + DW_OP_breg29 = 0x8d, + DW_OP_breg30 = 0x8e, + DW_OP_breg31 = 0x8f, + DW_OP_regx = 0x90, + DW_OP_fbreg = 0x91, + DW_OP_bregx = 0x92, + DW_OP_piece = 0x93, + DW_OP_deref_size = 0x94, + DW_OP_xderef_size = 0x95, + DW_OP_nop = 0x96, + DW_OP_push_object_address = 0x97, + DW_OP_call2 = 0x98, + DW_OP_call4 = 0x99, + DW_OP_call_ref = 0x9a, + DW_OP_form_tls_address = 0x9b, + DW_OP_call_frame_cfa = 0x9c, + DW_OP_bit_piece = 0x9d, + DW_OP_implicit_value = 0x9e, + DW_OP_stack_value = 0x9f, + DW_OP_GNU_push_tls_address = 0xe0, + DW_OP_GNU_addr_index = 0xfb, + DW_OP_GNU_const_index = 0xfc, +}; + enum DIFlags { DIFlagPrivate = 1, @@ -467,6 +629,72 @@ struct DIGlobalVariable : public DIBase virtual rdcstr toString() const; }; +struct DILocalVariable : public DIBase +{ + static const DIBase::Type DIType = DIBase::LocalVariable; + DILocalVariable(DW_TAG tag, const Metadata *scope, const rdcstr *name, const Metadata *file, + uint64_t line, const Metadata *type, uint64_t arg, DIFlags flags, + uint64_t alignInBits) + : DIBase(DIType), + tag(tag), + scope(scope), + name(name), + file(file), + line(line), + type(type), + arg(arg), + flags(flags), + alignInBits(alignInBits) + { + } + + DW_TAG tag; + const Metadata *scope; + const rdcstr *name; + const Metadata *file; + uint64_t line; + const Metadata *type; + uint64_t arg; + DIFlags flags; + uint64_t alignInBits; + + virtual rdcstr toString() const; +}; + +struct DIExpression : public DIBase +{ + static const DIBase::Type DIType = DIBase::Expression; + DIExpression() : DIBase(DIType) {} + rdcarray expr; + DW_OP op; + union + { + struct + { + uint64_t offset; + uint64_t size; + } bit_piece; + } evaluated; + + virtual rdcstr toString() const; +}; + +struct DILexicalBlock : public DIBase +{ + static const DIBase::Type DIType = DIBase::LexicalBlock; + DILexicalBlock(const Metadata *scope, const Metadata *file, uint64_t line, uint64_t column) + : DIBase(DIType), scope(scope), file(file), line(line), column(column) + { + } + + const Metadata *scope; + const Metadata *file; + uint64_t line; + uint64_t column; + + virtual rdcstr toString() const; +}; + }; // namespace DXIL DECLARE_REFLECTION_ENUM(DXIL::Attribute);