~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/Mono.Cecil/Mono.CompilerServices.SymbolWriterOld/MonoSymbolFile.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-02-02 11:39:59 UTC
  • mfrom: (1.4.4 upstream)
  • mto: (1.5.1 sid)
  • mto: This revision was merged to the branch mainline in revision 47.
  • Revision ID: james.westby@ubuntu.com-20100202113959-n3u848nfj35yyd03
* New upstream release
* debian/control:
  + Standards version 3.8.4 (no changes needed)
* debian/patches/remove_support_for_non_debian_functionality.patch,
  debian/patches/remove_support_for_soft_debugger.patch,
  debian/patches/remove_support_for_moonlight.patch,
  debian/rules:
  + Split patch into two pieces, to make it easier to enable either
    SDB or Moonlight support with a rebuild
* debian/monodevelop-moonlight.install,
  debian/monodevelop-debugger-sdb.install,
  debian/control:
  + Create packaging data for the Soft Debugger addin and Moonlight addin -
    and comment them out of debian/control as we can't provide them on
    Debian for now

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// Mono.CSharp.Debugger/MonoSymbolFile.cs
3
 
//
4
 
// Author:
5
 
//   Martin Baulig (martin@ximian.com)
6
 
//
7
 
// (C) 2003 Ximian, Inc.  http://www.ximian.com
8
 
//
9
 
 
10
 
//
11
 
// Permission is hereby granted, free of charge, to any person obtaining
12
 
// a copy of this software and associated documentation files (the
13
 
// "Software"), to deal in the Software without restriction, including
14
 
// without limitation the rights to use, copy, modify, merge, publish,
15
 
// distribute, sublicense, and/or sell copies of the Software, and to
16
 
// permit persons to whom the Software is furnished to do so, subject to
17
 
// the following conditions:
18
 
// 
19
 
// The above copyright notice and this permission notice shall be
20
 
// included in all copies or substantial portions of the Software.
21
 
// 
22
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
 
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
 
//
30
 
 
31
 
using System;
32
 
using System.Reflection;
33
 
using SRE = System.Reflection.Emit;
34
 
using System.Collections;
35
 
using System.Text;
36
 
using System.Threading;
37
 
using System.IO;
38
 
        
39
 
namespace Mono.CompilerServices.SymbolWriterOld
40
 
{
41
 
        public class MonoSymbolFileException : Exception
42
 
        {
43
 
                public MonoSymbolFileException ()
44
 
                        : base ()
45
 
                { }
46
 
 
47
 
                public MonoSymbolFileException (string message, params object[] args)
48
 
                        : base (String.Format (message, args))
49
 
                { }
50
 
        }
51
 
 
52
 
        internal class MyBinaryWriter : BinaryWriter
53
 
        {
54
 
                public MyBinaryWriter (Stream stream)
55
 
                        : base (stream)
56
 
                { }
57
 
 
58
 
                public void WriteLeb128 (int value)
59
 
                {
60
 
                        base.Write7BitEncodedInt (value);
61
 
                }
62
 
        }
63
 
 
64
 
        internal class MyBinaryReader : BinaryReader
65
 
        {
66
 
                public MyBinaryReader (Stream stream)
67
 
                        : base (stream)
68
 
                { }
69
 
 
70
 
                public int ReadLeb128 ()
71
 
                {
72
 
                        return base.Read7BitEncodedInt ();
73
 
                }
74
 
        }
75
 
 
76
 
#if !CECIL
77
 
        internal class MonoDebuggerSupport
78
 
        {
79
 
                static GetMethodTokenFunc get_method_token;
80
 
                static GetGuidFunc get_guid;
81
 
                static GetLocalIndexFunc get_local_index;
82
 
 
83
 
                delegate int GetMethodTokenFunc (MethodBase method);
84
 
                delegate Guid GetGuidFunc (Module module);
85
 
                delegate int GetLocalIndexFunc (SRE.LocalBuilder local);
86
 
 
87
 
                static Delegate create_delegate (Type type, Type delegate_type, string name)
88
 
                {
89
 
                        MethodInfo mi = type.GetMethod (name, BindingFlags.Static |
90
 
                                                        BindingFlags.NonPublic);
91
 
                        if (mi == null)
92
 
                                throw new Exception ("Can't find " + name);
93
 
 
94
 
                        return Delegate.CreateDelegate (delegate_type, mi);
95
 
                }
96
 
 
97
 
                static MonoDebuggerSupport ()
98
 
                {
99
 
                        get_method_token = (GetMethodTokenFunc) create_delegate (
100
 
                                typeof (Assembly), typeof (GetMethodTokenFunc),
101
 
                                "MonoDebugger_GetMethodToken");
102
 
 
103
 
                        get_guid = (GetGuidFunc) create_delegate (
104
 
                                typeof (Module), typeof (GetGuidFunc), "Mono_GetGuid");
105
 
 
106
 
                        get_local_index = (GetLocalIndexFunc) create_delegate (
107
 
                                typeof (SRE.LocalBuilder), typeof (GetLocalIndexFunc),
108
 
                                "Mono_GetLocalIndex");
109
 
                }
110
 
 
111
 
                public static int GetMethodToken (MethodBase method)
112
 
                {
113
 
                        return get_method_token (method);
114
 
                }
115
 
 
116
 
                public static Guid GetGuid (Module module)
117
 
                {
118
 
                        return get_guid (module);
119
 
                }
120
 
 
121
 
                public static int GetLocalIndex (SRE.LocalBuilder local)
122
 
                {
123
 
                        return get_local_index (local);
124
 
                }
125
 
        }
126
 
#endif
127
 
 
128
 
        public class MonoSymbolFile : IDisposable
129
 
        {
130
 
                ArrayList methods = new ArrayList ();
131
 
                ArrayList sources = new ArrayList ();
132
 
                Hashtable method_source_hash = new Hashtable ();
133
 
                Hashtable type_hash = new Hashtable ();
134
 
 
135
 
                OffsetTable ot;
136
 
                int last_type_index;
137
 
                int last_method_index;
138
 
                int last_source_index;
139
 
                int last_namespace_index;
140
 
 
141
 
                public int NumLineNumbers;
142
 
 
143
 
                public MonoSymbolFile ()
144
 
                { }
145
 
 
146
 
                internal int AddSource (SourceFileEntry source)
147
 
                {
148
 
                        sources.Add (source);
149
 
                        return ++last_source_index;
150
 
                }
151
 
 
152
 
                internal int DefineType (Type type)
153
 
                {
154
 
                        if (type_hash.Contains (type))
155
 
                                return (int) type_hash [type];
156
 
 
157
 
                        int index = ++last_type_index;
158
 
                        type_hash.Add (type, index);
159
 
                        return index;
160
 
                }
161
 
 
162
 
                internal void AddMethod (MethodEntry entry)
163
 
                {
164
 
                        methods.Add (entry);
165
 
                }
166
 
 
167
 
                internal int GetNextTypeIndex ()
168
 
                {
169
 
                        return ++last_type_index;
170
 
                }
171
 
 
172
 
                internal int GetNextMethodIndex ()
173
 
                {
174
 
                        return ++last_method_index;
175
 
                }
176
 
 
177
 
                internal int GetNextNamespaceIndex ()
178
 
                {
179
 
                        return ++last_namespace_index;
180
 
                }
181
 
                
182
 
                internal string ReadString (int offset)
183
 
                {
184
 
                        int old_pos = (int) reader.BaseStream.Position;
185
 
                        reader.BaseStream.Position = offset;
186
 
 
187
 
                        string text = reader.ReadString ();
188
 
 
189
 
                        reader.BaseStream.Position = old_pos;
190
 
                        return text;
191
 
                }
192
 
 
193
 
                void Write (MyBinaryWriter bw, Guid guid)
194
 
                {
195
 
                        // Magic number and file version.
196
 
                        bw.Write (OffsetTable.Magic);
197
 
                        bw.Write (OffsetTable.Version);
198
 
 
199
 
                        bw.Write (guid.ToByteArray ());
200
 
 
201
 
                        //
202
 
                        // Offsets of file sections; we must write this after we're done
203
 
                        // writing the whole file, so we just reserve the space for it here.
204
 
                        //
205
 
                        long offset_table_offset = bw.BaseStream.Position;
206
 
                        ot.Write (bw);
207
 
 
208
 
                        //
209
 
                        // Sort the methods according to their tokens and update their index.
210
 
                        //
211
 
                        methods.Sort ();
212
 
                        for (int i = 0; i < methods.Count; i++)
213
 
                                ((MethodEntry) methods [i]).Index = i + 1;
214
 
 
215
 
                        //
216
 
                        // Write data sections.
217
 
                        //
218
 
                        ot.DataSectionOffset = (int) bw.BaseStream.Position;
219
 
                        foreach (SourceFileEntry source in sources)
220
 
                                source.WriteData (bw);
221
 
                        ot.DataSectionSize = (int) bw.BaseStream.Position - ot.DataSectionOffset;
222
 
 
223
 
                        //
224
 
                        // Write the method index table.
225
 
                        //
226
 
                        ot.MethodTableOffset = (int) bw.BaseStream.Position;
227
 
                        for (int i = 0; i < methods.Count; i++) {
228
 
                                MethodEntry entry = (MethodEntry) methods [i];
229
 
                                entry.WriteIndex (bw);
230
 
                        }
231
 
                        ot.MethodTableSize = (int) bw.BaseStream.Position - ot.MethodTableOffset;
232
 
 
233
 
                        //
234
 
                        // Write source table.
235
 
                        //
236
 
                        ot.SourceTableOffset = (int) bw.BaseStream.Position;
237
 
                        for (int i = 0; i < sources.Count; i++) {
238
 
                                SourceFileEntry source = (SourceFileEntry) sources [i];
239
 
                                source.Write (bw);
240
 
                        }
241
 
                        ot.SourceTableSize = (int) bw.BaseStream.Position - ot.SourceTableOffset;
242
 
 
243
 
                        //
244
 
                        // Fixup offset table.
245
 
                        //
246
 
                        ot.TypeCount = last_type_index;
247
 
                        ot.MethodCount = methods.Count;
248
 
                        ot.SourceCount = sources.Count;
249
 
 
250
 
                        //
251
 
                        // Write offset table.
252
 
                        //
253
 
                        ot.TotalFileSize = (int) bw.BaseStream.Position;
254
 
                        bw.Seek ((int) offset_table_offset, SeekOrigin.Begin);
255
 
                        ot.Write (bw);
256
 
                        bw.Seek (0, SeekOrigin.End);
257
 
                }
258
 
 
259
 
                public void CreateSymbolFile (Guid guid, FileStream fs)
260
 
                {
261
 
                        if (reader != null)
262
 
                                throw new InvalidOperationException ();
263
 
                        
264
 
                        Write (new MyBinaryWriter (fs), guid);
265
 
                }
266
 
 
267
 
                MyBinaryReader reader;
268
 
                Hashtable method_hash;
269
 
                Hashtable source_file_hash;
270
 
 
271
 
                Hashtable method_token_hash;
272
 
                Hashtable source_name_hash;
273
 
 
274
 
                Guid guid;
275
 
 
276
 
                MonoSymbolFile (string filename)
277
 
                {
278
 
                        FileStream stream = new FileStream (filename, FileMode.Open, FileAccess.Read);
279
 
                        reader = new MyBinaryReader (stream);
280
 
 
281
 
                        try {
282
 
                                long magic = reader.ReadInt64 ();
283
 
                                long version = reader.ReadInt32 ();
284
 
                                if (magic != OffsetTable.Magic)
285
 
                                        throw new MonoSymbolFileException (
286
 
                                                "Symbol file `{0}' is not a valid " +
287
 
                                                "Mono symbol file", filename);
288
 
                                if (version != OffsetTable.Version)
289
 
                                        throw new MonoSymbolFileException (
290
 
                                                "Symbol file `{0}' has version {1}, " +
291
 
                                                "but expected {2}", filename, version,
292
 
                                                OffsetTable.Version);
293
 
 
294
 
                                guid = new Guid (reader.ReadBytes (16));
295
 
 
296
 
                                ot = new OffsetTable (reader);
297
 
                        } catch {
298
 
                                throw new MonoSymbolFileException (
299
 
                                        "Cannot read symbol file `{0}'", filename);
300
 
                        }
301
 
 
302
 
                        method_hash = new Hashtable ();
303
 
                        source_file_hash = new Hashtable ();
304
 
                }
305
 
 
306
 
                void CheckGuidMatch (Guid other, string filename, string assembly)
307
 
                {
308
 
                        if (other == guid)
309
 
                                return;
310
 
 
311
 
                        throw new MonoSymbolFileException (
312
 
                                "Symbol file `{0}' does not match assembly `{1}'",
313
 
                                filename, assembly);
314
 
                }
315
 
 
316
 
#if CECIL
317
 
                protected MonoSymbolFile (string filename, Mono.Cecil.AssemblyDefinition assembly) : this (filename)
318
 
                {
319
 
                        Guid mvid = assembly.MainModule.Mvid;
320
 
 
321
 
                        CheckGuidMatch (mvid, filename, assembly.MainModule.Image.FileInformation.FullName);
322
 
                }
323
 
 
324
 
                public static MonoSymbolFile ReadSymbolFile (Mono.Cecil.AssemblyDefinition assembly, string filename)
325
 
                {
326
 
                        string name = filename + ".mdb";
327
 
 
328
 
                        return new MonoSymbolFile (name, assembly);
329
 
                }
330
 
#else
331
 
                protected MonoSymbolFile (string filename, Assembly assembly) : this (filename)
332
 
                {
333
 
                        // Check that the MDB file matches the assembly, if we have been
334
 
                        // passed an assembly.
335
 
                        if (assembly == null)
336
 
                                return;
337
 
                        
338
 
                        Module[] modules = assembly.GetModules ();
339
 
                        Guid assembly_guid = MonoDebuggerSupport.GetGuid (modules [0]);
340
 
 
341
 
                        CheckGuidMatch (assembly_guid, filename, assembly.Location);
342
 
                }
343
 
 
344
 
                public static MonoSymbolFile ReadSymbolFile (Assembly assembly)
345
 
                {
346
 
                        string filename = assembly.Location;
347
 
                        string name = filename + ".mdb";
348
 
 
349
 
                        return new MonoSymbolFile (name, assembly);
350
 
                }
351
 
#endif
352
 
 
353
 
                public static MonoSymbolFile ReadSymbolFile (string mdbFilename)
354
 
                {
355
 
                        return new MonoSymbolFile (mdbFilename, null);
356
 
                }
357
 
 
358
 
                public int SourceCount {
359
 
                        get { return ot.SourceCount; }
360
 
                }
361
 
 
362
 
                public int MethodCount {
363
 
                        get { return ot.MethodCount; }
364
 
                }
365
 
 
366
 
                public int TypeCount {
367
 
                        get { return ot.TypeCount; }
368
 
                }
369
 
 
370
 
                public int NamespaceCount {
371
 
                        get { return last_namespace_index; }
372
 
                }
373
 
 
374
 
                public Guid Guid {
375
 
                        get { return guid; }
376
 
                }
377
 
 
378
 
                internal int LineNumberCount = 0;
379
 
                internal int LocalCount = 0;
380
 
                internal int StringSize = 0;
381
 
 
382
 
                public SourceFileEntry GetSourceFile (int index)
383
 
                {
384
 
                        if ((index < 1) || (index > ot.SourceCount))
385
 
                                throw new ArgumentException ();
386
 
                        if (reader == null)
387
 
                                throw new InvalidOperationException ();
388
 
 
389
 
                        SourceFileEntry source = (SourceFileEntry) source_file_hash [index];
390
 
                        if (source != null)
391
 
                                return source;
392
 
 
393
 
                        reader.BaseStream.Position = ot.SourceTableOffset +
394
 
                                SourceFileEntry.Size * (index - 1);
395
 
                        source = new SourceFileEntry (this, reader);
396
 
                        source_file_hash.Add (index, source);
397
 
                        return source;
398
 
                }
399
 
 
400
 
                public SourceFileEntry[] Sources {
401
 
                        get {
402
 
                                if (reader == null)
403
 
                                        throw new InvalidOperationException ();
404
 
 
405
 
                                SourceFileEntry[] retval = new SourceFileEntry [SourceCount];
406
 
                                for (int i = 0; i < SourceCount; i++)
407
 
                                        retval [i] = GetSourceFile (i + 1);
408
 
                                return retval;
409
 
                        }
410
 
                }
411
 
 
412
 
                public MethodIndexEntry GetMethodIndexEntry (int index)
413
 
                {
414
 
                        int old_pos = (int) reader.BaseStream.Position;
415
 
                        reader.BaseStream.Position = ot.MethodTableOffset +
416
 
                                MethodIndexEntry.Size * (index - 1);
417
 
                        MethodIndexEntry ie = new MethodIndexEntry (reader);
418
 
                        reader.BaseStream.Position = old_pos;
419
 
                        return ie;
420
 
                }
421
 
 
422
 
                public MethodEntry GetMethodByToken (int token)
423
 
                {
424
 
                        if (reader == null)
425
 
                                throw new InvalidOperationException ();
426
 
 
427
 
                        if (method_token_hash == null) {
428
 
                                method_token_hash = new Hashtable ();
429
 
 
430
 
                                for (int i = 0; i < MethodCount; i++) {
431
 
                                        MethodIndexEntry ie = GetMethodIndexEntry (i + 1);
432
 
 
433
 
                                        method_token_hash.Add (ie.Token, i + 1);
434
 
                                }
435
 
                        }
436
 
 
437
 
                        object value = method_token_hash [token];
438
 
                        if (value == null)
439
 
                                return null;
440
 
 
441
 
                        return GetMethod ((int) value);
442
 
                }
443
 
 
444
 
#if !CECIL
445
 
                public MethodEntry GetMethod (MethodBase method)
446
 
                {
447
 
                        if (reader == null)
448
 
                                throw new InvalidOperationException ();
449
 
                        int token = MonoDebuggerSupport.GetMethodToken (method);
450
 
                        return GetMethodByToken (token);
451
 
                }
452
 
#endif
453
 
                
454
 
                public MethodEntry GetMethod (int index)
455
 
                {
456
 
                        if ((index < 1) || (index > ot.MethodCount))
457
 
                                throw new ArgumentException ();
458
 
                        if (reader == null)
459
 
                                throw new InvalidOperationException ();
460
 
 
461
 
                        MethodEntry entry = (MethodEntry) method_hash [index];
462
 
                        if (entry != null)
463
 
                                return entry;
464
 
 
465
 
                        MethodIndexEntry ie = GetMethodIndexEntry (index);
466
 
                        reader.BaseStream.Position = ie.FileOffset;
467
 
 
468
 
                        entry = new MethodEntry (this, reader, index);
469
 
                        method_hash.Add (index, entry);
470
 
                        return entry;
471
 
                }
472
 
 
473
 
                public MethodEntry[] Methods {
474
 
                        get {
475
 
                                if (reader == null)
476
 
                                        throw new InvalidOperationException ();
477
 
 
478
 
                                MethodEntry[] retval = new MethodEntry [MethodCount];
479
 
                                for (int i = 0; i < MethodCount; i++)
480
 
                                        retval [i] = GetMethod (i + 1);
481
 
                                return retval;
482
 
                        }
483
 
                }
484
 
 
485
 
                public MethodSourceEntry GetMethodSource (int index)
486
 
                {
487
 
                        if ((index < 1) || (index > ot.MethodCount))
488
 
                                throw new ArgumentException ();
489
 
                        if (reader == null)
490
 
                                throw new InvalidOperationException ();
491
 
 
492
 
                        object entry = method_source_hash [index];
493
 
                        if (entry != null)
494
 
                                return (MethodSourceEntry) entry;
495
 
 
496
 
                        MethodEntry method = GetMethod (index);
497
 
                        foreach (MethodSourceEntry source in method.SourceFile.Methods) {
498
 
                                if (source.Index == index) {
499
 
                                        method_source_hash.Add (index, source);
500
 
                                        return source;
501
 
                                }
502
 
                        }
503
 
 
504
 
                        throw new MonoSymbolFileException ("Internal error.");
505
 
                }
506
 
 
507
 
                public int FindSource (string file_name)
508
 
                {
509
 
                        if (reader == null)
510
 
                                throw new InvalidOperationException ();
511
 
 
512
 
                        if (source_name_hash == null) {
513
 
                                source_name_hash = new Hashtable ();
514
 
 
515
 
                                for (int i = 0; i < ot.SourceCount; i++) {
516
 
                                        SourceFileEntry source = GetSourceFile (i + 1);
517
 
 
518
 
                                        source_name_hash.Add (source.FileName, i);
519
 
                                }
520
 
                        }
521
 
 
522
 
                        object value = source_name_hash [file_name];
523
 
                        if (value == null)
524
 
                                return -1;
525
 
                        return (int) value;
526
 
                }
527
 
 
528
 
                internal MyBinaryReader BinaryReader {
529
 
                        get {
530
 
                                if (reader == null)
531
 
                                        throw new InvalidOperationException ();
532
 
 
533
 
                                return reader;
534
 
                        }
535
 
                }
536
 
 
537
 
                public void Dispose ()
538
 
                {
539
 
                        Dispose (true);
540
 
                }
541
 
 
542
 
                protected virtual void Dispose (bool disposing)
543
 
                {
544
 
                        if (disposing) {
545
 
                                if (reader != null) {
546
 
                                        reader.Close ();
547
 
                                        reader = null;
548
 
                                }
549
 
                        }
550
 
                }
551
 
        }
552
 
}