Fix typo in OIDs corresponding to SHA256, SHA384, and SHA512 (#21707)
[mono-project.git] / mcs / tools / pdb2mdb / Driver.cs
blob7039503407518ca0c379d85e938c2c6036592531
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 public class Converter {
26 MonoSymbolWriter mdb;
27 Dictionary<string, SourceFile> files = new Dictionary<string, SourceFile> ();
29 public static void Convert (string filename)
31 using (var asm = AssemblyDefinition.ReadAssembly (filename)) {
33 var pdb = asm.Name.Name + ".pdb";
34 pdb = Path.Combine (Path.GetDirectoryName (filename), pdb);
36 if (!File.Exists (pdb))
37 throw new FileNotFoundException ("PDB file doesn't exist: " + pdb);
39 using (var stream = File.OpenRead (pdb)) {
40 if (IsPortablePdb (stream))
41 throw new PortablePdbNotSupportedException ();
43 var funcs = PdbFile.LoadFunctions (stream, true);
44 Converter.Convert (asm, funcs, new MonoSymbolWriter (filename));
49 static bool IsPortablePdb (FileStream stream)
51 const uint ppdb_signature = 0x424a5342;
53 var position = stream.Position;
54 try {
55 var reader = new BinaryReader (stream);
56 return reader.ReadUInt32 () == ppdb_signature;
57 } finally {
58 stream.Position = position;
62 internal Converter (MonoSymbolWriter mdb)
64 this.mdb = mdb;
67 internal static void Convert (AssemblyDefinition assembly, IEnumerable<PdbFunction> functions, MonoSymbolWriter mdb)
69 var converter = new Converter (mdb);
71 foreach (var function in functions)
72 converter.ConvertFunction (function);
74 mdb.WriteSymbolFile (assembly.MainModule.Mvid);
77 void ConvertFunction (PdbFunction function)
79 if (function.lines == null)
80 return;
82 var method = new SourceMethod { Name = function.name, Token = (int) function.token };
84 var file = GetSourceFile (mdb, function);
86 var builder = mdb.OpenMethod (file.CompilationUnit, 0, method);
88 ConvertSequencePoints (function, file, builder);
90 ConvertVariables (function);
92 mdb.CloseMethod ();
95 void ConvertSequencePoints (PdbFunction function, SourceFile file, SourceMethodBuilder builder)
97 int last_line = 0;
98 foreach (var line in function.lines.SelectMany (lines => lines.lines)) {
99 // 0xfeefee is an MS convention, we can't pass it into mdb files, so we use the last non-hidden line
100 bool is_hidden = line.lineBegin == 0xfeefee;
101 builder.MarkSequencePoint (
102 (int) line.offset,
103 file.CompilationUnit.SourceFile,
104 is_hidden ? last_line : (int) line.lineBegin,
105 (int) line.colBegin, is_hidden ? -1 : (int)line.lineEnd, is_hidden ? -1 : (int)line.colEnd,
106 is_hidden);
107 if (!is_hidden)
108 last_line = (int) line.lineBegin;
112 void ConvertVariables (PdbFunction function)
114 foreach (var scope in function.scopes)
115 ConvertScope (scope);
118 void ConvertScope (PdbScope scope)
120 ConvertSlots (scope, scope.slots);
122 foreach (var s in scope.scopes)
123 ConvertScope (s);
126 void ConvertSlots (PdbScope scope, IEnumerable<PdbSlot> slots)
128 int scope_idx = mdb.OpenScope ((int)scope.address);
129 foreach (var slot in slots) {
130 mdb.DefineLocalVariable ((int) slot.slot, slot.name);
131 mdb.DefineScopeVariable (scope_idx, (int)slot.slot);
133 mdb.CloseScope ((int)(scope.address + scope.length));
136 SourceFile GetSourceFile (MonoSymbolWriter mdb, PdbFunction function)
138 var name = (from l in function.lines where l.file != null select l.file.name).First ();
140 SourceFile file;
141 if (files.TryGetValue (name, out file))
142 return file;
144 var entry = mdb.DefineDocument (name);
145 var unit = mdb.DefineCompilationUnit (entry);
147 file = new SourceFile (unit, entry);
148 files.Add (name, file);
149 return file;
152 class SourceFile : ISourceFile {
153 CompileUnitEntry comp_unit;
154 SourceFileEntry entry;
156 public SourceFileEntry Entry
158 get { return entry; }
161 public CompileUnitEntry CompilationUnit
163 get { return comp_unit; }
166 public SourceFile (CompileUnitEntry comp_unit, SourceFileEntry entry)
168 this.comp_unit = comp_unit;
169 this.entry = entry;
173 class SourceMethod : IMethodDef {
175 public string Name { get; set; }
177 public int Token { get; set; }
181 public class PortablePdbNotSupportedException : Exception {
184 class Driver {
186 static void Main (string [] args)
188 if (args.Length != 1)
189 Usage ();
191 var asm = args [0];
193 if (!File.Exists (asm))
194 Usage ();
196 try {
197 Converter.Convert (asm);
198 } catch (FileNotFoundException ex) {
199 Usage ();
200 } catch (PortablePdbNotSupportedException) {
201 Console.WriteLine ("Error: A portable PDB can't be converted to mdb.");
202 Environment.Exit (2);
204 catch (Exception ex) {
205 Error (ex);
209 static void Usage ()
211 Console.WriteLine ("Mono pdb to mdb debug symbol store converter");
212 Console.WriteLine ("Usage: pdb2mdb assembly");
214 Environment.Exit (1);
217 static void Error (Exception e)
219 Console.WriteLine ("Fatal error:");
220 Console.WriteLine (e);
222 Environment.Exit (1);