in ClrMemDiag/Utilities/PDB/PdbFunction.cs [243:392]
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];
Namespaces = new string[usedNamespacesCount];
if (scope > 0)
Scopes[0] = new PdbScope(this.Address, proc.len, Slots, Constants, Namespaces);
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);
}
}
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:
uint typind;
Slots[slot++] = new PdbSlot(bits, out typind);
bits.Position = stop;
break;
case SYM.S_MANCONSTANT:
Constants[constant++] = new PdbConstant(bits);
bits.Position = stop;
break;
case SYM.S_UNAMESPACE:
bits.ReadCString(out Namespaces[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");
}
}