From b3b574ed0f45abcd7761fe04a6e71b4b39b27ffe Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Sun, 19 Oct 2014 00:58:01 -0700 Subject: Converted the remaining uses of the old decodeLocation(). --- src/dwarf2pdb.cpp | 46 ++++++++++++++---- src/readDwarf.cpp | 136 +----------------------------------------------------- src/readDwarf.h | 31 +++++++++---- 3 files changed, 61 insertions(+), 152 deletions(-) diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp index 028bb82..020c75b 100644 --- a/src/dwarf2pdb.cpp +++ b/src/dwarf2pdb.cpp @@ -353,13 +353,21 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c if(!isunion) { if (id.member_location.type == ExprLoc) - off = decodeLocation(id.member_location.expr.ptr, id.member_location.expr.len, true, cvid); - else + { + Location loc; + if (decodeLocation(id.member_location.expr.ptr, id.member_location.expr.len, loc) && loc.reg == NoReg) + { + off = loc.offset; + cvid = S_CONSTANT_V2; + } + } + else if (id.member_location.type == Const) { off = id.member_location.cons; cvid = S_CONSTANT_V2; } } + if(isunion || cvid == S_CONSTANT_V2) { checkDWARFTypeAlloc(kMaxNameLen + 100); @@ -370,7 +378,13 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c } else if(id.tag == DW_TAG_inheritance) { - int off = decodeLocation(id.member_location.expr.ptr, id.member_location.expr.len, true, cvid); + Location loc; + int off; + if (decodeLocation(id.member_location.expr.ptr, id.member_location.expr.len, loc) && loc.reg == NoReg) + { + cvid = S_CONSTANT_V2; + off = loc.offset; + } if(cvid == S_CONSTANT_V2) { codeview_fieldtype* bc = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); @@ -685,6 +699,15 @@ bool CV2PDB::createTypes() //printf("0x%08x, level = %d, id.code = %d, id.tag = %d\n", // (unsigned char*)cu + id.entryOff - (unsigned char*)img.debug_info, cursor.level, id.code, id.tag); + if (id.specification) + { + DIECursor specCursor(cu, id.specification); + DWARF_InfoData idspec; + specCursor.readNext(idspec); + assert(id.tag == idspec.tag); + id.merge(idspec); + } + int cvtype = -1; switch (id.tag) { @@ -781,12 +804,17 @@ bool CV2PDB::createTypes() } else { - int cvid; - segOff = decodeLocation(id.location.expr.ptr, id.location.expr.len, false, cvid); - if (cvid == S_GDATA_V2) - seg = img.findSection(segOff); - if (seg >= 0) - segOff -= img.getImageBase() + img.getSection(seg).VirtualAddress; + Location loc; + if (id.location.type == ExprLoc) + { + if (decodeLocation(id.location.expr.ptr, id.location.expr.len, loc) && loc.reg == NoReg) + { + segOff = loc.offset; + seg = img.findSection(segOff); + if (seg >= 0) + segOff -= img.getImageBase() + img.getSection(seg).VirtualAddress; + } + } } if (seg >= 0) { diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp index d6d0391..5827ea0 100644 --- a/src/readDwarf.cpp +++ b/src/readDwarf.cpp @@ -258,141 +258,6 @@ bool decodeLocation(byte* loc, long len, Location& result, Location* frameBase) return true; } - -long decodeLocation(byte* loc, long len, bool push0, int &id, int& size) -{ - byte* p = loc; - long stack[8] = { 0 }; - int stackDepth = push0 ? 1 : 0; - long data = 0; - id = push0 ? S_CONSTANT_V2 : -1; - do - { - if (p - loc >= len) - break; - - int op = *p++; - if (op == 0) - break; - size = 0; - - switch (op) - { - case DW_OP_addr: id = S_GDATA_V2; size = 4; stack[stackDepth++] = RD4(p); break; - case DW_OP_fbreg: id = S_BPREL_V2; stack[stackDepth++] = SLEB128(p); break; - case DW_OP_const1u: id = S_CONSTANT_V2; size = 1; stack[stackDepth++] = *p; break; - case DW_OP_const2u: id = S_CONSTANT_V2; size = 2; stack[stackDepth++] = RD2(p); break; - case DW_OP_const4u: id = S_CONSTANT_V2; size = 4; stack[stackDepth++] = RD4(p); break; - case DW_OP_const1s: id = S_CONSTANT_V2; size = 1; stack[stackDepth++] = (char)*p; break; - case DW_OP_const2s: id = S_CONSTANT_V2; size = 2; stack[stackDepth++] = (short)RD2(p); break; - case DW_OP_const4s: id = S_CONSTANT_V2; size = 4; stack[stackDepth++] = (int)RD4(p); break; - case DW_OP_constu: id = S_CONSTANT_V2; stack[stackDepth++] = LEB128(p); break; - case DW_OP_consts: id = S_CONSTANT_V2; stack[stackDepth++] = SLEB128(p); break; - case DW_OP_plus_uconst: stack[stackDepth - 1] += LEB128(p); break; - case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: - case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: - case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: - case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: - case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: - case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: - case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: - case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: - id = S_CONSTANT_V2; - stack[stackDepth++] = op - DW_OP_lit0; - break; - case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: - case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: - case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: - case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: - case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: - case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: - case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: - case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: - id = S_REGISTER_V2; - break; - case DW_OP_regx: - id = S_REGISTER_V2; - data = LEB128(p); // reg - break; - case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: - case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: - case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: - case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: - case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: - case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: - case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: - case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: - id = (op == DW_OP_breg4 ? S_REGREL_V3 : op == DW_OP_breg5 ? S_BPREL_V2 : S_REGISTER_V2); - stack[stackDepth++] = SLEB128(p); - break; - case DW_OP_bregx: - data = LEB128(p); // reg - id = (data == DW_OP_breg4 ? S_REGREL_V3 : data == DW_OP_breg5 ? S_BPREL_V2 : S_REGISTER_V2); - stack[stackDepth++] = SLEB128(p); - break; - - case DW_OP_deref: break; - case DW_OP_deref_size: size = 1; break; - case DW_OP_dup: stack[stackDepth] = stack[stackDepth - 1]; stackDepth++; break; - case DW_OP_drop: stackDepth--; break; - case DW_OP_over: stack[stackDepth] = stack[stackDepth - 2]; stackDepth++; break; - case DW_OP_pick: size = 1; stack[stackDepth++] = stack[*p]; break; - case DW_OP_swap: data = stack[stackDepth - 1]; stack[stackDepth - 1] = stack[stackDepth - 2]; stack[stackDepth - 2] = data; break; - case DW_OP_rot: data = stack[stackDepth - 1]; stack[stackDepth - 1] = stack[stackDepth - 2]; stack[stackDepth - 2] = stack[stackDepth - 3]; stack[stackDepth - 3] = data; break; - case DW_OP_xderef: stackDepth--; break; - case DW_OP_xderef_size: size = 1; stackDepth--; break; - - case DW_OP_push_object_address: stackDepth++; break; /* DWARF3 */ - case DW_OP_call2: size = 2; break; - case DW_OP_call4: size = 4; break; - case DW_OP_form_tls_address: break; - case DW_OP_call_frame_cfa: stack[stackDepth++] = -1; break; // default stack offset? - case DW_OP_call_ref: - case DW_OP_bit_piece: - case DW_OP_implicit_value: /* DWARF4 */ - case DW_OP_stack_value: - //assert(!"unsupported expression operations"); - id = -1; - return 0; - - // unary operations pop and push - case DW_OP_abs: stack[stackDepth - 1] = abs(stack[stackDepth - 1]); break; - case DW_OP_neg: stack[stackDepth - 1] = -stack[stackDepth - 1]; break; - case DW_OP_not: stack[stackDepth - 1] = ~stack[stackDepth - 1]; break; - break; - // binary operations pop twice and push - case DW_OP_and: stack[stackDepth - 2] = stack[stackDepth - 2] & stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_div: stack[stackDepth - 2] = stack[stackDepth - 2] / stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_minus: stack[stackDepth - 2] = stack[stackDepth - 2] - stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_mod: stack[stackDepth - 2] = stack[stackDepth - 2] % stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_mul: stack[stackDepth - 2] = stack[stackDepth - 2] * stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_or: stack[stackDepth - 2] = stack[stackDepth - 2] | stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_plus: stack[stackDepth - 2] = stack[stackDepth - 2] + stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_shl: stack[stackDepth - 2] = stack[stackDepth - 2] << stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_shr: stack[stackDepth - 2] = stack[stackDepth - 2] >> stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_shra: stack[stackDepth - 2] = stack[stackDepth - 2] >> stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_xor: stack[stackDepth - 2] = stack[stackDepth - 2] ^ stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_eq: stack[stackDepth - 2] = stack[stackDepth - 2] == stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_ge: stack[stackDepth - 2] = stack[stackDepth - 2] >= stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_gt: stack[stackDepth - 2] = stack[stackDepth - 2] > stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_le: stack[stackDepth - 2] = stack[stackDepth - 2] <= stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_lt: stack[stackDepth - 2] = stack[stackDepth - 2] < stack[stackDepth - 1]; stackDepth--; break; - case DW_OP_ne: stack[stackDepth - 2] = stack[stackDepth - 2] != stack[stackDepth - 1]; stackDepth--; break; - - case DW_OP_bra: - case DW_OP_skip: - size = RD2(p); - p += size; - break; - } - } while (stackDepth > 0); - size = p - loc; - return stack[0]; -} - - -//decodeLocation(byte* loc, long len) - // declare hasher for pair namespace std { @@ -484,6 +349,7 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull) return false; // root of the tree does not have a null terminator, but we know the length id.entryPtr = ptr; + id.entryOff = ptr - (byte*)cu; id.code = LEB128(ptr); if (id.code == 0) { diff --git a/src/readDwarf.h b/src/readDwarf.h index 238fb24..4191708 100644 --- a/src/readDwarf.h +++ b/src/readDwarf.h @@ -137,6 +137,7 @@ struct DWARF_FileName struct DWARF_InfoData { byte* entryPtr; + unsigned entryOff; // offset in the cu int code; byte* abbrev; int tag; @@ -189,6 +190,28 @@ struct DWARF_InfoData upper_bound = 0; lower_bound = 0; } + + void merge(const DWARF_InfoData& id) + { + if (id.name) name = id.name; + if (id.linkage_name) linkage_name = id.linkage_name; + if (id.dir) dir = id.dir; + if (id.byte_size) byte_size = id.byte_size; + if (id.sibling) sibling = id.sibling; + if (id.encoding) encoding = id.encoding; + if (id.pclo) pclo = id.pclo; + if (id.pchi) pchi = id.pchi; + if (id.type) type = id.type; + if (id.containing_type) containing_type = id.containing_type; + if (id.specification) specification = id.specification; + if (id.inlined) inlined = id.inlined; + if (id.external) external = id.external; + if (id.member_location.type != Invalid) member_location = id.member_location; + if (id.location.type != Invalid) location = id.location; + if (id.frame_base.type != Invalid) frame_base = id.frame_base; + if (id.upper_bound) upper_bound = id.upper_bound; + if (id.lower_bound) lower_bound = id.lower_bound; + } }; static const int maximum_operations_per_instruction = 1; @@ -292,14 +315,6 @@ const int NoReg = -1; bool decodeLocation(byte* loc, long len, Location& result, Location* frameBase = 0); -long decodeLocation(byte* loc, long len, bool push0, int &id, int& size); - -inline long decodeLocation(byte*loc, long len, bool push0, int &id) -{ - int size; - return decodeLocation(loc, len, push0, id, size); -} - class PEImage; // Debug Information Entry Cursor -- cgit v0.12