static void DumpCvInfo(BitAccess bits, int begin, int limit) { int indent = 0; string pad = ""; while (bits.Position < limit) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; #if false Dump(bits.GetBuffer(), star, stop); bits.Position = star; #endif bits.ReadUInt16(out rec); SYM cv = (SYM)rec; if (rec < 0x1000) { if (cv != SYM.S_END && cv != SYM.S_OEM) { throw new Exception("CV is unknown: " + rec); } } switch (cv) { 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 == PdbFunction.msilMetaData) { Console.WriteLine(" {0}META: ", pad); Dump(bits.Buffer, star + 22, stop); break; } else { Console.WriteLine(" {0}OEMS: guid={1} ti={2}", pad, oem.idOem, oem.typind); Dump(bits.Buffer, star + 22, stop); } break; } case SYM.S_OBJNAME: { // 0x1101 ObjNameSym obj; bits.ReadUInt32(out obj.signature); bits.ReadCString(out obj.name); Console.WriteLine(" {0}OBJN: sig={1:x8} [{2}]", pad, obj.signature, obj.name); break; } case SYM.S_FRAMEPROC: { // 0x1012 FrameProcSym frame; bits.ReadUInt32(out frame.cbFrame); bits.ReadUInt32(out frame.cbPad); bits.ReadUInt32(out frame.offPad); bits.ReadUInt32(out frame.cbSaveRegs); bits.ReadUInt32(out frame.offExHdlr); bits.ReadUInt16(out frame.secExHdlr); bits.ReadUInt32(out frame.flags); Console.WriteLine(" {0}FRAM: size={1}, pad={2}+{3}, exc={4:x4}:{5:x8}, flags={6:x3}", pad, frame.cbFrame, frame.cbPad, frame.offPad, frame.offExHdlr, frame.secExHdlr, frame.flags); break; } case SYM.S_BLOCK32: { // 0x1103 BlockSym32 block; 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.ReadCString(out block.name); Console.WriteLine(" {0}BLCK: par={1}, addr={2:x4}:{3:x8} len={4:x4} [{5}], end={6}", pad, block.parent, block.seg, block.off, block.len, block.name, block.end); indent++; pad = new String('.', indent); break; } case SYM.S_COMPILE2: { // 0x1116 CompileSym com; bits.ReadUInt32(out com.flags); bits.ReadUInt16(out com.machine); bits.ReadUInt16(out com.verFEMajor); bits.ReadUInt16(out com.verFEMinor); bits.ReadUInt16(out com.verFEBuild); bits.ReadUInt16(out com.verMajor); bits.ReadUInt16(out com.verMinor); bits.ReadUInt16(out com.verBuild); bits.ReadCString(out com.verSt); Console.WriteLine(" {0}COMP: flg={1:x4} mach={2:x2} [{3}] {4}.{5}.{6}.{7}.{8}.{9}", pad, com.flags, com.machine, com.verSt, com.verFEMajor, com.verFEMinor, com.verFEBuild, com.verMajor, com.verMinor, com.verBuild); break; } case SYM.S_BPREL32: { // 0x110b BpRelSym32 bp; bits.ReadInt32(out bp.off); bits.ReadUInt32(out bp.typind); bits.ReadCString(out bp.name); Console.WriteLine(" {0}BPRL: ti={1:x8} [{2}] off={3,6}", pad, bp.typind, bp.name, bp.off); break; } case SYM.S_LPROC32: // 0x110f case SYM.S_GPROC32: { // 0x1110 ProcSym32 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.typind); bits.ReadUInt32(out proc.off); bits.ReadUInt16(out proc.seg); bits.ReadUInt8(out proc.flags); bits.ReadCString(out proc.name); Console.WriteLine(" {0}PROC: ti={1,5} [{2}] addr={3:x4}:{4:x8} len={5} f={6:x4}, end={7}", pad, proc.typind, proc.name, proc.seg, proc.off, proc.len, proc.flags, proc.end); if (proc.parent != 0 || proc.next != 0) { Console.WriteLine(" !!! Warning parent={0}, next={1}", proc.parent, proc.next); } indent++; pad = new String('.', indent); break; } case SYM.S_MANSLOT: { // 0x1120 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); Console.WriteLine(" {0}SLOT: ti={1:x8} [{2}] slot={3} flg={4:x4}", pad, slot.typind, slot.name, slot.index, slot.flags); if (slot.segCod != 0 || slot.offCod != 0) { Console.WriteLine(" !!! Warning: addr={0:x4}:{1:x8}", slot.segCod, slot.offCod); } break; } case SYM.S_UNAMESPACE: { // 0x1124 UnamespaceSym ns; bits.ReadCString(out ns.name); Console.WriteLine(" {0}NAME: using [{1}]", pad, ns.name); break; } case SYM.S_GMANPROC: // 0x112a case SYM.S_LMANPROC: { // 0x112b 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); bits.ReadCString(out proc.name); Console.WriteLine(" {0}PROC: token={1:x8} [{2}] addr={3:x4}:{4:x8} len={5:x4} f={6:x4}, end={7}", pad, proc.token, proc.name, proc.seg, proc.off, proc.len, proc.flags, proc.end); if (proc.parent != 0 || proc.next != 0) { Console.WriteLine(" !!! Warning par={0}, pnext={1}", proc.parent, proc.next); } if (proc.dbgStart != 0 || proc.dbgEnd != 0) { Console.WriteLine(" !!! Warning DBG start={0}, end={1}", proc.dbgStart, proc.dbgEnd); } indent++; pad = new String('.', indent); break; } case SYM.S_END: { // 0x0006 indent--; pad = new String('.', indent); Console.WriteLine(" {0}END {1}", pad, bits.Position - 4); break; } case SYM.S_SECTION: { // 0x1136 SectionSym sect; bits.ReadUInt16(out sect.isec); bits.ReadUInt8(out sect.align); bits.ReadUInt8(out sect.bReserved); bits.ReadUInt32(out sect.rva); bits.ReadUInt32(out sect.cb); bits.ReadUInt32(out sect.characteristics); bits.ReadCString(out sect.name); Console.WriteLine(" {0}SECT: sec={1,4} align={2}, flags={3:x8} [{4}]", pad, sect.isec, sect.align, sect.characteristics, sect.name); break; } case SYM.S_COFFGROUP: { // 0x1137 CoffGroupSym group; bits.ReadUInt32(out group.cb); bits.ReadUInt32(out group.characteristics); bits.ReadUInt32(out group.off); bits.ReadUInt16(out group.seg); bits.ReadCString(out group.name); Console.WriteLine(" {0}CGRP: flags={1:x8} [{2}] addr={3:x4}:{4:x8}", pad, group.characteristics, group.name, group.seg, group.off); break; } case SYM.S_THUNK32: { // 0x1102 ThunkSym32 thunk; bits.ReadUInt32(out thunk.parent); bits.ReadUInt32(out thunk.end); bits.ReadUInt32(out thunk.next); bits.ReadUInt32(out thunk.off); bits.ReadUInt16(out thunk.seg); bits.ReadUInt16(out thunk.len); bits.ReadUInt8(out thunk.ord); bits.ReadCString(out thunk.name); Console.WriteLine(" {0}THNK: addr={1:x4}:{2:x8} [{3}], end={4}", pad, thunk.seg, thunk.off, thunk.name, thunk.end); indent++; pad = new String('.', indent); break; } default: { Console.WriteLine(" {0}{1}:", pad, cv); Dump(bits.Buffer, star + 2, stop); break; } } bits.Position = stop; } if (indent != 0) { throw new Exception("indent isn't 0."); } }