internal DbiModuleInfo(BitAccess bits, bool readStrings) { bits.ReadInt32(out opened); 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); //} }
internal short stream; // 34..35 #endregion Fields #region Constructors internal DbiModuleInfo(BitAccess bits, bool readStrings) { bits.ReadInt32(out opened); 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); //} }
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); Slot = slot.index; Name = slot.name; Flags = slot.flags; typind = slot.typind; }
//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; }
/// <summary> /// </summary> /// <param name="bits"> /// </param> /// <param name="typind"> /// </param> 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 void CountScopesAndSlots(BitAccess bits, uint limit, out int scopes, out int slots) { int pos = bits.Position; BlockSym32 block; slots = 0; scopes = 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_BLOCK32: { bits.ReadUInt32(out block.parent); bits.ReadUInt32(out block.end); scopes++; bits.Position = (int)block.end; break; } case SYM.S_MANSLOT: slots++; bits.Position = stop; break; default: bits.Position = stop; break; } } bits.Position = pos; }
internal DbiHeader(BitAccess bits) { bits.ReadInt32(out sig); bits.ReadInt32(out ver); bits.ReadInt32(out age); bits.ReadInt16(out gssymStream); bits.ReadUInt16(out vers); bits.ReadInt16(out pssymStream); bits.ReadUInt16(out pdbver); bits.ReadInt16(out symrecStream); bits.ReadUInt16(out pdbver2); bits.ReadInt32(out gpmodiSize); bits.ReadInt32(out secconSize); bits.ReadInt32(out secmapSize); bits.ReadInt32(out filinfSize); bits.ReadInt32(out tsmapSize); bits.ReadInt32(out mfcIndex); bits.ReadInt32(out dbghdrSize); bits.ReadInt32(out ecinfoSize); bits.ReadUInt16(out flags); bits.ReadUInt16(out machine); bits.ReadInt32(out reserved); }
internal ushort vers; // 14..15 #endregion Fields #region Constructors internal DbiHeader(BitAccess bits) { bits.ReadInt32(out sig); bits.ReadInt32(out ver); bits.ReadInt32(out age); bits.ReadInt16(out gssymStream); bits.ReadUInt16(out vers); bits.ReadInt16(out pssymStream); bits.ReadUInt16(out pdbver); bits.ReadInt16(out symrecStream); bits.ReadUInt16(out pdbver2); bits.ReadInt32(out gpmodiSize); bits.ReadInt32(out secconSize); bits.ReadInt32(out secmapSize); bits.ReadInt32(out filinfSize); bits.ReadInt32(out tsmapSize); bits.ReadInt32(out mfcIndex); bits.ReadInt32(out dbghdrSize); bits.ReadInt32(out ecinfoSize); bits.ReadUInt16(out flags); bits.ReadUInt16(out machine); bits.ReadInt32(out reserved); }
internal ushort vers; // 14..15 /// <summary> /// </summary> /// <param name="bits"> /// </param> internal DbiHeader(BitAccess bits) { bits.ReadInt32(out this.sig); bits.ReadInt32(out this.ver); bits.ReadInt32(out this.age); bits.ReadInt16(out this.gssymStream); bits.ReadUInt16(out this.vers); bits.ReadInt16(out this.pssymStream); bits.ReadUInt16(out this.pdbver); bits.ReadInt16(out this.symrecStream); bits.ReadUInt16(out this.pdbver2); bits.ReadInt32(out this.gpmodiSize); bits.ReadInt32(out this.secconSize); bits.ReadInt32(out this.secmapSize); bits.ReadInt32(out this.filinfSize); bits.ReadInt32(out this.tsmapSize); bits.ReadInt32(out this.mfcIndex); bits.ReadInt32(out this.dbghdrSize); bits.ReadInt32(out this.ecinfoSize); bits.ReadUInt16(out this.flags); bits.ReadUInt16(out this.machine); bits.ReadInt32(out this.reserved); }
internal DbiModuleInfo(BitAccess bits, bool readStrings) { bits.ReadInt32(out opened); 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); }
internal PdbScope(BlockSym32 block, BitAccess bits, out uint typind) { this.segment = block.seg; this.address = block.off; this.length = block.len; typind = 0; int scopeCount; int slotCount; PdbFunction.CountScopesAndSlots(bits, block.end, out scopeCount, out slotCount); scopes = new PdbScope[scopeCount]; slots = new PdbSlot[slotCount]; int scope = 0; int slot = 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(sub, bits, out typind); break; } case SYM.S_MANSLOT: slots[slot++] = new PdbSlot(bits, out typind); bits.Position = stop; break; case SYM.S_END: case SYM.S_UNAMESPACE: case SYM.S_MANCONSTANT: bits.Position = stop; break; default: throw new PdbException("Unknown SYM in scope {0}", (SYM)rec); // bits.Position = stop; } } 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) { uint token; bits.ReadUInt32(out token); Token = token; byte tag1; bits.ReadUInt8(out tag1); byte tag2; bits.ReadUInt8(out tag2); if (tag2 == 0) { Value = tag1; } else if (tag2 == 0x80) { switch (tag1) { case 0x00: //sbyte sbyte sb; bits.ReadInt8(out sb); Value = sb; break; case 0x01: //short short s; bits.ReadInt16(out s); Value = s; break; case 0x02: //ushort ushort us; bits.ReadUInt16(out us); Value = us; break; case 0x03: //int int i; bits.ReadInt32(out i); Value = i; break; case 0x04: //uint uint ui; bits.ReadUInt32(out ui); Value = ui; break; case 0x05: //float Value = bits.ReadFloat(); break; case 0x06: //double Value = bits.ReadDouble(); break; case 0x09: //long long sl; bits.ReadInt64(out sl); Value = sl; break; case 0x0a: //ulong ulong ul; bits.ReadUInt64(out ul); Value = ul; break; case 0x10: //string string str; bits.ReadBString(out str); Value = str; break; case 0x19: //decimal Value = bits.ReadDecimal(); break; } } bits.ReadCString(out string name); Name = name; }
/// <summary> /// </summary> /// <param name="bits"> /// </param> 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 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 this.name); }
internal ushort snXdata; // 14..15 #endregion Fields #region Constructors internal DbiDbgHdr(BitAccess bits) { bits.ReadUInt16(out snFPO); bits.ReadUInt16(out snException); bits.ReadUInt16(out snFixup); bits.ReadUInt16(out snOmapToSrc); bits.ReadUInt16(out snOmapFromSrc); bits.ReadUInt16(out snSectionHdr); bits.ReadUInt16(out snTokenRidMap); bits.ReadUInt16(out snXdata); bits.ReadUInt16(out snPdata); bits.ReadUInt16(out snNewFPO); bits.ReadUInt16(out snSectionHdrOrig); }
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 ushort snXdata; // 14..15 /// <summary> /// </summary> /// <param name="bits"> /// </param> internal DbiDbgHdr(BitAccess bits) { bits.ReadUInt16(out this.snFPO); bits.ReadUInt16(out this.snException); bits.ReadUInt16(out this.snFixup); bits.ReadUInt16(out this.snOmapToSrc); bits.ReadUInt16(out this.snOmapFromSrc); bits.ReadUInt16(out this.snSectionHdr); bits.ReadUInt16(out this.snTokenRidMap); bits.ReadUInt16(out this.snXdata); bits.ReadUInt16(out this.snPdata); bits.ReadUInt16(out this.snNewFPO); bits.ReadUInt16(out this.snSectionHdrOrig); }
static void LoadManagedLines(PdbFunction[] funcs, IntHashTable names, BitAccess bits, uint limit) { Array.Sort(funcs, PdbFunction.byAddress); checks.Clear(); // Read the files first int begin = bits.Position; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int place = bits.Position; int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.FILECHKSMS: while (bits.Position < endSym) { CV_FileCheckSum chk; int ni = bits.Position - place; bits.ReadUInt32(out chk.name); bits.ReadUInt8(out chk.len); bits.ReadUInt8(out chk.type); string name = (string)names[(int)chk.name]; PdbSource src = new PdbSource((uint)ni, name); checks.Add(ni, src); bits.Position += chk.len; bits.Align(4); } bits.Position = endSym; break; default: bits.Position = endSym; break; } } // Read the lines next. bits.Position = begin; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.LINES: { CV_LineSection sec; bits.ReadUInt32(out sec.off); bits.ReadUInt16(out sec.sec); bits.ReadUInt16(out sec.flags); bits.ReadUInt32(out sec.cod); PdbFunction func = FindFunction(funcs, sec.sec, sec.off); // Count the line blocks. int begSym = bits.Position; int blocks = 0; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0)); bits.Position += linsiz; blocks++; } func.lines = new PdbLines[blocks]; int block = 0; bits.Position = begSym; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. PdbSource src = (PdbSource)checks[(int)file.index]; PdbLines tmp = new PdbLines(src, file.count); func.lines[block++] = tmp; PdbLine[] lines = tmp.lines; int plin = bits.Position; int pcol = bits.Position + 8 * (int)file.count; for (int i = 0; i < file.count; i++) { CV_Line line; CV_Column column = new CV_Column(); bits.Position = plin + 8 * i; bits.ReadUInt32(out line.offset); bits.ReadUInt32(out line.flags); uint delta = (line.flags & 0x7f000000) >> 24; bool statement = ((line.flags & 0x80000000) == 0); if ((sec.flags & 1) != 0) { bits.Position = pcol + 4 * i; bits.ReadUInt16(out column.offColumnStart); bits.ReadUInt16(out column.offColumnEnd); } lines[i] = new PdbLine(line.offset, line.flags & 0xffffff, column.offColumnStart, column.offColumnEnd); } } break; } } bits.Position = endSym; } }
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; this.slotToken = 0; 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 scopeCount; int slotCount; CountScopesAndSlots(bits, proc.end, out scopeCount, out slotCount); scopes = new PdbScope[scopeCount]; int scope = 0; 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); // public byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == msilMetaData) { metadata = new byte[stop - bits.Position]; bits.ReadBytes(metadata); 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(block, bits, out slotToken); bits.Position = (int)block.end; break; } case SYM.S_UNAMESPACE: bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; default: { throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); // bits.Position = stop; } } } 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"); } }
private static void LoadTokenToSourceInfo( BitAccess bits, DbiModuleInfo module, IntHashTable names, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader, Dictionary<uint, PdbTokenLine> tokenToSourceMapping) { bits.Position = 0; int sig; bits.ReadInt32(out sig); if (sig != 4) { throw new Exception(string.Format("Invalid signature. (sig={0})", sig)); } bits.Position = 4; while (bits.Position < module.cbSyms) { 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: 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 == "TSLI") { uint token; uint file_id; uint line; uint column; uint endLine; uint endColumn; bits.ReadUInt32(out token); bits.ReadUInt32(out file_id); bits.ReadUInt32(out line); bits.ReadUInt32(out column); bits.ReadUInt32(out endLine); bits.ReadUInt32(out endColumn); PdbTokenLine tokenLine; if (!tokenToSourceMapping.TryGetValue(token, out tokenLine)) tokenToSourceMapping.Add(token, new PdbTokenLine(token, file_id, line, column, endLine, endColumn)); else { while (tokenLine.nextLine != null) tokenLine = tokenLine.nextLine; tokenLine.nextLine = new PdbTokenLine(token, file_id, line, column, endLine, endColumn); } } bits.Position = stop; break; } else { throw new Exception(string.Format("OEM section: guid={0} ti={1}", oem.idOem, oem.typind)); } case SYM.S_END: bits.Position = stop; break; default: bits.Position = stop; break; } } bits.Position = module.cbSyms + module.cbOldLines; int limit = module.cbSyms + module.cbOldLines + module.cbLines; IntHashTable sourceFiles = ReadSourceFileInfo(bits, (uint)limit, names, dir, nameIndex, reader); foreach (var tokenLine in tokenToSourceMapping.Values) { tokenLine.sourceFile = (PdbSource)sourceFiles[(int)tokenLine.file_id]; } }
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; } } } return(funcs); }