Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2017-02-14 00:41:38 +0300
committerMarek Safar <marek.safar@gmail.com>2017-02-14 00:41:38 +0300
commitaae16928bc94a24bc901ea4780712e79606ddd11 (patch)
treee0cc654eb97a9bd299c60aeea90deeb6674a80d0
parent96c5c284af2832be96644150868685fc73c85947 (diff)
parent2f13ff507824f64c90c78210a91d3a505cc9e6a5 (diff)
Merge remote-tracking branch 'upstream/master'
-rw-r--r--Mono.Cecil.Cil/PortablePdb.cs10
-rw-r--r--Mono.Cecil.Cil/Symbols.cs161
-rw-r--r--Mono.Cecil.Metadata/Buffers.cs88
-rw-r--r--Mono.Cecil/AssemblyNameReference.cs3
-rw-r--r--Mono.Cecil/AssemblyReader.cs5
-rw-r--r--Mono.Cecil/AssemblyWriter.cs3
-rw-r--r--Mono.Cecil/BaseAssemblyResolver.cs6
-rw-r--r--Mono.Cecil/CustomAttribute.cs11
-rw-r--r--Mono.Cecil/DefaultAssemblyResolver.cs3
-rw-r--r--Mono.Cecil/EventReference.cs4
-rw-r--r--Mono.Cecil/FieldReference.cs6
-rw-r--r--Mono.Cecil/GenericParameter.cs3
-rw-r--r--Mono.Cecil/Import.cs2
-rw-r--r--Mono.Cecil/MetadataResolver.cs9
-rw-r--r--Mono.Cecil/MethodReference.cs6
-rw-r--r--Mono.Cecil/MethodSpecification.cs3
-rw-r--r--Mono.Cecil/Modifiers.cs19
-rw-r--r--Mono.Cecil/ModuleDefinition.cs83
-rw-r--r--Mono.Cecil/PropertyReference.cs3
-rw-r--r--Mono.Cecil/TypeDefinition.cs3
-rw-r--r--Mono.Cecil/TypeSpecification.cs9
-rw-r--r--Mono/Empty.cs8
-rw-r--r--Test/Mono.Cecil.Tests.csproj8
-rw-r--r--Test/Mono.Cecil.Tests/SymbolTests.cs53
-rw-r--r--Test/Resources/assemblies/libmdb.dllbin0 -> 3072 bytes
-rw-r--r--Test/Resources/assemblies/libmdb.dll.mdbbin0 -> 238 bytes
-rw-r--r--Test/Resources/assemblies/libpdb.dllbin0 -> 3584 bytes
-rw-r--r--Test/Resources/assemblies/libpdb.pdbbin0 -> 11776 bytes
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs (renamed from symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs)4
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs (renamed from symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs)4
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs29
31 files changed, 397 insertions, 149 deletions
diff --git a/Mono.Cecil.Cil/PortablePdb.cs b/Mono.Cecil.Cil/PortablePdb.cs
index 4df8813..f7cb061 100644
--- a/Mono.Cecil.Cil/PortablePdb.cs
+++ b/Mono.Cecil.Cil/PortablePdb.cs
@@ -248,7 +248,13 @@ namespace Mono.Cecil.Cil {
if (IsEmbedded)
return;
+ WritePdbFile ();
+ }
+
+ void WritePdbFile ()
+ {
WritePdbHeap ();
+
WriteTableHeap ();
writer.BuildMetadataTextMap ();
@@ -291,6 +297,10 @@ namespace Mono.Cecil.Cil {
void WriteTableHeap ()
{
+ if (module_metadata.string_heap != pdb_metadata.string_heap) {
+ pdb_metadata.table_heap.string_offsets = pdb_metadata.string_heap.WriteStrings ();
+ }
+
pdb_metadata.table_heap.WriteTableHeap ();
}
}
diff --git a/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.Cil/Symbols.cs
index 485152f..62ff6c9 100644
--- a/Mono.Cecil.Cil/Symbols.cs
+++ b/Mono.Cecil.Cil/Symbols.cs
@@ -630,16 +630,69 @@ namespace Mono.Cecil.Cil {
}
#if !PCL
- static class SymbolProvider {
+ public class DefaultSymbolReaderProvider : ISymbolReaderProvider {
+
+ readonly bool throw_if_no_symbol;
+
+ public DefaultSymbolReaderProvider ()
+ : this (throwIfNoSymbol: true)
+ {
+ }
- static readonly string symbol_kind = Type.GetType ("Mono.Runtime") != null ? "Mdb" : "Pdb";
+ public DefaultSymbolReaderProvider (bool throwIfNoSymbol)
+ {
+ throw_if_no_symbol = throwIfNoSymbol;
+ }
- static SR.AssemblyName GetPlatformSymbolAssemblyName ()
+ public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
{
+ if (module.Image.HasDebugTables ())
+ return null;
+
+ var pdb_file_name = Mixin.GetPdbFileName (fileName);
+
+ if (File.Exists (pdb_file_name))
+ return Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName))
+ ? new PortablePdbReaderProvider ().GetSymbolReader (module, fileName)
+ : SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, fileName);
+
+ var mdb_file_name = Mixin.GetMdbFileName (fileName);
+ if (File.Exists (mdb_file_name))
+ return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, fileName);
+
+ if (throw_if_no_symbol)
+ throw new FileNotFoundException (string.Format ("No symbol found for file: {0}", fileName));
+
+ return null;
+ }
+
+ public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
+ {
+ throw new NotSupportedException ();
+ }
+ }
+#endif
+
+#if !PCL
+ enum SymbolKind {
+ NativePdb,
+ PortablePdb,
+ Mdb,
+ }
+
+ static class SymbolProvider {
+
+ static SR.AssemblyName GetSymbolAssemblyName (SymbolKind kind)
+ {
+ if (kind == SymbolKind.PortablePdb)
+ throw new ArgumentException ();
+
+ var suffix = GetSymbolNamespace (kind);
+
var cecil_name = typeof (SymbolProvider).GetAssembly ().GetName ();
var name = new SR.AssemblyName {
- Name = "Mono.Cecil." + symbol_kind,
+ Name = cecil_name.Name + "." + suffix,
Version = cecil_name.Version,
};
@@ -648,13 +701,13 @@ namespace Mono.Cecil.Cil {
return name;
}
- static Type GetPlatformType (string fullname)
+ static Type GetSymbolType (SymbolKind kind, string fullname)
{
var type = Type.GetType (fullname);
if (type != null)
return type;
- var assembly_name = GetPlatformSymbolAssemblyName ();
+ var assembly_name = GetSymbolAssemblyName (kind);
type = Type.GetType (fullname + ", " + assembly_name.FullName);
if (type != null)
@@ -671,39 +724,60 @@ namespace Mono.Cecil.Cil {
return null;
}
- static ISymbolReaderProvider reader_provider;
-
- public static ISymbolReaderProvider GetPlatformReaderProvider ()
+ public static ISymbolReaderProvider GetReaderProvider (SymbolKind kind)
{
- if (reader_provider != null)
- return reader_provider;
+ if (kind == SymbolKind.PortablePdb)
+ return new PortablePdbReaderProvider ();
- var type = GetPlatformType (GetProviderTypeName ("ReaderProvider"));
+ var type = GetSymbolType (kind, GetSymbolTypeName (kind, "ReaderProvider"));
if (type == null)
return null;
- return reader_provider = (ISymbolReaderProvider) Activator.CreateInstance (type);
+ return (ISymbolReaderProvider) Activator.CreateInstance (type);
}
- static string GetProviderTypeName (string name)
+ static string GetSymbolTypeName (SymbolKind kind, string name)
{
- return "Mono.Cecil." + symbol_kind + "." + symbol_kind + name;
+ var ns = GetSymbolNamespace (kind);
+ return typeof (SymbolProvider).Assembly.GetName ().Name + "." + ns + "." + kind + name;
}
-#if !READ_ONLY
+ static string GetSymbolNamespace (SymbolKind kind)
+ {
+ if (kind == SymbolKind.PortablePdb)
+ return "Cil";
+ if (kind == SymbolKind.NativePdb)
+ return "Pdb";
+ if (kind == SymbolKind.Mdb)
+ return "Mdb";
+
+ throw new ArgumentException ();
+ }
- static ISymbolWriterProvider writer_provider;
+#if !READ_ONLY
- public static ISymbolWriterProvider GetPlatformWriterProvider ()
+ public static ISymbolWriterProvider GetWriterProvider (SymbolKind kind)
{
- if (writer_provider != null)
- return writer_provider;
+ if (kind == SymbolKind.PortablePdb)
+ return new PortablePdbWriterProvider ();
- var type = GetPlatformType (GetProviderTypeName ("WriterProvider"));
+ var type = GetSymbolType (kind, GetSymbolTypeName (kind, "WriterProvider"));
if (type == null)
return null;
- return writer_provider = (ISymbolWriterProvider) Activator.CreateInstance (type);
+ return (ISymbolWriterProvider) Activator.CreateInstance (type);
+ }
+
+ public static SymbolKind GetSymbolKind (Type type)
+ {
+ if (type.Name.Contains (SymbolKind.PortablePdb.ToString ()))
+ return SymbolKind.PortablePdb;
+ if (type.Name.Contains (SymbolKind.NativePdb.ToString ()))
+ return SymbolKind.NativePdb;
+ if (type.Name.Contains (SymbolKind.Mdb.ToString ()))
+ return SymbolKind.Mdb;
+
+ throw new ArgumentException ();
}
#endif
@@ -726,6 +800,29 @@ namespace Mono.Cecil.Cil {
ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream);
}
+#if !PCL
+ public class DefaultSymbolWriterProvider : ISymbolWriterProvider {
+
+ public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
+ {
+ var reader = module.SymbolReader;
+ if (reader == null)
+ throw new InvalidOperationException ();
+
+ if (module.Image != null && module.Image.HasDebugTables ())
+ return null;
+
+ var reader_kind = SymbolProvider.GetSymbolKind (reader.GetType ());
+ return SymbolProvider.GetWriterProvider (reader_kind).GetSymbolWriter (module, fileName);
+ }
+
+ public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
+ {
+ throw new NotSupportedException ();
+ }
+ }
+#endif
+
#endif
}
@@ -744,6 +841,26 @@ namespace Mono.Cecil {
{
return assemblyFileName + ".mdb";
}
+
+ public static bool IsPortablePdb (string fileName)
+ {
+ using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
+ return IsPortablePdb (file);
+ }
+
+ public static bool IsPortablePdb (Stream stream)
+ {
+ const uint ppdb_signature = 0x424a5342;
+
+ var position = stream.Position;
+ try {
+ var reader = new BinaryReader (stream);
+ return reader.ReadUInt32 () == ppdb_signature;
+ } finally {
+ stream.Position = position;
+ }
+ }
+
}
}
diff --git a/Mono.Cecil.Metadata/Buffers.cs b/Mono.Cecil.Metadata/Buffers.cs
index 5a915e2..0eb0b48 100644
--- a/Mono.Cecil.Metadata/Buffers.cs
+++ b/Mono.Cecil.Metadata/Buffers.cs
@@ -34,6 +34,8 @@ namespace Mono.Cecil.Metadata {
readonly int [] coded_index_sizes = new int [Mixin.CodedIndexCount];
readonly Func<Table, int> counter;
+ internal uint [] string_offsets;
+
public override bool IsEmpty {
get { return false; }
}
@@ -81,7 +83,7 @@ namespace Mono.Cecil.Metadata {
public void WriteString (uint @string)
{
- WriteBySize (@string, large_string);
+ WriteBySize (string_offsets [@string], large_string);
}
public void WriteBlob (uint blob)
@@ -299,7 +301,7 @@ namespace Mono.Cecil.Metadata {
class StringHeapBuffer : HeapBuffer {
- readonly Dictionary<string, uint> strings = new Dictionary<string, uint> (StringComparer.Ordinal);
+ protected Dictionary<string, uint> strings = new Dictionary<string, uint> (StringComparer.Ordinal);
public sealed override bool IsEmpty {
get { return length <= 1; }
@@ -311,23 +313,87 @@ namespace Mono.Cecil.Metadata {
WriteByte (0);
}
- public uint GetStringIndex (string @string)
+ public virtual uint GetStringIndex (string @string)
{
uint index;
if (strings.TryGetValue (@string, out index))
return index;
- index = (uint) base.position;
- WriteString (@string);
+ index = (uint) strings.Count + 1;
strings.Add (@string, index);
return index;
}
+ public uint [] WriteStrings ()
+ {
+ var sorted = SortStrings (strings);
+ strings = null;
+
+ // Add 1 for empty string whose index and offset are both 0
+ var string_offsets = new uint [sorted.Count + 1];
+ string_offsets [0] = 0;
+
+ // Find strings that can be folded
+ var previous = string.Empty;
+ foreach (var entry in sorted) {
+ var @string = entry.Key;
+ var index = entry.Value;
+ var position = base.position;
+
+ if (previous.EndsWith (@string, StringComparison.Ordinal) && !IsLowSurrogateChar (entry.Key [0])) {
+ // Map over the tail of prev string. Watch for null-terminator of prev string.
+ string_offsets [index] = (uint) (position - (Encoding.UTF8.GetByteCount (entry.Key) + 1));
+ } else {
+ string_offsets [index] = (uint) position;
+ WriteString (@string);
+ }
+
+ previous = entry.Key;
+ }
+
+ return string_offsets;
+ }
+
+ static List<KeyValuePair<string, uint>> SortStrings (Dictionary<string, uint> strings)
+ {
+ var sorted = new List<KeyValuePair<string, uint>> (strings);
+ sorted.Sort (new SuffixSort ());
+ return sorted;
+ }
+
+ static bool IsLowSurrogateChar (int c)
+ {
+ return unchecked((uint)(c - 0xDC00)) <= 0xDFFF - 0xDC00;
+ }
+
protected virtual void WriteString (string @string)
{
WriteBytes (Encoding.UTF8.GetBytes (@string));
WriteByte (0);
}
+
+ // Sorts strings such that a string is followed immediately by all strings
+ // that are a suffix of it.
+ private class SuffixSort : IComparer<KeyValuePair<string, uint>> {
+
+ public int Compare(KeyValuePair<string, uint> xPair, KeyValuePair<string, uint> yPair)
+ {
+ var x = xPair.Key;
+ var y = yPair.Key;
+
+ for (int i = x.Length - 1, j = y.Length - 1; i >= 0 & j >= 0; i--, j--) {
+ if (x [i] < y [j]) {
+ return -1;
+ }
+
+ if (x [i] > y [j]) {
+ return +1;
+ }
+ }
+
+ return y.Length.CompareTo (x.Length);
+ }
+ }
}
sealed class BlobHeapBuffer : HeapBuffer {
@@ -365,6 +431,18 @@ namespace Mono.Cecil.Metadata {
sealed class UserStringHeapBuffer : StringHeapBuffer {
+ public override uint GetStringIndex (string @string)
+ {
+ uint index;
+ if (strings.TryGetValue (@string, out index))
+ return index;
+
+ index = (uint) base.position;
+ WriteString (@string);
+ strings.Add (@string, index);
+ return index;
+ }
+
protected override void WriteString (string @string)
{
WriteCompressedUInt32 ((uint) @string.Length * 2 + 1);
diff --git a/Mono.Cecil/AssemblyNameReference.cs b/Mono.Cecil/AssemblyNameReference.cs
index fbbe67a..f5d47ce 100644
--- a/Mono.Cecil/AssemblyNameReference.cs
+++ b/Mono.Cecil/AssemblyNameReference.cs
@@ -238,8 +238,7 @@ namespace Mono.Cecil {
public AssemblyNameReference (string name, Version version)
{
- if (name == null)
- throw new ArgumentNullException ("name");
+ Mixin.CheckName (name);
this.name = name;
this.version = Mixin.CheckVersion (version);
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs
index f9b84bb..5482153 100644
--- a/Mono.Cecil/AssemblyReader.cs
+++ b/Mono.Cecil/AssemblyReader.cs
@@ -99,7 +99,7 @@ namespace Mono.Cecil {
#if !PCL
if (symbol_reader_provider == null && parameters.ReadSymbols)
- symbol_reader_provider = SymbolProvider.GetPlatformReaderProvider ();
+ symbol_reader_provider = new DefaultSymbolReaderProvider ();
#endif
if (symbol_reader_provider != null) {
@@ -115,7 +115,8 @@ namespace Mono.Cecil {
var reader = symbol_reader_provider.GetSymbolReader (module, parameters.SymbolStream);
#endif
- module.ReadSymbols (reader);
+ if (reader != null)
+ module.ReadSymbols (reader);
}
if (module.Image.HasDebugTables ())
diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs
index 7841240..ec7e4d5 100644
--- a/Mono.Cecil/AssemblyWriter.cs
+++ b/Mono.Cecil/AssemblyWriter.cs
@@ -93,7 +93,7 @@ namespace Mono.Cecil {
var symbol_writer_provider = parameters.SymbolWriterProvider;
#if !PCL && !NET_CORE
if (symbol_writer_provider == null && parameters.WriteSymbols)
- symbol_writer_provider = SymbolProvider.GetPlatformWriterProvider ();
+ symbol_writer_provider = new DefaultSymbolWriterProvider ();
#endif
var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters);
@@ -1007,6 +1007,7 @@ namespace Mono.Cecil {
{
BuildModule ();
+ table_heap.string_offsets = string_heap.WriteStrings ();
table_heap.WriteTableHeap ();
}
diff --git a/Mono.Cecil/BaseAssemblyResolver.cs b/Mono.Cecil/BaseAssemblyResolver.cs
index 5390d66..10cf3e5 100644
--- a/Mono.Cecil/BaseAssemblyResolver.cs
+++ b/Mono.Cecil/BaseAssemblyResolver.cs
@@ -105,10 +105,8 @@ namespace Mono.Cecil {
public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters)
{
- if (name == null)
- throw new ArgumentNullException ("name");
- if (parameters == null)
- parameters = new ReaderParameters ();
+ Mixin.CheckName (name);
+ Mixin.CheckParameters (parameters);
var assembly = SearchDirectory (name, directories, parameters);
if (assembly != null)
diff --git a/Mono.Cecil/CustomAttribute.cs b/Mono.Cecil/CustomAttribute.cs
index 11dcb89..5e33667 100644
--- a/Mono.Cecil/CustomAttribute.cs
+++ b/Mono.Cecil/CustomAttribute.cs
@@ -200,15 +200,4 @@ namespace Mono.Cecil {
});
}
}
-
- static partial class Mixin {
-
- public static void CheckName (string name)
- {
- if (name == null)
- throw new ArgumentNullException ("name");
- if (name.Length == 0)
- throw new ArgumentException ("Empty name");
- }
- }
}
diff --git a/Mono.Cecil/DefaultAssemblyResolver.cs b/Mono.Cecil/DefaultAssemblyResolver.cs
index d33b563..d121388 100644
--- a/Mono.Cecil/DefaultAssemblyResolver.cs
+++ b/Mono.Cecil/DefaultAssemblyResolver.cs
@@ -26,8 +26,7 @@ namespace Mono.Cecil {
public override AssemblyDefinition Resolve (AssemblyNameReference name)
{
- if (name == null)
- throw new ArgumentNullException ("name");
+ Mixin.CheckName (name);
AssemblyDefinition assembly;
if (cache.TryGetValue (name.FullName, out assembly))
diff --git a/Mono.Cecil/EventReference.cs b/Mono.Cecil/EventReference.cs
index 925a581..d4df72b 100644
--- a/Mono.Cecil/EventReference.cs
+++ b/Mono.Cecil/EventReference.cs
@@ -28,9 +28,7 @@ namespace Mono.Cecil {
protected EventReference (string name, TypeReference eventType)
: base (name)
{
- if (eventType == null)
- throw new ArgumentNullException ("eventType");
-
+ Mixin.CheckType (eventType, Mixin.Argument.eventType);
event_type = eventType;
}
diff --git a/Mono.Cecil/FieldReference.cs b/Mono.Cecil/FieldReference.cs
index f65a300..944c225 100644
--- a/Mono.Cecil/FieldReference.cs
+++ b/Mono.Cecil/FieldReference.cs
@@ -37,8 +37,7 @@ namespace Mono.Cecil {
public FieldReference (string name, TypeReference fieldType)
: base (name)
{
- if (fieldType == null)
- throw new ArgumentNullException ("fieldType");
+ Mixin.CheckType (fieldType, Mixin.Argument.fieldType);
this.field_type = fieldType;
this.token = new MetadataToken (TokenType.MemberRef);
@@ -47,8 +46,7 @@ namespace Mono.Cecil {
public FieldReference (string name, TypeReference fieldType, TypeReference declaringType)
: this (name, fieldType)
{
- if (declaringType == null)
- throw new ArgumentNullException("declaringType");
+ Mixin.CheckType (declaringType, Mixin.Argument.declaringType);
this.DeclaringType = declaringType;
}
diff --git a/Mono.Cecil/GenericParameter.cs b/Mono.Cecil/GenericParameter.cs
index 24024d2..f2997da 100644
--- a/Mono.Cecil/GenericParameter.cs
+++ b/Mono.Cecil/GenericParameter.cs
@@ -188,8 +188,7 @@ namespace Mono.Cecil {
internal GenericParameter (int position, GenericParameterType type, ModuleDefinition module)
: base (string.Empty, string.Empty)
{
- if (module == null)
- throw new ArgumentNullException ();
+ Mixin.CheckModule (module);
this.position = position;
this.type = type;
diff --git a/Mono.Cecil/Import.cs b/Mono.Cecil/Import.cs
index 846f6d5..8d8b8f7 100644
--- a/Mono.Cecil/Import.cs
+++ b/Mono.Cecil/Import.cs
@@ -740,7 +740,7 @@ namespace Mono.Cecil {
public static void CheckModule (ModuleDefinition module)
{
if (module == null)
- throw new ArgumentNullException ("module");
+ throw new ArgumentNullException (Argument.module.ToString ());
}
public static bool TryGetAssemblyNameReference (this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference)
diff --git a/Mono.Cecil/MetadataResolver.cs b/Mono.Cecil/MetadataResolver.cs
index 95b0e30..cd3c354 100644
--- a/Mono.Cecil/MetadataResolver.cs
+++ b/Mono.Cecil/MetadataResolver.cs
@@ -87,8 +87,7 @@ namespace Mono.Cecil {
public virtual TypeDefinition Resolve (TypeReference type)
{
- if (type == null)
- throw new ArgumentNullException ("type");
+ Mixin.CheckType (type);
type = type.GetElementType ();
@@ -159,8 +158,7 @@ namespace Mono.Cecil {
public virtual FieldDefinition Resolve (FieldReference field)
{
- if (field == null)
- throw new ArgumentNullException ("field");
+ Mixin.CheckField (field);
var type = Resolve (field.DeclaringType);
if (type == null)
@@ -207,8 +205,7 @@ namespace Mono.Cecil {
public virtual MethodDefinition Resolve (MethodReference method)
{
- if (method == null)
- throw new ArgumentNullException ("method");
+ Mixin.CheckMethod (method);
var type = Resolve (method.DeclaringType);
if (type == null)
diff --git a/Mono.Cecil/MethodReference.cs b/Mono.Cecil/MethodReference.cs
index 8e92479..89ee6a7 100644
--- a/Mono.Cecil/MethodReference.cs
+++ b/Mono.Cecil/MethodReference.cs
@@ -144,8 +144,7 @@ namespace Mono.Cecil {
public MethodReference (string name, TypeReference returnType)
: base (name)
{
- if (returnType == null)
- throw new ArgumentNullException ("returnType");
+ Mixin.CheckType (returnType, Mixin.Argument.returnType);
this.return_type = new MethodReturnType (this);
this.return_type.ReturnType = returnType;
@@ -155,8 +154,7 @@ namespace Mono.Cecil {
public MethodReference (string name, TypeReference returnType, TypeReference declaringType)
: this (name, returnType)
{
- if (declaringType == null)
- throw new ArgumentNullException ("declaringType");
+ Mixin.CheckType (declaringType, Mixin.Argument.declaringType);
this.DeclaringType = declaringType;
}
diff --git a/Mono.Cecil/MethodSpecification.cs b/Mono.Cecil/MethodSpecification.cs
index c0f3a86..040be6e 100644
--- a/Mono.Cecil/MethodSpecification.cs
+++ b/Mono.Cecil/MethodSpecification.cs
@@ -70,8 +70,7 @@ namespace Mono.Cecil {
internal MethodSpecification (MethodReference method)
{
- if (method == null)
- throw new ArgumentNullException ("method");
+ Mixin.CheckMethod (method);
this.method = method;
this.token = new MetadataToken (TokenType.MethodSpec);
diff --git a/Mono.Cecil/Modifiers.cs b/Mono.Cecil/Modifiers.cs
index 7575ec1..9c50f0e 100644
--- a/Mono.Cecil/Modifiers.cs
+++ b/Mono.Cecil/Modifiers.cs
@@ -56,7 +56,9 @@ namespace Mono.Cecil {
public OptionalModifierType (TypeReference modifierType, TypeReference type)
: base (type)
{
- Mixin.CheckModifier (modifierType, type);
+ if (modifierType == null)
+ throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ());
+ Mixin.CheckType (type);
this.modifier_type = modifierType;
this.etype = MD.ElementType.CModOpt;
}
@@ -99,21 +101,12 @@ namespace Mono.Cecil {
public RequiredModifierType (TypeReference modifierType, TypeReference type)
: base (type)
{
- Mixin.CheckModifier (modifierType, type);
+ if (modifierType == null)
+ throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ());
+ Mixin.CheckType (type);
this.modifier_type = modifierType;
this.etype = MD.ElementType.CModReqD;
}
}
-
- static partial class Mixin {
-
- public static void CheckModifier (TypeReference modifierType, TypeReference type)
- {
- if (modifierType == null)
- throw new ArgumentNullException ("modifierType");
- if (type == null)
- throw new ArgumentNullException ("type");
- }
- }
}
diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs
index 0d799c8..2036986 100644
--- a/Mono.Cecil/ModuleDefinition.cs
+++ b/Mono.Cecil/ModuleDefinition.cs
@@ -88,10 +88,12 @@ namespace Mono.Cecil {
set { symbol_reader_provider = value; }
}
+#if !PCL
public bool ReadSymbols {
get { return read_symbols; }
set { read_symbols = value; }
}
+#endif
public bool ReadWrite {
get { return read_write; }
@@ -234,10 +236,13 @@ namespace Mono.Cecil {
set { symbol_writer_provider = value; }
}
+#if !PCL
public bool WriteSymbols {
get { return write_symbols; }
set { write_symbols = value; }
}
+#endif
+
#if !PCL && !NET_CORE
public SR.StrongNameKeyPair StrongNameKeyPair {
get { return key_pair; }
@@ -615,7 +620,7 @@ namespace Mono.Cecil {
public bool HasTypeReference (string scope, string fullName)
{
- CheckFullName (fullName);
+ Mixin.CheckFullName (fullName);
if (!HasImage)
return false;
@@ -630,7 +635,7 @@ namespace Mono.Cecil {
public bool TryGetTypeReference (string scope, string fullName, out TypeReference type)
{
- CheckFullName (fullName);
+ Mixin.CheckFullName (fullName);
if (!HasImage) {
type = null;
@@ -678,7 +683,7 @@ namespace Mono.Cecil {
public TypeDefinition GetType (string fullName)
{
- CheckFullName (fullName);
+ Mixin.CheckFullName (fullName);
var position = fullName.IndexOf ('/');
if (position > 0)
@@ -714,14 +719,6 @@ namespace Mono.Cecil {
}
}
- static void CheckFullName (string fullName)
- {
- if (fullName == null)
- throw new ArgumentNullException ("fullName");
- if (fullName.Length == 0)
- throw new ArgumentException ();
- }
-
TypeDefinition GetNestedType (string fullname)
{
var names = fullname.Split ('/');
@@ -1089,10 +1086,7 @@ namespace Mono.Cecil {
if (string.IsNullOrEmpty (file_name))
throw new InvalidOperationException ();
- var provider = SymbolProvider.GetPlatformReaderProvider ();
- if (provider == null)
- throw new InvalidOperationException ();
-
+ var provider = new DefaultSymbolReaderProvider (throwIfNoSymbol: true);
ReadSymbols (provider.GetSymbolReader (this, file_name));
}
#endif
@@ -1220,18 +1214,53 @@ namespace Mono.Cecil {
static partial class Mixin {
+ public enum Argument {
+ name,
+ fileName,
+ fullName,
+ stream,
+ type,
+ method,
+ field,
+ parameters,
+ module,
+ modifierType,
+ eventType,
+ fieldType,
+ declaringType,
+ returnType,
+ propertyType,
+ interfaceType,
+ }
+
+ public static void CheckName (object name)
+ {
+ if (name == null)
+ throw new ArgumentNullException (Argument.name.ToString ());
+ }
+
+ public static void CheckName (string name)
+ {
+ if (string.IsNullOrEmpty (name))
+ throw new ArgumentNullOrEmptyException (Argument.name.ToString ());
+ }
+
public static void CheckFileName (string fileName)
{
- if (fileName == null)
- throw new ArgumentNullException ("fileName");
- if (fileName.Length == 0)
- throw new ArgumentException ();
+ if (string.IsNullOrEmpty (fileName))
+ throw new ArgumentNullOrEmptyException (Argument.fileName.ToString ());
+ }
+
+ public static void CheckFullName (string fullName)
+ {
+ if (string.IsNullOrEmpty (fullName))
+ throw new ArgumentNullOrEmptyException (Argument.fullName.ToString ());
}
public static void CheckStream (object stream)
{
if (stream == null)
- throw new ArgumentNullException ("stream");
+ throw new ArgumentNullException (Argument.stream.ToString ());
}
public static void CheckWriteSeek (Stream stream)
@@ -1251,19 +1280,25 @@ namespace Mono.Cecil {
public static void CheckType (object type)
{
if (type == null)
- throw new ArgumentNullException ("type");
+ throw new ArgumentNullException (Argument.type.ToString ());
+ }
+
+ public static void CheckType (object type, Argument argument)
+ {
+ if (type == null)
+ throw new ArgumentNullException (argument.ToString ());
}
public static void CheckField (object field)
{
if (field == null)
- throw new ArgumentNullException ("field");
+ throw new ArgumentNullException (Argument.field.ToString ());
}
public static void CheckMethod (object method)
{
if (method == null)
- throw new ArgumentNullException ("method");
+ throw new ArgumentNullException (Argument.method.ToString ());
}
#endif
@@ -1271,7 +1306,7 @@ namespace Mono.Cecil {
public static void CheckParameters (object parameters)
{
if (parameters == null)
- throw new ArgumentNullException ("parameters");
+ throw new ArgumentNullException (Argument.parameters.ToString ());
}
public static bool HasImage (this ModuleDefinition self)
diff --git a/Mono.Cecil/PropertyReference.cs b/Mono.Cecil/PropertyReference.cs
index 4b827cd..2434d0f 100644
--- a/Mono.Cecil/PropertyReference.cs
+++ b/Mono.Cecil/PropertyReference.cs
@@ -30,8 +30,7 @@ namespace Mono.Cecil {
internal PropertyReference (string name, TypeReference propertyType)
: base (name)
{
- if (propertyType == null)
- throw new ArgumentNullException ("propertyType");
+ Mixin.CheckType (propertyType, Mixin.Argument.propertyType);
property_type = propertyType;
}
diff --git a/Mono.Cecil/TypeDefinition.cs b/Mono.Cecil/TypeDefinition.cs
index 62f65a5..435beaf 100644
--- a/Mono.Cecil/TypeDefinition.cs
+++ b/Mono.Cecil/TypeDefinition.cs
@@ -528,8 +528,7 @@ namespace Mono.Cecil {
public InterfaceImplementation (TypeReference interfaceType)
{
- if (interfaceType == null)
- throw new ArgumentNullException ("interfaceType");
+ Mixin.CheckType (interfaceType, Mixin.Argument.interfaceType);
this.interface_type = interfaceType;
this.token = new MetadataToken (TokenType.InterfaceImpl);
diff --git a/Mono.Cecil/TypeSpecification.cs b/Mono.Cecil/TypeSpecification.cs
index d26be5b..16e0cab 100644
--- a/Mono.Cecil/TypeSpecification.cs
+++ b/Mono.Cecil/TypeSpecification.cs
@@ -65,13 +65,4 @@ namespace Mono.Cecil {
return element_type.GetElementType ();
}
}
-
- static partial class Mixin {
-
- public static void CheckType (TypeReference type)
- {
- if (type == null)
- throw new ArgumentNullException ("type");
- }
- }
}
diff --git a/Mono/Empty.cs b/Mono/Empty.cs
index 14589cc..de28e65 100644
--- a/Mono/Empty.cs
+++ b/Mono/Empty.cs
@@ -17,6 +17,14 @@ namespace Mono {
public static readonly T [] Array = new T [0];
}
+
+ class ArgumentNullOrEmptyException : ArgumentException {
+
+ public ArgumentNullOrEmptyException (string paramName)
+ : base ("Argument null or empty", paramName)
+ {
+ }
+ }
}
namespace Mono.Cecil {
diff --git a/Test/Mono.Cecil.Tests.csproj b/Test/Mono.Cecil.Tests.csproj
index 993a1c6..9277d6a 100644
--- a/Test/Mono.Cecil.Tests.csproj
+++ b/Test/Mono.Cecil.Tests.csproj
@@ -10,6 +10,14 @@
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
+ <ProjectReference Include="..\symbols\mdb\Mono.Cecil.Mdb.csproj">
+ <Project>{8559dd7f-a16f-46d0-a05a-9139faeba8fd}</Project>
+ <Name>Mono.Cecil.Mdb</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\symbols\pdb\Mono.Cecil.Pdb.csproj">
+ <Project>{63e6915c-7ea4-4d76-ab28-0d7191eea626}</Project>
+ <Name>Mono.Cecil.Pdb</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\ProjectInfo.cs" />
diff --git a/Test/Mono.Cecil.Tests/SymbolTests.cs b/Test/Mono.Cecil.Tests/SymbolTests.cs
new file mode 100644
index 0000000..d9b85f1
--- /dev/null
+++ b/Test/Mono.Cecil.Tests/SymbolTests.cs
@@ -0,0 +1,53 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Mono.Cecil.Cil;
+using Mono.Cecil.Mdb;
+using Mono.Cecil.Pdb;
+
+namespace Mono.Cecil.Tests {
+
+ [TestFixture]
+ public class SymbolTests : BaseTestFixture {
+
+ [Test]
+ public void DefaultPdb ()
+ {
+ IgnoreOnMono ();
+
+ TestModule ("libpdb.dll", module => {
+ Assert.IsTrue (module.HasSymbols);
+ Assert.AreEqual (typeof (NativePdbReader), module.SymbolReader.GetType ());
+ }, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider));
+ }
+
+ [Test]
+ public void DefaultMdb ()
+ {
+ TestModule ("libmdb.dll", module => {
+ Assert.IsTrue (module.HasSymbols);
+ Assert.AreEqual (typeof (MdbReader), module.SymbolReader.GetType ());
+ }, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider));
+ }
+
+ [Test]
+ public void DefaultPortablePdb ()
+ {
+ TestModule ("PdbTarget.exe", module => {
+ Assert.IsTrue (module.HasSymbols);
+ Assert.AreEqual (typeof (PortablePdbReader), module.SymbolReader.GetType ());
+ }, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider));
+ }
+
+ [Test]
+ public void DefaultEmbeddedPortablePdb ()
+ {
+ TestModule ("EmbeddedPdbTarget.exe", module => {
+ Assert.IsTrue (module.HasSymbols);
+ Assert.AreEqual (typeof (PortablePdbReader), module.SymbolReader.GetType ());
+ }, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider), verify: !Platform.OnMono);
+ }
+ }
+}
diff --git a/Test/Resources/assemblies/libmdb.dll b/Test/Resources/assemblies/libmdb.dll
new file mode 100644
index 0000000..545c2c0
--- /dev/null
+++ b/Test/Resources/assemblies/libmdb.dll
Binary files differ
diff --git a/Test/Resources/assemblies/libmdb.dll.mdb b/Test/Resources/assemblies/libmdb.dll.mdb
new file mode 100644
index 0000000..76b56d4
--- /dev/null
+++ b/Test/Resources/assemblies/libmdb.dll.mdb
Binary files differ
diff --git a/Test/Resources/assemblies/libpdb.dll b/Test/Resources/assemblies/libpdb.dll
new file mode 100644
index 0000000..29dbf08
--- /dev/null
+++ b/Test/Resources/assemblies/libpdb.dll
Binary files differ
diff --git a/Test/Resources/assemblies/libpdb.pdb b/Test/Resources/assemblies/libpdb.pdb
new file mode 100644
index 0000000..dd35d1b
--- /dev/null
+++ b/Test/Resources/assemblies/libpdb.pdb
Binary files differ
diff --git a/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs b/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs
index 317a496..4ad1bc4 100644
--- a/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs
+++ b/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs
@@ -20,7 +20,7 @@ using Mono.Cecil.Cil;
namespace Mono.Cecil.Pdb {
- public class PdbReader : ISymbolReader {
+ public class NativePdbReader : ISymbolReader {
int age;
Guid guid;
@@ -29,7 +29,7 @@ namespace Mono.Cecil.Pdb {
readonly Dictionary<string, Document> documents = new Dictionary<string, Document> ();
readonly Dictionary<uint, PdbFunction> functions = new Dictionary<uint, PdbFunction> ();
- internal PdbReader (Disposable<Stream> file)
+ internal NativePdbReader (Disposable<Stream> file)
{
this.pdb_file = file;
}
diff --git a/symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs b/symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs
index 553ef2f..28df637 100644
--- a/symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs
+++ b/symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs
@@ -19,13 +19,13 @@ using Mono.Collections.Generic;
namespace Mono.Cecil.Pdb {
- public class PdbWriter : Cil.ISymbolWriter {
+ public class NativePdbWriter : Cil.ISymbolWriter {
readonly ModuleDefinition module;
readonly SymWriter writer;
readonly Dictionary<string, SymDocumentWriter> documents;
- internal PdbWriter (ModuleDefinition module, SymWriter writer)
+ internal NativePdbWriter (ModuleDefinition module, SymWriter writer)
{
this.module = module;
this.writer = writer;
diff --git a/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs b/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs
index c397398..ced9729 100644
--- a/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs
+++ b/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs
@@ -22,7 +22,7 @@ namespace Mono.Cecil.Pdb {
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
- return new PdbReader (Disposable.Owned (File.OpenRead (Mixin.GetPdbFileName (fileName)) as Stream));
+ return new NativePdbReader (Disposable.Owned (File.OpenRead (Mixin.GetPdbFileName (fileName)) as Stream));
}
public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
@@ -30,7 +30,7 @@ namespace Mono.Cecil.Pdb {
Mixin.CheckModule (module);
Mixin.CheckStream (symbolStream);
- return new PdbReader (Disposable.NotOwned (symbolStream));
+ return new NativePdbReader (Disposable.NotOwned (symbolStream));
}
}
@@ -41,7 +41,7 @@ namespace Mono.Cecil.Pdb {
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
- return IsPortablePdb (Mixin.GetPdbFileName (fileName))
+ return Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName))
? new PortablePdbReaderProvider ().GetSymbolReader (module, fileName)
: new NativePdbReaderProvider ().GetSymbolReader (module, fileName);
}
@@ -52,29 +52,10 @@ namespace Mono.Cecil.Pdb {
Mixin.CheckStream (symbolStream);
Mixin.CheckReadSeek (symbolStream);
- return IsPortablePdb (symbolStream)
+ return Mixin.IsPortablePdb (symbolStream)
? new PortablePdbReaderProvider ().GetSymbolReader (module, symbolStream)
: new NativePdbReaderProvider ().GetSymbolReader (module, symbolStream);
}
-
- static bool IsPortablePdb (string fileName)
- {
- using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
- return IsPortablePdb (file);
- }
-
- static bool IsPortablePdb (Stream stream)
- {
- const uint ppdb_signature = 0x424a5342;
-
- var position = stream.Position;
- try {
- var reader = new BinaryReader (stream);
- return reader.ReadUInt32 () == ppdb_signature;
- } finally {
- stream.Position = position;
- }
- }
}
#if !READ_ONLY
@@ -86,7 +67,7 @@ namespace Mono.Cecil.Pdb {
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
- return new PdbWriter (module, CreateWriter (module, Mixin.GetPdbFileName (fileName)));
+ return new NativePdbWriter (module, CreateWriter (module, Mixin.GetPdbFileName (fileName)));
}
static SymWriter CreateWriter (ModuleDefinition module, string pdb)