Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,229 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.IO;
using System.Text;
namespace Microsoft.Cci.Pdb {
internal class BitAccess {
internal BitAccess(int capacity) {
this.buffer = new byte[capacity];
this.offset = 0;
}
internal byte[] Buffer {
get { return buffer; }
}
private byte[] buffer;
internal void FillBuffer(Stream stream, int capacity) {
MinCapacity(capacity);
stream.Read(buffer, 0, capacity);
offset = 0;
}
internal int Position {
get { return offset; }
set { offset = value; }
}
private int offset;
internal void WriteBuffer(Stream stream, int count) {
stream.Write(buffer, 0, count);
}
internal void MinCapacity(int capacity) {
if (buffer.Length < capacity) {
buffer = new byte[capacity];
}
offset = 0;
}
internal void Align(int alignment) {
while ((offset % alignment) != 0) {
offset++;
}
}
internal void WriteInt32(int value) {
buffer[offset + 0] = (byte)value;
buffer[offset + 1] = (byte)(value >> 8);
buffer[offset + 2] = (byte)(value >> 16);
buffer[offset + 3] = (byte)(value >> 24);
offset += 4;
}
internal void WriteInt32(int[] values) {
for (int i = 0; i < values.Length; i++) {
WriteInt32(values[i]);
}
}
internal void WriteBytes(byte[] bytes) {
for (int i = 0; i < bytes.Length; i++) {
buffer[offset++] = bytes[i];
}
}
internal void ReadInt16(out short value) {
value = (short)((buffer[offset + 0] & 0xFF) |
(buffer[offset + 1] << 8));
offset += 2;
}
internal void ReadInt32(out int value) {
value = (int)((buffer[offset + 0] & 0xFF) |
(buffer[offset + 1] << 8) |
(buffer[offset + 2] << 16) |
(buffer[offset + 3] << 24));
offset += 4;
}
internal void ReadInt64(out long value) {
value = (long)((buffer[offset + 0] & 0xFF) |
(buffer[offset + 1] << 8) |
(buffer[offset + 2] << 16) |
(buffer[offset + 3] << 24) |
(buffer[offset + 4] << 32) |
(buffer[offset + 5] << 40) |
(buffer[offset + 6] << 48) |
(buffer[offset + 7] << 56));
offset += 8;
}
internal void ReadUInt16(out ushort value) {
value = (ushort)((buffer[offset + 0] & 0xFF) |
(buffer[offset + 1] << 8));
offset += 2;
}
internal void ReadUInt8(out byte value) {
value = (byte)((buffer[offset + 0] & 0xFF));
offset += 1;
}
internal void ReadUInt32(out uint value) {
value = (uint)((buffer[offset + 0] & 0xFF) |
(buffer[offset + 1] << 8) |
(buffer[offset + 2] << 16) |
(buffer[offset + 3] << 24));
offset += 4;
}
internal void ReadUInt64(out ulong value) {
value = (ulong)((buffer[offset + 0] & 0xFF) |
(buffer[offset + 1] << 8) |
(buffer[offset + 2] << 16) |
(buffer[offset + 3] << 24) |
(buffer[offset + 4] << 32) |
(buffer[offset + 5] << 40) |
(buffer[offset + 6] << 48) |
(buffer[offset + 7] << 56));
offset += 8;
}
internal void ReadInt32(int[] values) {
for (int i = 0; i < values.Length; i++) {
ReadInt32(out values[i]);
}
}
internal void ReadUInt32(uint[] values) {
for (int i = 0; i < values.Length; i++) {
ReadUInt32(out values[i]);
}
}
internal void ReadBytes(byte[] bytes) {
for (int i = 0; i < bytes.Length; i++) {
bytes[i] = buffer[offset++];
}
}
internal float ReadFloat() {
float result = BitConverter.ToSingle(buffer, offset);
offset += 4;
return result;
}
internal double ReadDouble() {
double result = BitConverter.ToDouble(buffer, offset);
offset += 8;
return result;
}
internal decimal ReadDecimal() {
int[] bits = new int[4];
this.ReadInt32(bits);
return new decimal(bits);
}
internal void ReadBString(out string value) {
ushort len;
this.ReadUInt16(out len);
value = Encoding.UTF8.GetString(buffer, offset, len);
offset += len;
}
internal void ReadCString(out string value) {
int len = 0;
while (offset + len < buffer.Length && buffer[offset + len] != 0) {
len++;
}
value = Encoding.UTF8.GetString(buffer, offset, len);
offset += len + 1;
}
internal void SkipCString(out string value) {
int len = 0;
while (offset + len < buffer.Length && buffer[offset + len] != 0) {
len++;
}
offset += len + 1;
value= null;
}
internal void ReadGuid(out Guid guid) {
uint a;
ushort b;
ushort c;
byte d;
byte e;
byte f;
byte g;
byte h;
byte i;
byte j;
byte k;
ReadUInt32(out a);
ReadUInt16(out b);
ReadUInt16(out c);
ReadUInt8(out d);
ReadUInt8(out e);
ReadUInt8(out f);
ReadUInt8(out g);
ReadUInt8(out h);
ReadUInt8(out i);
ReadUInt8(out j);
ReadUInt8(out k);
guid = new Guid(a, b, c, d, e, f, g, h, i, j, k);
}
internal string ReadString() {
int len = 0;
while (offset + len < buffer.Length && buffer[offset + len] != 0) {
len+=2;
}
string result = Encoding.Unicode.GetString(buffer, offset, len);
offset += len + 2;
return result;
}
}
}

View File

@@ -0,0 +1,69 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
namespace Microsoft.Cci.Pdb {
internal struct BitSet {
internal BitSet(BitAccess bits) {
bits.ReadInt32(out size); // 0..3 : Number of words
words = new uint[size];
bits.ReadUInt32(words);
}
internal BitSet(int size) {
this.size = size;
words = new uint[size];
}
internal bool IsSet(int index) {
int word = index / 32;
if (word >= this.size) return false;
return ((words[word] & GetBit(index)) != 0);
}
internal void Set(int index) {
int word = index / 32;
if (word >= this.size) return;
words[word] |= GetBit(index);
}
internal void Clear(int index) {
int word = index / 32;
if (word >= this.size) return;
words[word] &= ~GetBit(index);
}
private uint GetBit(int index) {
return ((uint)1 << (index % 32));
}
private uint ReverseBits(uint value) {
uint o = 0;
for (int i = 0; i < 32; i++) {
o = (o << 1) | (value & 1);
value >>= 1;
}
return o;
}
internal bool IsEmpty {
get { return size == 0; }
}
internal bool GetWord(int index, out uint word) {
if (index < size) {
word = ReverseBits(words[index]);
return true;
}
word = 0;
return false;
}
private int size;
private uint[] words;
}
}

View File

@@ -0,0 +1,16 @@
2009-04-27 Jb Evain <jbevain@novell.com>
* sync with CodePlex r10923.
2009-04-23 Jb Evain <jbevain@novell.com>
* pdb2mdb.exe.sources: added.
* Makefile: update to the mcs build system.
2009-04-21 Jb Evain <jbevain@novell.com>
* Driver.cs: don't crash if a function doesn't have line information.
2009-04-20 Jb Evain <jbevain@novell.com>
* Initial commit of my week-end's hack: a fully managed pdb2mdb.

2430
mcs/tools/pdb2mdb/CvInfo.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,146 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.IO;
namespace Microsoft.Cci.Pdb {
internal class DataStream {
internal DataStream() {
this.contentSize = 0;
this.pages = null;
}
internal DataStream(int contentSize, BitAccess bits, int count) {
this.contentSize = contentSize;
if (count > 0) {
this.pages = new int[count];
bits.ReadInt32(this.pages);
}
}
internal void Read(PdbReader reader, BitAccess bits) {
bits.MinCapacity(contentSize);
Read(reader, 0, bits.Buffer, 0, contentSize);
}
internal void Read(PdbReader reader, int position,
byte[] bytes, int offset, int data) {
if (position + data > contentSize) {
throw new PdbException("DataStream can't read off end of stream. " +
"(pos={0},siz={1})",
position, data);
}
if (position == contentSize) {
return;
}
int left = data;
int page = position / reader.pageSize;
int rema = position % reader.pageSize;
// First get remained of first page.
if (rema != 0) {
int todo = reader.pageSize - rema;
if (todo > left) {
todo = left;
}
reader.Seek(pages[page], rema);
reader.Read(bytes, offset, todo);
offset += todo;
left -= todo;
page++;
}
// Now get the remaining pages.
while (left > 0) {
int todo = reader.pageSize;
if (todo > left) {
todo = left;
}
reader.Seek(pages[page], 0);
reader.Read(bytes, offset, todo);
offset += todo;
left -= todo;
page++;
}
}
internal void Write(PdbWriter writer, byte[] bytes) {
Write(writer, bytes, bytes.Length);
}
internal void Write(PdbWriter writer, byte[] bytes, int data) {
if (bytes == null || data == 0) {
return;
}
int left = data;
int used = 0;
int rema = contentSize % writer.pageSize;
if (rema != 0) {
int todo = writer.pageSize - rema;
if (todo > left) {
todo = left;
}
int lastPage = pages[pages.Length - 1];
writer.Seek(lastPage, rema);
writer.Write(bytes, used, todo);
used += todo;
left -= todo;
}
if (left > 0) {
int count = (left + writer.pageSize - 1) / writer.pageSize;
int page0 = writer.AllocatePages(count);
writer.Seek(page0, 0);
writer.Write(bytes, used, left);
AddPages(page0, count);
}
contentSize += data;
}
private void AddPages(int page0, int count) {
if (pages == null) {
pages = new int[count];
for (int i = 0; i < count; i++) {
pages[i] = page0 + i;
}
} else {
int[] old = pages;
int used = old.Length;
pages = new int[used + count];
Array.Copy(old, pages, used);
for (int i = 0; i < count; i++) {
pages[used + i] = page0 + i;
}
}
}
internal int Pages {
get { return pages == null ? 0 : pages.Length; }
}
internal int Length {
get { return contentSize; }
}
internal int GetPage(int index) {
return pages[index];
}
internal int contentSize;
internal int[] pages;
}
}

View File

@@ -0,0 +1,36 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
namespace Microsoft.Cci.Pdb {
internal struct DbiDbgHdr {
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 ushort snFPO; // 0..1
internal ushort snException; // 2..3 (deprecated)
internal ushort snFixup; // 4..5
internal ushort snOmapToSrc; // 6..7
internal ushort snOmapFromSrc; // 8..9
internal ushort snSectionHdr; // 10..11
internal ushort snTokenRidMap; // 12..13
internal ushort snXdata; // 14..15
internal ushort snPdata; // 16..17
internal ushort snNewFPO; // 18..19
internal ushort snSectionHdrOrig; // 20..21
}
}

View File

@@ -0,0 +1,54 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
namespace Microsoft.Cci.Pdb {
internal struct DbiHeader {
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 int sig; // 0..3
internal int ver; // 4..7
internal int age; // 8..11
internal short gssymStream; // 12..13
internal ushort vers; // 14..15
internal short pssymStream; // 16..17
internal ushort pdbver; // 18..19
internal short symrecStream; // 20..21
internal ushort pdbver2; // 22..23
internal int gpmodiSize; // 24..27
internal int secconSize; // 28..31
internal int secmapSize; // 32..35
internal int filinfSize; // 36..39
internal int tsmapSize; // 40..43
internal int mfcIndex; // 44..47
internal int dbghdrSize; // 48..51
internal int ecinfoSize; // 52..55
internal ushort flags; // 56..57
internal ushort machine; // 58..59
internal int reserved; // 60..63
}
}

View File

@@ -0,0 +1,52 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
namespace Microsoft.Cci.Pdb {
internal class DbiModuleInfo {
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);
//}
}
internal int opened; // 0..3
internal DbiSecCon section; // 4..31
internal ushort flags; // 32..33
internal short stream; // 34..35
internal int cbSyms; // 36..39
internal int cbOldLines; // 40..43
internal int cbLines; // 44..57
internal short files; // 48..49
internal short pad1; // 50..51
internal uint offsets;
internal int niSource;
internal int niCompiler;
internal string moduleName;
internal string objectName;
}
}

View File

@@ -0,0 +1,37 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
namespace Microsoft.Cci.Pdb {
internal struct DbiSecCon {
internal DbiSecCon(BitAccess bits) {
bits.ReadInt16(out section);
bits.ReadInt16(out pad1);
bits.ReadInt32(out offset);
bits.ReadInt32(out size);
bits.ReadUInt32(out flags);
bits.ReadInt16(out module);
bits.ReadInt16(out pad2);
bits.ReadUInt32(out dataCrc);
bits.ReadUInt32(out relocCrc);
//if (pad1 != 0 || pad2 != 0) {
// throw new PdbException("Invalid DBI section. "+
// "(pad1={0}, pad2={1})",
// pad1, pad2);
//}
}
internal short section; // 0..1
internal short pad1; // 2..3
internal int offset; // 4..7
internal int size; // 8..11
internal uint flags; // 12..15
internal short module; // 16..17
internal short pad2; // 18..19
internal uint dataCrc; // 20..23
internal uint relocCrc; // 24..27
}
}

205
mcs/tools/pdb2mdb/Driver.cs Normal file
View File

@@ -0,0 +1,205 @@
//
// Driver.cs
//
// Author:
// Jb Evain (jbevain@novell.com)
//
// (C) 2009 Novell, Inc. (http://www.novell.com)
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Cci;
using Microsoft.Cci.Pdb;
using Mono.Cecil;
using Mono.CompilerServices.SymbolWriter;
namespace Pdb2Mdb {
public class Converter {
MonoSymbolWriter mdb;
Dictionary<string, SourceFile> files = new Dictionary<string, SourceFile> ();
public static void Convert (string filename)
{
var asm = AssemblyDefinition.ReadAssembly (filename);
var pdb = asm.Name.Name + ".pdb";
pdb = Path.Combine (Path.GetDirectoryName (filename), pdb);
using (var stream = File.OpenRead (pdb)) {
var funcs = PdbFile.LoadFunctions (stream, true);
Converter.Convert (asm, funcs, new MonoSymbolWriter (filename));
}
}
internal Converter (MonoSymbolWriter mdb)
{
this.mdb = mdb;
}
internal static void Convert (AssemblyDefinition assembly, IEnumerable<PdbFunction> functions, MonoSymbolWriter mdb)
{
var converter = new Converter (mdb);
foreach (var function in functions)
converter.ConvertFunction (function);
mdb.WriteSymbolFile (assembly.MainModule.Mvid);
}
void ConvertFunction (PdbFunction function)
{
if (function.lines == null)
return;
var method = new SourceMethod { Name = function.name, Token = (int) function.token };
var file = GetSourceFile (mdb, function);
var builder = mdb.OpenMethod (file.CompilationUnit, 0, method);
ConvertSequencePoints (function, file, builder);
ConvertVariables (function);
mdb.CloseMethod ();
}
void ConvertSequencePoints (PdbFunction function, SourceFile file, SourceMethodBuilder builder)
{
int last_line = 0;
foreach (var line in function.lines.SelectMany (lines => lines.lines)) {
// 0xfeefee is an MS convention, we can't pass it into mdb files, so we use the last non-hidden line
bool is_hidden = line.lineBegin == 0xfeefee;
builder.MarkSequencePoint (
(int) line.offset,
file.CompilationUnit.SourceFile,
is_hidden ? last_line : (int) line.lineBegin,
(int) line.colBegin, is_hidden ? -1 : (int)line.lineEnd, is_hidden ? -1 : (int)line.colEnd,
is_hidden);
if (!is_hidden)
last_line = (int) line.lineBegin;
}
}
void ConvertVariables (PdbFunction function)
{
foreach (var scope in function.scopes)
ConvertScope (scope);
}
void ConvertScope (PdbScope scope)
{
ConvertSlots (scope.slots);
foreach (var s in scope.scopes)
ConvertScope (s);
}
void ConvertSlots (IEnumerable<PdbSlot> slots)
{
foreach (var slot in slots)
mdb.DefineLocalVariable ((int) slot.slot, slot.name);
}
SourceFile GetSourceFile (MonoSymbolWriter mdb, PdbFunction function)
{
var name = (from l in function.lines where l.file != null select l.file.name).First ();
SourceFile file;
if (files.TryGetValue (name, out file))
return file;
var entry = mdb.DefineDocument (name);
var unit = mdb.DefineCompilationUnit (entry);
file = new SourceFile (unit, entry);
files.Add (name, file);
return file;
}
class SourceFile : ISourceFile {
CompileUnitEntry comp_unit;
SourceFileEntry entry;
public SourceFileEntry Entry
{
get { return entry; }
}
public CompileUnitEntry CompilationUnit
{
get { return comp_unit; }
}
public SourceFile (CompileUnitEntry comp_unit, SourceFileEntry entry)
{
this.comp_unit = comp_unit;
this.entry = entry;
}
}
class SourceMethod : IMethodDef {
public string Name { get; set; }
public int Token { get; set; }
}
}
class Driver {
static void Main (string [] args)
{
if (args.Length != 1)
Usage ();
var asm = args [0];
if (!File.Exists (asm))
Usage ();
var assembly = AssemblyDefinition.ReadAssembly (asm);
var pdb = assembly.Name.Name + ".pdb";
pdb = Path.Combine (Path.GetDirectoryName (asm), pdb);
if (!File.Exists (pdb))
Usage ();
using (var stream = File.OpenRead (pdb)) {
Convert (assembly, stream, new MonoSymbolWriter (asm));
}
}
static void Convert (AssemblyDefinition assembly, Stream pdb, MonoSymbolWriter mdb)
{
try {
Converter.Convert (assembly, PdbFile.LoadFunctions (pdb, true), mdb);
} catch (Exception e) {
Error (e);
}
}
static void Usage ()
{
Console.WriteLine ("Mono pdb to mdb debug symbol store converter");
Console.WriteLine ("Usage: pdb2mdb assembly");
Environment.Exit (1);
}
static void Error (Exception e)
{
Console.WriteLine ("Fatal error:");
Console.WriteLine (e);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
namespace Microsoft.Cci {
/// <summary>
/// A range of CLR IL operations that comprise a lexical scope, specified as an IL offset and a length.
/// </summary>
public interface ILocalScope {
/// <summary>
/// The offset of the first operation in the scope.
/// </summary>
uint Offset { get; }
/// <summary>
/// The length of the scope. Offset+Length equals the offset of the first operation outside the scope, or equals the method body length.
/// </summary>
uint Length { get; }
}
/// <summary>
/// A description of the lexical scope in which a namespace type has been nested. This scope is tied to a particular
/// method body, so that partial types can be accommodated.
/// </summary>
public interface INamespaceScope {
/// <summary>
/// Zero or more used namespaces. These correspond to using clauses in C#.
/// </summary>
IEnumerable<IUsedNamespace> UsedNamespaces { get; }
}
/// <summary>
/// A namespace that is used (imported) inside a namespace scope.
/// </summary>
public interface IUsedNamespace {
/// <summary>
/// An alias for a namespace. For example the "x" of "using x = y.z;" in C#. Empty if no alias is present.
/// </summary>
IName Alias { get; }
/// <summary>
/// The name of a namepace that has been aliased. For example the "y.z" of "using x = y.z;" or "using y.z" in C#.
/// </summary>
IName NamespaceName { get; }
}
/// <summary>
/// The name of an entity. Typically name instances come from a common pool. Within the pool no two distinct instances will have the same Value or UniqueKey.
/// </summary>
public interface IName {
/// <summary>
/// An integer that is unique within the pool from which the name instance has been allocated. Useful as a hashtable key.
/// </summary>
int UniqueKey {
get;
//^ ensures result > 0;
}
/// <summary>
/// An integer that is unique within the pool from which the name instance has been allocated. Useful as a hashtable key.
/// All name instances in the pool that have the same string value when ignoring the case of the characters in the string
/// will have the same key value.
/// </summary>
int UniqueKeyIgnoringCase {
get;
//^ ensures result > 0;
}
/// <summary>
/// The string value corresponding to this name.
/// </summary>
string Value { get; }
}
}

22
mcs/tools/pdb2mdb/LICENSE Normal file
View File

@@ -0,0 +1,22 @@
Microsoft Public License (Ms-PL)
This license governs use of the accompanying software. If you use the software, you
accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.

View File

@@ -0,0 +1,13 @@
thisdir = tools/pdb2mdb
SUBDIRS =
include ../../build/rules.make
PROGRAM = pdb2mdb.exe
LOCAL_MCS_FLAGS = \
/r:Mono.Cecil.dll \
/r:Mono.CompilerServices.SymbolWriter.dll
EXTRA_DISTFILES = LICENSE
include ../../build/executable.make

View File

@@ -0,0 +1,45 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
namespace Microsoft.Cci.Pdb {
internal class MsfDirectory {
internal MsfDirectory(PdbReader reader, PdbFileHeader head, BitAccess bits) {
bits.MinCapacity(head.directorySize);
int pages = reader.PagesFromSize(head.directorySize);
// 0..n in page of directory pages.
reader.Seek(head.directoryRoot, 0);
bits.FillBuffer(reader.reader, pages * 4);
DataStream stream = new DataStream(head.directorySize, bits, pages);
bits.MinCapacity(head.directorySize);
stream.Read(reader, bits);
// 0..3 in directory pages
int count;
bits.ReadInt32(out count);
// 4..n
int[] sizes = new int[count];
bits.ReadInt32(sizes);
// n..m
streams = new DataStream[count];
for (int i = 0; i < count; i++) {
if (sizes[i] <= 0) {
streams[i] = new DataStream();
} else {
streams[i] = new DataStream(sizes[i], bits,
reader.PagesFromSize(sizes[i]));
}
}
}
internal DataStream[] streams;
}
}

View File

@@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;
namespace Microsoft.Cci.Pdb {
internal class PdbConstant {
internal string name;
internal uint token;
internal object value;
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 name);
}
}
}

View File

@@ -0,0 +1,15 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.IO;
namespace Microsoft.Cci.Pdb {
internal class PdbDebugException : IOException {
internal PdbDebugException(String format, params object[] args)
: base(String.Format(format, args)) {
}
}
}

View File

@@ -0,0 +1,15 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.IO;
namespace Microsoft.Cci.Pdb {
internal class PdbException : IOException {
internal PdbException(String format, params object[] args)
: base(String.Format(format, args)) {
}
}
}

View File

@@ -0,0 +1,423 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics.SymbolStore;
namespace Microsoft.Cci.Pdb {
internal class PdbFile {
private PdbFile() // This class can't be instantiated.
{
}
static void LoadGuidStream(BitAccess bits, out Guid doctype, out Guid language, out Guid vendor) {
bits.ReadGuid(out language);
bits.ReadGuid(out vendor);
bits.ReadGuid(out doctype);
}
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, ni);
j++;
}
}
if (j != cnt) {
throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt);
}
return result;
}
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;
}
private static PdbFunction match = new PdbFunction();
private static PdbFunction FindFunction(PdbFunction[] funcs, ushort sec, uint off) {
match.segment = sec;
match.address = off;
int item = Array.BinarySearch(funcs, match, PdbFunction.byAddress);
if (item >= 0) {
return funcs[item];
}
return null;
}
static void LoadManagedLines(PdbFunction[] funcs,
IntHashTable names,
BitAccess bits,
MsfDirectory dir,
Dictionary<string, int> nameIndex,
PdbReader reader,
uint limit) {
Array.Sort(funcs, PdbFunction.byAddress);
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 = SymLanguageType.CSharp;
Guid vendorGuid = SymLanguageVendor.Microsoft;
if (nameIndex.TryGetValue("/src/files/"+name, 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;
}
}
// 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);
if (func == null) break;
// 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 lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart;
uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24;
bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 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,
lineBegin,
column.offColumnStart,
lineBegin+delta,
column.offColumnEnd);
}
}
break;
}
}
bits.Position = endSym;
}
}
static void LoadFuncsFromDbiModule(BitAccess bits,
DbiModuleInfo info,
IntHashTable names,
ArrayList funcList,
bool readStrings,
MsfDirectory dir,
Dictionary<string, int> nameIndex,
PdbReader reader) {
PdbFunction[] funcs = null;
bits.Position = 0;
int sig;
bits.ReadInt32(out sig);
if (sig != 4) {
throw new PdbDebugException("Invalid signature. (sig={0})", sig);
}
bits.Position = 4;
// Console.WriteLine("{0}:", info.moduleName);
funcs = PdbFunction.LoadManagedFunctions(info.moduleName,
bits, (uint)info.cbSyms,
readStrings);
if (funcs != null) {
bits.Position = info.cbSyms + info.cbOldLines;
LoadManagedLines(funcs, names, bits, dir, nameIndex, reader,
(uint)(info.cbSyms + info.cbOldLines + info.cbLines));
for (int i = 0; i < funcs.Length; i++) {
funcList.Add(funcs[i]);
}
}
}
static void LoadDbiStream(BitAccess bits,
out DbiModuleInfo[] modules,
out DbiDbgHdr header,
bool readStrings) {
DbiHeader dh = new DbiHeader(bits);
header = new DbiDbgHdr();
if (dh.sig != -1 || dh.ver != 19990903) {
throw new PdbException("Unsupported DBI Stream version, sig={0}, ver={1}",
dh.sig, dh.ver);
}
// Read gpmod section.
ArrayList modList = new ArrayList();
int end = bits.Position + dh.gpmodiSize;
while (bits.Position < end) {
DbiModuleInfo mod = new DbiModuleInfo(bits, readStrings);
modList.Add(mod);
}
if (bits.Position != end) {
throw new PdbDebugException("Error reading DBI stream, pos={0} != {1}",
bits.Position, end);
}
if (modList.Count > 0) {
modules = (DbiModuleInfo[])modList.ToArray(typeof(DbiModuleInfo));
} else {
modules = null;
}
// Skip the Section Contribution substream.
bits.Position += dh.secconSize;
// Skip the Section Map substream.
bits.Position += dh.secmapSize;
// Skip the File Info substream.
bits.Position += dh.filinfSize;
// Skip the TSM substream.
bits.Position += dh.tsmapSize;
// Skip the EC substream.
bits.Position += dh.ecinfoSize;
// Read the optional header.
end = bits.Position + dh.dbghdrSize;
if (dh.dbghdrSize > 0) {
header = new DbiDbgHdr(bits);
}
bits.Position = end;
}
internal static PdbFunction[] LoadFunctions(Stream read, bool readAllStrings) {
BitAccess bits = new BitAccess(512 * 1024);
return LoadFunctions(read, bits, readAllStrings);
}
internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings) {
PdbFileHeader head = new PdbFileHeader(read, bits);
PdbReader reader = new PdbReader(read, head.pageSize);
MsfDirectory dir = new MsfDirectory(reader, head, bits);
DbiModuleInfo[] modules = null;
DbiDbgHdr header;
dir.streams[1].Read(reader, bits);
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);
dir.streams[3].Read(reader, bits);
LoadDbiStream(bits, out modules, out header, readAllStrings);
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);
}
}
}
PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction));
// After reading the functions, apply the token remapping table if it exists.
if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) {
dir.streams[header.snTokenRidMap].Read(reader, bits);
uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4];
bits.ReadUInt32(ridMap);
foreach (PdbFunction func in funcs) {
func.token = 0x06000000 | ridMap[func.token & 0xffffff];
}
}
//
Array.Sort(funcs, PdbFunction.byAddress);
//Array.Sort(funcs, PdbFunction.byToken);
return funcs;
}
}
}

View File

@@ -0,0 +1,82 @@
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.IO;
using System.Text;
namespace Microsoft.Cci.Pdb {
internal class PdbFileHeader {
internal PdbFileHeader(int pageSize) {
this.magic = new byte[32] {
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, // "Microsof"
0x74, 0x20, 0x43, 0x2F, 0x43, 0x2B, 0x2B, 0x20, // "t C/C++ "
0x4D, 0x53, 0x46, 0x20, 0x37, 0x2E, 0x30, 0x30, // "MSF 7.00"
0x0D, 0x0A, 0x1A, 0x44, 0x53, 0x00, 0x00, 0x00 // "^^^DS^^^"
};
this.pageSize = pageSize;
this.zero = 0;
}
internal PdbFileHeader(Stream reader, BitAccess bits) {
bits.MinCapacity(56);
reader.Seek(0, SeekOrigin.Begin);
bits.FillBuffer(reader, 56);
this.magic = new byte[32];
bits.ReadBytes(this.magic); // 0..31
bits.ReadInt32(out this.pageSize); // 32..35
bits.ReadInt32(out this.freePageMap); // 36..39
bits.ReadInt32(out this.pagesUsed); // 40..43
bits.ReadInt32(out this.directorySize); // 44..47
bits.ReadInt32(out this.zero); // 48..51
bits.ReadInt32(out this.directoryRoot); // 52..55
}
internal string Magic {
get { return StringFromBytesUTF8(magic); }
}
internal void Write(Stream writer, BitAccess bits) {
bits.MinCapacity(56);
bits.WriteBytes(magic); // 0..31
bits.WriteInt32(pageSize); // 32..35
bits.WriteInt32(freePageMap); // 36..39
bits.WriteInt32(pagesUsed); // 40..43
bits.WriteInt32(directorySize); // 44..47
bits.WriteInt32(zero); // 48..51
bits.WriteInt32(directoryRoot); // 52..55
writer.Seek(0, SeekOrigin.Begin);
bits.WriteBuffer(writer, 56);
}
//////////////////////////////////////////////////// Helper Functions.
//
internal string StringFromBytesUTF8(byte[] bytes) {
return StringFromBytesUTF8(bytes, 0, bytes.Length);
}
internal string StringFromBytesUTF8(byte[] bytes, int offset, int length) {
for (int i = 0; i < length; i++) {
if (bytes[offset + i] < ' ') {
length = i;
}
}
return Encoding.UTF8.GetString(bytes, offset, length);
}
////////////////////////////////////////////////////////////// Fields.
//
internal readonly byte[] magic;
internal readonly int pageSize;
internal int freePageMap;
internal int pagesUsed;
internal int directorySize;
internal readonly int zero;
internal int directoryRoot;
}
}

Some files were not shown because too many files have changed in this diff Show More