diff options
author | Bret Ehlert <bret.ehlert@cargowise.com> | 2012-09-28 05:59:19 +0400 |
---|---|---|
committer | Bret Ehlert <bret.ehlert@cargowise.com> | 2012-10-15 04:33:54 +0400 |
commit | 33a889f8732c4cdeeb6b2c672ed22eb0113a6f51 (patch) | |
tree | fac5193f65814a6acba60d419fb3b6f35308ecc1 /symbols | |
parent | 9f3c0f88b4a3d7568c689421bae39318f5d49540 (diff) |
Update Microsoft.Cci.Pdb with latest code from Cci project (fix Issue #110)
Diffstat (limited to 'symbols')
-rw-r--r-- | symbols/pdb/Microsoft.Cci.Pdb/BitAccess.cs | 6 | ||||
-rw-r--r-- | symbols/pdb/Microsoft.Cci.Pdb/PdbFile.cs | 216 | ||||
-rw-r--r-- | symbols/pdb/Microsoft.Cci.Pdb/PdbFunction.cs | 12 | ||||
-rw-r--r-- | symbols/pdb/Microsoft.Cci.Pdb/PdbScope.cs | 4 | ||||
-rw-r--r-- | symbols/pdb/Microsoft.Cci.Pdb/PdbSlot.cs | 5 | ||||
-rw-r--r-- | symbols/pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs | 33 | ||||
-rw-r--r-- | symbols/pdb/Mono.Cecil.Pdb.csproj | 7 | ||||
-rw-r--r-- | symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs | 9 |
8 files changed, 217 insertions, 75 deletions
diff --git a/symbols/pdb/Microsoft.Cci.Pdb/BitAccess.cs b/symbols/pdb/Microsoft.Cci.Pdb/BitAccess.cs index e8e77b0..d92a5b7 100644 --- a/symbols/pdb/Microsoft.Cci.Pdb/BitAccess.cs +++ b/symbols/pdb/Microsoft.Cci.Pdb/BitAccess.cs @@ -189,6 +189,12 @@ namespace Microsoft.Cci.Pdb { offset += len; } + internal string ReadBString(int len) { + var result = Encoding.UTF8.GetString(buffer, offset, len); + offset += len; + return result; + } + internal void ReadCString(out string value) { int len = 0; while (offset + len < buffer.Length && buffer[offset + len] != 0) { diff --git a/symbols/pdb/Microsoft.Cci.Pdb/PdbFile.cs b/symbols/pdb/Microsoft.Cci.Pdb/PdbFile.cs index 9e56028..a989ce9 100644 --- a/symbols/pdb/Microsoft.Cci.Pdb/PdbFile.cs +++ b/symbols/pdb/Microsoft.Cci.Pdb/PdbFile.cs @@ -26,10 +26,12 @@ namespace Microsoft.Cci.Pdb { bits.ReadGuid(out doctype); } - static Dictionary<string, int> LoadNameIndex(BitAccess bits, out int age, out Guid guid) { + 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 @@ -148,52 +150,9 @@ namespace Microsoft.Cci.Pdb { PdbReader reader, uint limit) { Array.Sort(funcs, PdbFunction.byAddressAndToken); - IntHashTable checks = new IntHashTable(); - // 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]; - int guidStream; - Guid doctypeGuid = SymDocumentType.Text; - Guid languageGuid = Guid.Empty; - Guid vendorGuid = Guid.Empty; - if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { - var guidBits = new BitAccess(0x100); - dir.streams[guidStream].Read(reader, guidBits); - LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); - } - - PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); - checks.Add(ni, src); - bits.Position += chk.len; - bits.Align(4); - } - bits.Position = endSym; - break; - - default: - bits.Position = endSym; - break; - } - } + IntHashTable checks = ReadSourceFileInfo(bits, limit, names, dir, nameIndex, reader); // Read the lines next. bits.Position = begin; @@ -222,7 +181,7 @@ namespace Microsoft.Cci.Pdb { func = f; funcIndex--; } - } else { + } else { while (funcIndex < funcs.Length-1 && func.lines != null) { var f = funcs[funcIndex+1]; if (f.segment != sec.sec || f.address != sec.off) break; @@ -380,12 +339,9 @@ namespace Microsoft.Cci.Pdb { bits.Position = end; } - internal static PdbFunction[] LoadFunctions(Stream read, bool readAllStrings, out int age, out Guid guid) { + internal static PdbFunction[] LoadFunctions(Stream read, out Dictionary<uint, PdbTokenLine> tokenToSourceMapping, out string sourceServerData) { + tokenToSourceMapping = new Dictionary<uint, PdbTokenLine>(); BitAccess bits = new BitAccess(512 * 1024); - return LoadFunctions(read, bits, readAllStrings, out age, out guid); - } - - internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings, out int age, out Guid guid) { PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); @@ -393,26 +349,39 @@ namespace Microsoft.Cci.Pdb { DbiDbgHdr header; dir.streams[1].Read(reader, bits); - Dictionary<string, int> nameIndex = LoadNameIndex(bits, out age, out guid); + Dictionary<string, int> nameIndex = LoadNameIndex(bits); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("No `name' stream"); } - dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); + int srcsrvStream; + if (!nameIndex.TryGetValue("SRCSRV", out srcsrvStream)) + sourceServerData = string.Empty; + else { + DataStream dataStream = dir.streams[srcsrvStream]; + byte[] bytes = new byte[dataStream.contentSize]; + dataStream.Read(reader, bits); + sourceServerData = bits.ReadBString(bytes.Length); + } + dir.streams[3].Read(reader, bits); - LoadDbiStream(bits, out modules, out header, readAllStrings); + LoadDbiStream(bits, out modules, out header, true); ArrayList funcList = new ArrayList(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { - if (modules[m].stream > 0) { - dir.streams[modules[m].stream].Read(reader, bits); - LoadFuncsFromDbiModule(bits, modules[m], names, funcList, - readAllStrings, dir, nameIndex, reader); + var module = modules[m]; + if (module.stream > 0) { + dir.streams[module.stream].Read(reader, bits); + if (module.moduleName == "TokenSourceLineInfo") { + LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, tokenToSourceMapping); + continue; + } + LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader); } } } @@ -435,5 +404,136 @@ namespace Microsoft.Cci.Pdb { //Array.Sort(funcs, PdbFunction.byToken); return funcs; } + + 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 PdbDebugException("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 == PdbFunction.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 PdbDebugException("OEM section: guid={0} ti={1}", + oem.idOem, oem.typind); + // bits.Position = stop; + } + + 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; + } + } + + 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]; + } + + } + + private static IntHashTable ReadSourceFileInfo(BitAccess bits, uint limit, IntHashTable names, MsfDirectory dir, + Dictionary<string, int> nameIndex, PdbReader reader) { + IntHashTable checks = new IntHashTable(); + + 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]; + int guidStream; + Guid doctypeGuid = SymDocumentType.Text; + Guid languageGuid = Guid.Empty; + Guid vendorGuid = Guid.Empty; + if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { + var guidBits = new BitAccess(0x100); + dir.streams[guidStream].Read(reader, guidBits); + LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); + } + + PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); + checks.Add(ni, src); + bits.Position += chk.len; + bits.Align(4); + } + bits.Position = endSym; + break; + + default: + bits.Position = endSym; + break; + } + } + return checks; + } } } diff --git a/symbols/pdb/Microsoft.Cci.Pdb/PdbFunction.cs b/symbols/pdb/Microsoft.Cci.Pdb/PdbFunction.cs index d1daba1..fa0639f 100644 --- a/symbols/pdb/Microsoft.Cci.Pdb/PdbFunction.cs +++ b/symbols/pdb/Microsoft.Cci.Pdb/PdbFunction.cs @@ -22,6 +22,7 @@ namespace Microsoft.Cci.Pdb { internal uint token; internal uint slotToken; + internal uint tokenOfMethodWhoseUsingInfoAppliesToThisMethod; //internal string name; //internal string module; //internal ushort flags; @@ -294,8 +295,7 @@ namespace Microsoft.Cci.Pdb { } case SYM.S_MANSLOT: - uint typind; - slots[slot++] = new PdbSlot(bits, out typind); + slots[slot++] = new PdbSlot(bits); bits.Position = stop; break; @@ -349,7 +349,7 @@ namespace Microsoft.Cci.Pdb { bits.ReadUInt32(out numberOfBytesInItem); switch (kind) { case 0: this.ReadUsingInfo(bits); break; - case 1: break; // this.ReadForwardInfo(bits); break; + case 1: this.ReadForwardInfo(bits); break; case 2: break; // this.ReadForwardedToModuleInfo(bits); break; case 3: this.ReadIteratorLocals(bits); break; case 4: this.ReadForwardIterator(bits); break; @@ -378,8 +378,9 @@ namespace Microsoft.Cci.Pdb { //private void ReadForwardedToModuleInfo(BitAccess bits) { //} - //private void ReadForwardInfo(BitAccess bits) { - //} + private void ReadForwardInfo(BitAccess bits) { + bits.ReadUInt32(out this.tokenOfMethodWhoseUsingInfoAppliesToThisMethod); + } private void ReadUsingInfo(BitAccess bits) { ushort numberOfNamespaces; @@ -449,4 +450,5 @@ namespace Microsoft.Cci.Pdb { //} } + } diff --git a/symbols/pdb/Microsoft.Cci.Pdb/PdbScope.cs b/symbols/pdb/Microsoft.Cci.Pdb/PdbScope.cs index c46220b..d3a34ad 100644 --- a/symbols/pdb/Microsoft.Cci.Pdb/PdbScope.cs +++ b/symbols/pdb/Microsoft.Cci.Pdb/PdbScope.cs @@ -80,7 +80,7 @@ namespace Microsoft.Cci.Pdb { } case SYM.S_MANSLOT: - slots[slot++] = new PdbSlot(bits, out typind); + slots[slot++] = new PdbSlot(bits); bits.Position = stop; break; @@ -88,7 +88,7 @@ namespace Microsoft.Cci.Pdb { bits.ReadCString(out usedNamespaces[usedNs++]); bits.Position = stop; break; - + case SYM.S_END: bits.Position = stop; break; diff --git a/symbols/pdb/Microsoft.Cci.Pdb/PdbSlot.cs b/symbols/pdb/Microsoft.Cci.Pdb/PdbSlot.cs index 0dc89ad..e2b76d5 100644 --- a/symbols/pdb/Microsoft.Cci.Pdb/PdbSlot.cs +++ b/symbols/pdb/Microsoft.Cci.Pdb/PdbSlot.cs @@ -13,12 +13,13 @@ using System; namespace Microsoft.Cci.Pdb { internal class PdbSlot { internal uint slot; + internal uint typeToken; internal string name; internal ushort flags; //internal uint segment; //internal uint address; - internal PdbSlot(BitAccess bits, out uint typind) { + internal PdbSlot(BitAccess bits) { AttrSlotSym slot; bits.ReadUInt32(out slot.index); @@ -29,12 +30,12 @@ namespace Microsoft.Cci.Pdb { 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; - typind = slot.typind; } } } diff --git a/symbols/pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs b/symbols/pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs new file mode 100644 index 0000000..879339b --- /dev/null +++ b/symbols/pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class PdbTokenLine { + internal uint token; + internal uint file_id; + internal uint line; + internal uint column; + internal uint endLine; + internal uint endColumn; + internal PdbSource sourceFile; + internal PdbTokenLine/*?*/ nextLine; + + internal PdbTokenLine(uint token, uint file_id, uint line, uint column, uint endLine, uint endColumn) { + this.token = token; + this.file_id = file_id; + this.line = line; + this.column = column; + this.endLine = endLine; + this.endColumn = endColumn; + } + } +} diff --git a/symbols/pdb/Mono.Cecil.Pdb.csproj b/symbols/pdb/Mono.Cecil.Pdb.csproj index 5248bad..e35add0 100644 --- a/symbols/pdb/Mono.Cecil.Pdb.csproj +++ b/symbols/pdb/Mono.Cecil.Pdb.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">net_4_0_Debug</Configuration> @@ -108,7 +108,10 @@ <Compile Include="Microsoft.Cci.Pdb\PdbScope.cs" /> <Compile Include="Microsoft.Cci.Pdb\PdbSlot.cs" /> <Compile Include="Microsoft.Cci.Pdb\PdbSource.cs" /> - <Compile Include="Microsoft.Cci.Pdb\SourceLocationProvider.cs" /> + <Compile Include="Microsoft.Cci.Pdb\PdbTokenLine.cs" /> + <Compile Include="Microsoft.Cci.Pdb\SourceLocationProvider.cs"> + <SubType>Code</SubType> + </Compile> <Compile Include="Mono.Cecil.Pdb\AssemblyInfo.cs" /> <Compile Include="Mono.Cecil.Pdb\ISymUnmanagedDocumentWriter.cs" /> <Compile Include="Mono.Cecil.Pdb\ISymUnmanagedWriter2.cs" /> diff --git a/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs b/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs index 9d71666..279c896 100644 --- a/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs +++ b/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs @@ -86,12 +86,9 @@ namespace Mono.Cecil.Pdb { bool PopulateFunctions () { using (pdb_file) { - int age; - Guid guid; - var funcs = PdbFile.LoadFunctions (pdb_file, true, out age, out guid); - - if (this.age != 0 && this.guid != guid) - return false; + Dictionary<uint, PdbTokenLine> tokenToSourceMapping; + string sourceServerData; + var funcs = PdbFile.LoadFunctions (pdb_file, out tokenToSourceMapping, out sourceServerData); foreach (PdbFunction function in funcs) functions.Add (function.token, function); |