5 // Jb Evain (jbevain@novell.com)
7 // (C) 2009 Novell, Inc. (http://www.novell.com)
11 using System
.Collections
.Generic
;
16 using Microsoft
.Cci
.Pdb
;
20 using Mono
.CompilerServices
.SymbolWriter
;
27 Dictionary
<string, SourceFile
> files
= new Dictionary
<string, SourceFile
> ();
29 public Converter (MonoSymbolWriter mdb
)
34 public static void Convert (AssemblyDefinition assembly
, IEnumerable
<PdbFunction
> functions
, MonoSymbolWriter mdb
)
36 var converter
= new Converter (mdb
);
38 foreach (var function
in functions
)
39 converter
.ConvertFunction (function
);
41 mdb
.WriteSymbolFile (assembly
.MainModule
.Mvid
);
44 void ConvertFunction (PdbFunction function
)
46 var method
= new SourceMethod { Name = function.name, Token = (int) function.token }
;
48 var file
= GetSourceFile (mdb
, function
);
50 var builder
= mdb
.OpenMethod (file
.CompilationUnit
, 0, method
);
52 ConvertSequencePoints (function
, file
, builder
);
54 ConvertVariables (function
);
59 void ConvertSequencePoints (PdbFunction function
, SourceFile file
, SourceMethodBuilder builder
)
61 if (function
.lines
== null)
64 foreach (var line
in function
.lines
.SelectMany (lines
=> lines
.lines
))
65 builder
.MarkSequencePoint (
67 file
.CompilationUnit
.SourceFile
,
69 (int) line
.colBegin
, line
.lineBegin
== 0xfeefee);
72 void ConvertVariables (PdbFunction function
)
74 foreach (var scope
in function
.scopes
)
78 void ConvertScope (PdbScope scope
)
80 ConvertSlots (scope
.slots
);
82 foreach (var s
in scope
.scopes
)
86 void ConvertSlots (IEnumerable
<PdbSlot
> slots
)
88 foreach (var slot
in slots
)
89 mdb
.DefineLocalVariable ((int) slot
.slot
, slot
.name
);
92 SourceFile
GetSourceFile (MonoSymbolWriter mdb
, PdbFunction function
)
94 var name
= (from l
in function
.lines where l
.file
!= null select l
.file
.name
).First ();
97 if (files
.TryGetValue (name
, out file
))
100 var entry
= mdb
.DefineDocument (name
);
101 var unit
= mdb
.DefineCompilationUnit (entry
);
103 file
= new SourceFile (unit
, entry
);
104 files
.Add (name
, file
);
108 class SourceFile
: ISourceFile
{
109 CompileUnitEntry comp_unit
;
110 SourceFileEntry entry
;
112 public SourceFileEntry Entry
114 get { return entry; }
117 public CompileUnitEntry CompilationUnit
119 get { return comp_unit; }
122 public SourceFile (CompileUnitEntry comp_unit
, SourceFileEntry entry
)
124 this.comp_unit
= comp_unit
;
129 class SourceMethod
: IMethodDef
{
131 public string Name { get; set; }
133 public int Token { get; set; }
139 static void Main (string [] args
)
141 if (args
.Length
!= 1)
146 if (!File
.Exists (asm
))
149 var assembly
= AssemblyFactory
.GetAssembly (asm
);
151 var pdb
= assembly
.Name
.Name
+ ".pdb";
153 if (!File
.Exists (pdb
))
156 using (var stream
= File
.OpenRead (pdb
)) {
157 Convert (assembly
, stream
, new MonoSymbolWriter (asm
));
161 static void Convert (AssemblyDefinition assembly
, Stream pdb
, MonoSymbolWriter mdb
)
164 Converter
.Convert (assembly
, PdbFile
.LoadFunctions (pdb
, true), mdb
);
165 } catch (Exception e
) {
172 Console
.WriteLine ("Mono pdb to mdb debug symbol store converter");
173 Console
.WriteLine ("Usage: pdb2mdb assembly");
175 Environment
.Exit (1);
178 static void Error (Exception e
)
180 Console
.WriteLine ("Fatal error:");
181 Console
.WriteLine (e
);