2009-09-24 Zoltan Varga <vargaz@gmail.com>
[mcs.git] / tools / pdb2mdb / Driver.cs
blob0a37c9c4478be489d033a2d4634f17debb1ad1a9
1 //
2 // Driver.cs
3 //
4 // Author:
5 // Jb Evain (jbevain@novell.com)
6 //
7 // (C) 2009 Novell, Inc. (http://www.novell.com)
8 //
10 using System;
11 using System.Collections.Generic;
12 using System.IO;
13 using System.Linq;
15 using Microsoft.Cci;
16 using Microsoft.Cci.Pdb;
18 using Mono.Cecil;
20 using Mono.CompilerServices.SymbolWriter;
22 namespace Pdb2Mdb {
24 class Converter {
26 MonoSymbolWriter mdb;
27 Dictionary<string, SourceFile> files = new Dictionary<string, SourceFile> ();
29 public Converter (MonoSymbolWriter mdb)
31 this.mdb = 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);
56 mdb.CloseMethod ();
59 void ConvertSequencePoints (PdbFunction function, SourceFile file, SourceMethodBuilder builder)
61 if (function.lines == null)
62 return;
64 foreach (var line in function.lines.SelectMany (lines => lines.lines))
65 builder.MarkSequencePoint (
66 (int) line.offset,
67 file.CompilationUnit.SourceFile,
68 (int) line.lineBegin,
69 (int) line.colBegin, line.lineBegin == 0xfeefee);
72 void ConvertVariables (PdbFunction function)
74 foreach (var scope in function.scopes)
75 ConvertScope (scope);
78 void ConvertScope (PdbScope scope)
80 ConvertSlots (scope.slots);
82 foreach (var s in scope.scopes)
83 ConvertScope (s);
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 ();
96 SourceFile file;
97 if (files.TryGetValue (name, out file))
98 return file;
100 var entry = mdb.DefineDocument (name);
101 var unit = mdb.DefineCompilationUnit (entry);
103 file = new SourceFile (unit, entry);
104 files.Add (name, file);
105 return 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;
125 this.entry = entry;
129 class SourceMethod : IMethodDef {
131 public string Name { get; set; }
133 public int Token { get; set; }
137 class Driver {
139 static void Main (string [] args)
141 if (args.Length != 1)
142 Usage ();
144 var asm = args [0];
146 if (!File.Exists (asm))
147 Usage ();
149 var assembly = AssemblyFactory.GetAssembly (asm);
151 var pdb = assembly.Name.Name + ".pdb";
153 if (!File.Exists (pdb))
154 Usage ();
156 using (var stream = File.OpenRead (pdb)) {
157 Convert (assembly, stream, new MonoSymbolWriter (asm));
161 static void Convert (AssemblyDefinition assembly, Stream pdb, MonoSymbolWriter mdb)
163 try {
164 Converter.Convert (assembly, PdbFile.LoadFunctions (pdb, true), mdb);
165 } catch (Exception e) {
166 Error (e);
170 static void Usage ()
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);