internal DbiModuleInfo(BitAccess bits, bool readStrings) { bits.ReadInt32(out opened); section = new DbiSecCon(bits); bits.ReadUInt16(out flags); bits.ReadInt16(out stream); bits.ReadInt32(out cbSyms); bits.ReadInt32(out cbOldLines); bits.ReadInt32(out cbLines); bits.ReadInt16(out files); bits.ReadInt16(out pad1); bits.ReadUInt32(out offsets); bits.ReadInt32(out niSource); bits.ReadInt32(out niCompiler); if (readStrings) { bits.ReadCString(out moduleName); bits.ReadCString(out objectName); } else { bits.SkipCString(out moduleName); bits.SkipCString(out objectName); } bits.Align(4); //if (opened != 0 || pad1 != 0) { // throw new PdbException("Invalid DBI module. "+ // "(opened={0}, pad={1})", opened, pad1); //} }
static Dictionary<string, int> LoadNameIndex(BitAccess bits) { Dictionary<string, int> result = new Dictionary<string, int>(); int ver; int sig; int age; Guid guid; bits.ReadInt32(out ver); // 0..3 Version bits.ReadInt32(out sig); // 4..7 Signature bits.ReadInt32(out age); // 8..11 Age bits.ReadGuid(out guid); // 12..27 GUID //if (ver != 20000404) { // throw new PdbDebugException("Unsupported PDB Stream version {0}", ver); //} // Read string buffer. int buf; bits.ReadInt32(out buf); // 28..31 Bytes of Strings int beg = bits.Position; int nxt = bits.Position + buf; bits.Position = nxt; // Read map index. int cnt; // n+0..3 hash size. int max; // n+4..7 maximum ni. bits.ReadInt32(out cnt); bits.ReadInt32(out max); BitSet present = new BitSet(bits); BitSet deleted = new BitSet(bits); if (!deleted.IsEmpty) { throw new PdbDebugException("Unsupported PDB deleted bitset is not empty."); } int j = 0; for (int i = 0; i < max; i++) { if (present.IsSet(i)) { int ns; int ni; bits.ReadInt32(out ns); bits.ReadInt32(out ni); string name; int saved = bits.Position; bits.Position = beg + ns; bits.ReadCString(out name); bits.Position = saved; result.Add(name.ToUpperInvariant(), ni); j++; } } if (j != cnt) { throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); } return result; }
//internal uint segment; //internal uint address; internal PdbSlot(BitAccess bits) { AttrSlotSym slot; bits.ReadUInt32(out slot.index); bits.ReadUInt32(out slot.typind); bits.ReadUInt32(out slot.offCod); bits.ReadUInt16(out slot.segCod); bits.ReadUInt16(out slot.flags); bits.ReadCString(out slot.name); this.slot = slot.index; this.typeToken = slot.typind; this.name = slot.name; this.flags = slot.flags; //this.segment = slot.segCod; //this.address = slot.offCod; }
internal PdbSlot(BitAccess bits, out uint typind) { AttrSlotSym slot; bits.ReadUInt32(out slot.index); bits.ReadUInt32(out slot.typind); bits.ReadUInt32(out slot.offCod); bits.ReadUInt16(out slot.segCod); bits.ReadUInt16(out slot.flags); bits.ReadCString(out slot.name); this.Slot = slot.index; this.Name = slot.name; this.Flags = slot.flags; this.Segment = slot.segCod; this.Address = slot.offCod; typind = slot.typind; }
internal static PdbFunction[] LoadManagedFunctions(/*string module,*/ BitAccess bits, uint limit, bool readStrings) { //string mod = StripNamespace(module); int begin = bits.Position; int count = 0; while (bits.Position < limit) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.Position = star; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.Position = (int)proc.end; count++; break; case SYM.S_END: bits.Position = stop; break; default: //Console.WriteLine("{0,6}: {1:x2} {2}", // bits.Position, rec, (SYM)rec); bits.Position = stop; break; } } if (count == 0) { return null; } bits.Position = begin; PdbFunction[] funcs = new PdbFunction[count]; int func = 0; while (bits.Position < limit) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; //int offset = bits.Position; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.ReadUInt32(out proc.next); bits.ReadUInt32(out proc.len); bits.ReadUInt32(out proc.dbgStart); bits.ReadUInt32(out proc.dbgEnd); bits.ReadUInt32(out proc.token); bits.ReadUInt32(out proc.off); bits.ReadUInt16(out proc.seg); bits.ReadUInt8(out proc.flags); bits.ReadUInt16(out proc.retReg); if (readStrings) { bits.ReadCString(out proc.name); } else { bits.SkipCString(out proc.name); } //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name); bits.Position = stop; funcs[func++] = new PdbFunction(/*module,*/ proc, bits); break; default: { //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec); bits.Position = stop; break; } } } return funcs; }
internal PdbFunction(/*string module, */ManProcSym proc, BitAccess bits) { this.token = proc.token; //this.module = module; //this.name = proc.name; //this.flags = proc.flags; this.segment = proc.seg; this.address = proc.off; //this.length = proc.len; if (proc.seg != 1) { throw new PdbDebugException("Segment is {0}, not 1.", proc.seg); } if (proc.parent != 0 || proc.next != 0) { throw new PdbDebugException("Warning parent={0}, next={1}", proc.parent, proc.next); } //if (proc.dbgStart != 0 || proc.dbgEnd != 0) { // throw new PdbDebugException("Warning DBG start={0}, end={1}", // proc.dbgStart, proc.dbgEnd); //} int constantCount; int scopeCount; int slotCount; int usedNamespacesCount; CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount); int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0; int slot = 0; int constant = 0; int usedNs = 0; scopes = new PdbScope[scopeCount+scope]; slots = new PdbSlot[slotCount]; constants = new PdbConstant[constantCount]; usedNamespaces = new string[usedNamespacesCount]; if (scope > 0) scopes[0] = new PdbScope(this.address, proc.len, slots, constants, usedNamespaces); while (bits.Position < proc.end) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.Position = star; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_OEM: { // 0x0404 OemSymbol oem; bits.ReadGuid(out oem.idOem); bits.ReadUInt32(out oem.typind); // internal byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == msilMetaData) { string name = bits.ReadString(); if (name == "MD2") { byte version; bits.ReadUInt8(out version); if (version == 4) { byte count; bits.ReadUInt8(out count); bits.Align(4); while (count-- > 0) this.ReadCustomMetadata(bits); } } else if (name == "asyncMethodInfo") { this.synchronizationInformation = new PdbSynchronizationInformation(bits); } bits.Position = stop; break; } else { throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind); // bits.Position = stop; } } case SYM.S_BLOCK32: { BlockSym32 block = new BlockSym32(); bits.ReadUInt32(out block.parent); bits.ReadUInt32(out block.end); bits.ReadUInt32(out block.len); bits.ReadUInt32(out block.off); bits.ReadUInt16(out block.seg); bits.SkipCString(out block.name); bits.Position = stop; scopes[scope++] = new PdbScope(this.address, block, bits, out slotToken); bits.Position = (int)block.end; break; } case SYM.S_MANSLOT: slots[slot++] = new PdbSlot(bits); bits.Position = stop; break; case SYM.S_MANCONSTANT: constants[constant++] = new PdbConstant(bits); bits.Position = stop; break; case SYM.S_UNAMESPACE: bits.ReadCString(out usedNamespaces[usedNs++]); bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; default: { //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); bits.Position = stop; break; } } } if (bits.Position != proc.end) { throw new PdbDebugException("Not at S_END"); } ushort esiz; ushort erec; bits.ReadUInt16(out esiz); bits.ReadUInt16(out erec); if (erec != (ushort)SYM.S_END) { throw new PdbDebugException("Missing S_END"); } }
static IntHashTable LoadNameStream(BitAccess bits) { IntHashTable ht = new IntHashTable(); uint sig; int ver; bits.ReadUInt32(out sig); // 0..3 Signature bits.ReadInt32(out ver); // 4..7 Version // Read (or skip) string buffer. int buf; bits.ReadInt32(out buf); // 8..11 Bytes of Strings if (sig != 0xeffeeffe || ver != 1) { throw new PdbDebugException("Unsupported Name Stream version. "+ "(sig={0:x8}, ver={1})", sig, ver); } int beg = bits.Position; int nxt = bits.Position + buf; bits.Position = nxt; // Read hash table. int siz; bits.ReadInt32(out siz); // n+0..3 Number of hash buckets. nxt = bits.Position; for (int i = 0; i < siz; i++) { int ni; string name; bits.ReadInt32(out ni); if (ni != 0) { int saved = bits.Position; bits.Position = beg + ni; bits.ReadCString(out name); bits.Position = saved; ht.Add(ni, name); } } bits.Position = nxt; return ht; }
internal PdbConstant(BitAccess bits) { bits.ReadUInt32(out this.token); byte tag1; bits.ReadUInt8(out tag1); byte tag2; bits.ReadUInt8(out tag2); if (tag2 == 0) { this.value = tag1; } else if (tag2 == 0x80) { switch (tag1) { case 0x00: //sbyte sbyte sb; bits.ReadInt8(out sb); this.value = sb; break; case 0x01: //short short s; bits.ReadInt16(out s); this.value = s; break; case 0x02: //ushort ushort us; bits.ReadUInt16(out us); this.value = us; break; case 0x03: //int int i; bits.ReadInt32(out i); this.value = i; break; case 0x04: //uint uint ui; bits.ReadUInt32(out ui); this.value = ui; break; case 0x05: //float this.value = bits.ReadFloat(); break; case 0x06: //double this.value = bits.ReadDouble(); break; case 0x09: //long long sl; bits.ReadInt64(out sl); this.value = sl; break; case 0x0a: //ulong ulong ul; bits.ReadUInt64(out ul); this.value = ul; break; case 0x10: //string string str; bits.ReadBString(out str); this.value = str; break; case 0x19: //decimal this.value = bits.ReadDecimal(); break; default: //TODO: error break; } } else { //TODO: error } bits.ReadCString(out name); }
internal PdbScope(uint funcOffset, BlockSym32 block, BitAccess bits, out uint typind) { //this.segment = block.seg; this.address = block.off; this.offset = block.off - funcOffset; this.length = block.len; typind = 0; int constantCount; int scopeCount; int slotCount; int namespaceCount; PdbFunction.CountScopesAndSlots(bits, block.end, out constantCount, out scopeCount, out slotCount, out namespaceCount); constants = new PdbConstant[constantCount]; scopes = new PdbScope[scopeCount]; slots = new PdbSlot[slotCount]; usedNamespaces = new string[namespaceCount]; int constant = 0; int scope = 0; int slot = 0; int usedNs = 0; while (bits.Position < block.end) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.Position = star; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_BLOCK32: { BlockSym32 sub = new BlockSym32(); bits.ReadUInt32(out sub.parent); bits.ReadUInt32(out sub.end); bits.ReadUInt32(out sub.len); bits.ReadUInt32(out sub.off); bits.ReadUInt16(out sub.seg); bits.SkipCString(out sub.name); bits.Position = stop; scopes[scope++] = new PdbScope(funcOffset, sub, bits, out typind); break; } case SYM.S_MANSLOT: slots[slot++] = new PdbSlot(bits, out typind); bits.Position = stop; break; case SYM.S_UNAMESPACE: bits.ReadCString(out usedNamespaces[usedNs++]); bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; case SYM.S_MANCONSTANT: constants[constant++] = new PdbConstant(bits); bits.Position = stop; break; default: //throw new PdbException("Unknown SYM in scope {0}", (SYM)rec); bits.Position = stop; break; } } if (bits.Position != block.end) { throw new Exception("Not at S_END"); } ushort esiz; ushort erec; bits.ReadUInt16(out esiz); bits.ReadUInt16(out erec); if (erec != (ushort)SYM.S_END) { throw new Exception("Missing S_END"); } }
internal PdbConstant(BitAccess bits) { bits.ReadUInt32(out this.Token); byte tag1; bits.ReadUInt8(out tag1); byte tag2; bits.ReadUInt8(out tag2); switch (tag2) { case 0: this.Value = tag1; break; case 0x80: switch (tag1) { case 0x01: //short short s; bits.ReadInt16(out s); this.Value = s; break; case 0x02: //ushort ushort us; bits.ReadUInt16(out us); this.Value = us; break; case 0x03: //int int i; bits.ReadInt32(out i); this.Value = i; break; case 0x04: //uint uint ui; bits.ReadUInt32(out ui); this.Value = ui; break; case 0x05: //float this.Value = bits.ReadFloat(); break; case 0x06: //double this.Value = bits.ReadDouble(); break; case 0x09: //long long sl; bits.ReadInt64(out sl); this.Value = sl; break; case 0x0a: //ulong ulong ul; bits.ReadUInt64(out ul); this.Value = ul; break; case 0x10: //string string str; bits.ReadBString(out str); this.Value = str; break; case 0x19: //decimal this.Value = bits.ReadDecimal(); break; } break; } bits.ReadCString(out this.Name); }
internal static PdbFunction[] LoadManagedFunctions(string module, BitAccess bits, uint limit, bool readStrings) { int begin = bits.Position; int count = 0; while (bits.Position < limit) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.Position = star; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.Position = (int)proc.end; count++; break; case SYM.S_END: bits.Position = stop; break; default: //Console.WriteLine("{0,6}: {1:x2} {2}", // bits.Position, rec, (SYM)rec); bits.Position = stop; break; } } if (count == 0) { return(null); } bits.Position = begin; PdbFunction[] funcs = new PdbFunction[count]; int func = 0; while (bits.Position < limit) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int stop = bits.Position + siz; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.ReadUInt32(out proc.next); bits.ReadUInt32(out proc.len); bits.ReadUInt32(out proc.dbgStart); bits.ReadUInt32(out proc.dbgEnd); bits.ReadUInt32(out proc.token); bits.ReadUInt32(out proc.off); bits.ReadUInt16(out proc.seg); bits.ReadUInt8(out proc.flags); bits.ReadUInt16(out proc.retReg); if (readStrings) { bits.ReadCString(out proc.name); } else { bits.SkipCString(out proc.name); } //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name); bits.Position = stop; funcs[func++] = new PdbFunction(module, proc, bits); break; default: { //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec); bits.Position = stop; break; } } } return(funcs); }
internal PdbFunction(/*string module, */ ManProcSym proc, BitAccess bits) { this.token = proc.token; //this.module = module; //this.name = proc.name; //this.flags = proc.flags; this.segment = proc.seg; this.address = proc.off; this.length = proc.len; if (proc.seg != 1) { throw new PdbDebugException("Segment is {0}, not 1.", proc.seg); } if (proc.parent != 0 || proc.next != 0) { throw new PdbDebugException("Warning parent={0}, next={1}", proc.parent, proc.next); } //if (proc.dbgStart != 0 || proc.dbgEnd != 0) { // throw new PdbDebugException("Warning DBG start={0}, end={1}", // proc.dbgStart, proc.dbgEnd); //} int constantCount; int scopeCount; int slotCount; int usedNamespacesCount; CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount); int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0; int slot = 0; int constant = 0; int usedNs = 0; scopes = new PdbScope[scopeCount + scope]; slots = new PdbSlot[slotCount]; constants = new PdbConstant[constantCount]; usedNamespaces = new string[usedNamespacesCount]; if (scope > 0) { scopes[0] = new PdbScope(this.address, proc.len, slots, constants, usedNamespaces); } while (bits.Position < proc.end) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.Position = star; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_OEM: { // 0x0404 OemSymbol oem; bits.ReadGuid(out oem.idOem); bits.ReadUInt32(out oem.typind); // internal byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == msilMetaData) { string name = bits.ReadString(); if (name == "MD2") { ReadMD2CustomMetadata(bits); } else if (name == "asyncMethodInfo") { this.synchronizationInformation = new PdbSynchronizationInformation(bits); } bits.Position = stop; break; } else { throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind); // bits.Position = stop; } } case SYM.S_BLOCK32: { BlockSym32 block = new BlockSym32(); bits.ReadUInt32(out block.parent); bits.ReadUInt32(out block.end); bits.ReadUInt32(out block.len); bits.ReadUInt32(out block.off); bits.ReadUInt16(out block.seg); bits.SkipCString(out block.name); bits.Position = stop; scopes[scope++] = new PdbScope(this.address, block, bits, out slotToken); bits.Position = (int)block.end; break; } case SYM.S_MANSLOT: slots[slot++] = new PdbSlot(bits); bits.Position = stop; break; case SYM.S_MANCONSTANT: constants[constant++] = new PdbConstant(bits); bits.Position = stop; break; case SYM.S_UNAMESPACE: bits.ReadCString(out usedNamespaces[usedNs++]); bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; default: { //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); bits.Position = stop; break; } } } if (bits.Position != proc.end) { throw new PdbDebugException("Not at S_END"); } ushort esiz; ushort erec; bits.ReadUInt16(out esiz); bits.ReadUInt16(out erec); if (erec != (ushort)SYM.S_END) { throw new PdbDebugException("Missing S_END"); } }
static Dictionary <string, int> LoadNameIndex(BitAccess bits, out int age, out Guid guid) { Dictionary <string, int> result = new Dictionary <string, int>(); int ver; int sig; bits.ReadInt32(out ver); // 0..3 Version bits.ReadInt32(out sig); // 4..7 Signature bits.ReadInt32(out age); // 8..11 Age bits.ReadGuid(out guid); // 12..27 GUID //if (ver != 20000404) { // throw new PdbDebugException("Unsupported PDB Stream version {0}", ver); //} // Read string buffer. int buf; bits.ReadInt32(out buf); // 28..31 Bytes of Strings int beg = bits.Position; int nxt = bits.Position + buf; bits.Position = nxt; // Read map index. int cnt; // n+0..3 hash size. int max; // n+4..7 maximum ni. bits.ReadInt32(out cnt); bits.ReadInt32(out max); BitSet present = new BitSet(bits); BitSet deleted = new BitSet(bits); if (!deleted.IsEmpty) { throw new PdbDebugException("Unsupported PDB deleted bitset is not empty."); } int j = 0; for (int i = 0; i < max; i++) { if (present.IsSet(i)) { int ns; int ni; bits.ReadInt32(out ns); bits.ReadInt32(out ni); string name; int saved = bits.Position; bits.Position = beg + ns; bits.ReadCString(out name); bits.Position = saved; result.Add(name.ToUpperInvariant(), ni); j++; } } if (j != cnt) { throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); } return(result); }