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>2021-06-30 19:13:42 +0300
committerMarek Safar <marek.safar@gmail.com>2021-06-30 19:13:42 +0300
commitcfb80b23787949a6fa5e3e3d6af35d86287517e9 (patch)
treef0da81c6aa2dd83a5309775aa9da05bd1f459b27
parente069cd8d25d5b61b0e28fe65e75959c20af7aa80 (diff)
parent96c159d4687ea7493893011f3bd4a6e098dab163 (diff)
Merge remote-tracking branch 'upstream/master'
-rw-r--r--Mono.Cecil.Cil/CodeWriter.cs1
-rw-r--r--Mono.Cecil.Cil/PortablePdb.cs30
-rw-r--r--Mono.Cecil.Cil/Symbols.cs57
-rw-r--r--Mono.Cecil.PE/ImageWriter.cs2
-rw-r--r--Mono.Cecil/AssemblyReader.cs58
-rw-r--r--Mono.Cecil/AssemblyWriter.cs13
-rw-r--r--Mono.Cecil/FieldDefinition.cs6
-rw-r--r--Mono.Cecil/MetadataResolver.cs3
-rw-r--r--Test/Mono.Cecil.Tests/FieldTests.cs8
-rw-r--r--Test/Mono.Cecil.Tests/PortablePdbTests.cs7
-rw-r--r--Test/Mono.Cecil.Tests/ResolveTests.cs35
-rw-r--r--Test/Mono.Cecil.Tests/SymbolTests.cs9
-rw-r--r--Test/Resources/assemblies/System.Private.Xml.dllbin0 -> 8422792 bytes
-rw-r--r--Test/Resources/assemblies/System.Private.Xml.pdbbin0 -> 1284024 bytes
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb.csproj1
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs109
-rw-r--r--symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs43
-rw-r--r--symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs11
-rw-r--r--symbols/pdb/Test/Resources/assemblies/longtypename.dllbin0 -> 4096 bytes
-rw-r--r--symbols/pdb/Test/Resources/assemblies/longtypename.pdbbin0 -> 11776 bytes
20 files changed, 275 insertions, 118 deletions
diff --git a/Mono.Cecil.Cil/CodeWriter.cs b/Mono.Cecil.Cil/CodeWriter.cs
index 88942e1..501710e 100644
--- a/Mono.Cecil.Cil/CodeWriter.cs
+++ b/Mono.Cecil.Cil/CodeWriter.cs
@@ -424,7 +424,6 @@ namespace Mono.Cecil.Cil {
{
switch (instruction.opcode.FlowControl) {
case FlowControl.Branch:
- case FlowControl.Break:
case FlowControl.Throw:
case FlowControl.Return:
stack_size = 0;
diff --git a/Mono.Cecil.Cil/PortablePdb.cs b/Mono.Cecil.Cil/PortablePdb.cs
index b5515ba..aff6b29 100644
--- a/Mono.Cecil.Cil/PortablePdb.cs
+++ b/Mono.Cecil.Cil/PortablePdb.cs
@@ -70,8 +70,20 @@ namespace Mono.Cecil.Cil {
if (image == module.Image)
return true;
- var entry = header.GetCodeViewEntry ();
- if (entry == null)
+ foreach (var entry in header.Entries) {
+ if (!IsMatchingEntry (image.PdbHeap, entry))
+ continue;
+
+ ReadModule ();
+ return true;
+ }
+
+ return false;
+ }
+
+ static bool IsMatchingEntry (PdbHeap heap, ImageDebugHeaderEntry entry)
+ {
+ if (entry.Directory.Type != ImageDebugType.CodeView)
return false;
var data = entry.Data;
@@ -88,15 +100,11 @@ namespace Mono.Cecil.Cil {
var module_guid = new Guid (buffer);
- Buffer.BlockCopy (image.PdbHeap.Id, 0, buffer, 0, 16);
+ Buffer.BlockCopy (heap.Id, 0, buffer, 0, 16);
var pdb_guid = new Guid (buffer);
- if (module_guid != pdb_guid)
- return false;
-
- ReadModule ();
- return true;
+ return module_guid == pdb_guid;
}
static int ReadInt32 (byte [] bytes, int start)
@@ -301,7 +309,11 @@ namespace Mono.Cecil.Cil {
// PDB Age
buffer.WriteUInt32 (1);
// PDB Path
- buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (writer.BaseStream.GetFileName ()));
+ var fileName = writer.BaseStream.GetFileName ();
+ if (string.IsNullOrEmpty (fileName)) {
+ fileName = module.Assembly.Name.Name + ".pdb";
+ }
+ buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (fileName));
buffer.WriteByte (0);
var data = new byte [buffer.length];
diff --git a/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.Cil/Symbols.cs
index 4cf435d..5e92b67 100644
--- a/Mono.Cecil.Cil/Symbols.cs
+++ b/Mono.Cecil.Cil/Symbols.cs
@@ -619,17 +619,36 @@ namespace Mono.Cecil.Cil {
public sealed class EmbeddedSourceDebugInformation : CustomDebugInformation {
+ internal uint index;
+ internal MetadataReader debug_reader;
+ internal bool resolved;
internal byte [] content;
internal bool compress;
public byte [] Content {
- get { return content; }
- set { content = value; }
+ get {
+ if (!resolved)
+ Resolve ();
+
+ return content;
+ }
+ set {
+ content = value;
+ resolved = true;
+ }
}
public bool Compress {
- get { return compress; }
- set { compress = value; }
+ get {
+ if (!resolved)
+ Resolve ();
+
+ return compress;
+ }
+ set {
+ compress = value;
+ resolved = true;
+ }
}
public override CustomDebugInformationKind Kind {
@@ -638,12 +657,42 @@ namespace Mono.Cecil.Cil {
public static Guid KindIdentifier = new Guid ("{0E8A571B-6926-466E-B4AD-8AB04611F5FE}");
+ internal EmbeddedSourceDebugInformation (uint index, MetadataReader debug_reader)
+ : base (KindIdentifier)
+ {
+ this.index = index;
+ this.debug_reader = debug_reader;
+ }
+
public EmbeddedSourceDebugInformation (byte [] content, bool compress)
: base (KindIdentifier)
{
+ this.resolved = true;
this.content = content;
this.compress = compress;
}
+
+ internal byte [] ReadRawEmbeddedSourceDebugInformation ()
+ {
+ if (debug_reader == null)
+ throw new InvalidOperationException ();
+
+ return debug_reader.ReadRawEmbeddedSourceDebugInformation (index);
+ }
+
+ void Resolve ()
+ {
+ if (resolved)
+ return;
+
+ if (debug_reader == null)
+ throw new InvalidOperationException ();
+
+ var row = debug_reader.ReadEmbeddedSourceDebugInformation (index);
+ content = row.Col1;
+ compress = row.Col2;
+ resolved = true;
+ }
}
public sealed class SourceLinkDebugInformation : CustomDebugInformation {
diff --git a/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.PE/ImageWriter.cs
index b33efe3..7e5e923 100644
--- a/Mono.Cecil.PE/ImageWriter.cs
+++ b/Mono.Cecil.PE/ImageWriter.cs
@@ -784,7 +784,7 @@ namespace Mono.Cecil.PE {
int GetStrongNameLength ()
{
- if (module.Assembly == null)
+ if (module.kind == ModuleKind.NetModule || module.Assembly == null)
return 0;
var public_key = module.Assembly.Name.PublicKey;
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs
index 2a59358..9fdcf68 100644
--- a/Mono.Cecil/AssemblyReader.cs
+++ b/Mono.Cecil/AssemblyReader.cs
@@ -182,7 +182,7 @@ namespace Mono.Cecil {
ReadCustomAttributes (module);
var assembly = module.Assembly;
- if (assembly == null)
+ if (module.kind == ModuleKind.NetModule || assembly == null)
return;
ReadCustomAttributes (assembly);
@@ -667,8 +667,10 @@ namespace Mono.Cecil {
AssemblyResolver = module.AssemblyResolver
};
- modules.Add (ModuleDefinition.ReadModule (
- GetModuleFileName (name), parameters));
+ var netmodule = ModuleDefinition.ReadModule (GetModuleFileName (name), parameters);
+ netmodule.assembly = this.module.assembly;
+
+ modules.Add (netmodule);
}
return modules;
@@ -3221,28 +3223,7 @@ namespace Mono.Cecil {
infos.Add (async_body);
} else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) {
- var signature = ReadSignature (rows [i].Col2);
- var format = signature.ReadInt32 ();
- var length = signature.sig_length - 4;
-
- var info = null as CustomDebugInformation;
-
- if (format == 0) {
- info = new EmbeddedSourceDebugInformation (signature.ReadBytes ((int) length), compress: false);
- } else if (format > 0) {
- var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length));
- var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document
- var decompressed_stream = new MemoryStream (decompressed_document);
-
- using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
- deflate_stream.CopyTo (decompressed_stream);
-
- info = new EmbeddedSourceDebugInformation (decompressed_document, compress: true);
- } else if (format < 0) {
- info = new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2));
- }
-
- infos.Add (info);
+ infos.Add (new EmbeddedSourceDebugInformation (rows [i].Col2, this));
} else if (rows [i].Col1 == SourceLinkDebugInformation.KindIdentifier) {
infos.Add (new SourceLinkDebugInformation (Encoding.UTF8.GetString (ReadBlob (rows [i].Col2))));
} else {
@@ -3254,6 +3235,33 @@ namespace Mono.Cecil {
return infos;
}
+
+ public byte [] ReadRawEmbeddedSourceDebugInformation (uint index)
+ {
+ var signature = ReadSignature (index);
+ return signature.ReadBytes ((int) signature.sig_length);
+ }
+
+ public Row<byte [], bool> ReadEmbeddedSourceDebugInformation (uint index)
+ {
+ var signature = ReadSignature (index);
+ var format = signature.ReadInt32 ();
+ var length = signature.sig_length - 4;
+
+ if (format == 0) {
+ return new Row<byte [], bool> (signature.ReadBytes ((int) length), false);
+ } else if (format > 0) {
+ var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length));
+ var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document
+ var decompressed_stream = new MemoryStream (decompressed_document);
+
+ using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
+ deflate_stream.CopyTo (decompressed_stream);
+
+ return new Row<byte [], bool> (decompressed_document, true);
+ } else
+ throw new NotSupportedException ();
+ }
}
sealed class SignatureReader : ByteBuffer {
diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs
index f14ce1b..c83f997 100644
--- a/Mono.Cecil/AssemblyWriter.cs
+++ b/Mono.Cecil/AssemblyWriter.cs
@@ -94,7 +94,7 @@ namespace Mono.Cecil {
if (module.symbol_reader != null)
module.symbol_reader.Dispose ();
- var name = module.assembly != null ? module.assembly.Name : null;
+ var name = module.assembly != null && module.kind != ModuleKind.NetModule ? module.assembly.Name : null;
var fq_name = stream.value.GetFileName ();
var timestamp = parameters.Timestamp ?? module.timestamp;
var symbol_writer_provider = parameters.SymbolWriterProvider;
@@ -1018,7 +1018,7 @@ namespace Mono.Cecil {
var assembly = module.Assembly;
- if (assembly != null)
+ if (module.kind != ModuleKind.NetModule && assembly != null)
BuildAssembly ();
if (module.HasAssemblyReferences)
@@ -1035,7 +1035,7 @@ namespace Mono.Cecil {
BuildTypes ();
- if (assembly != null) {
+ if (module.kind != ModuleKind.NetModule && assembly != null) {
if (assembly.HasCustomAttributes)
AddCustomAttributes (assembly);
@@ -2428,6 +2428,13 @@ namespace Mono.Cecil {
void AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source)
{
var signature = CreateSignatureWriter ();
+
+ if (!embedded_source.resolved) {
+ signature.WriteBytes (embedded_source.ReadRawEmbeddedSourceDebugInformation ());
+ AddCustomDebugInformation (provider, embedded_source, signature);
+ return;
+ }
+
var content = embedded_source.content ?? Empty<byte>.Array;
if (embedded_source.compress) {
signature.WriteInt32 (content.Length);
diff --git a/Mono.Cecil/FieldDefinition.cs b/Mono.Cecil/FieldDefinition.cs
index 15b7720..7ce8d27 100644
--- a/Mono.Cecil/FieldDefinition.cs
+++ b/Mono.Cecil/FieldDefinition.cs
@@ -113,6 +113,7 @@ namespace Mono.Cecil {
}
set {
initial_value = value;
+ HasFieldRVA = !initial_value.IsNullOrEmpty ();
rva = 0;
}
}
@@ -245,6 +246,11 @@ namespace Mono.Cecil {
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasDefault, value); }
}
+ public bool HasFieldRVA {
+ get { return attributes.GetAttributes ((ushort) FieldAttributes.HasFieldRVA); }
+ set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasFieldRVA, value); }
+ }
+
#endregion
public override bool IsDefinition {
diff --git a/Mono.Cecil/MetadataResolver.cs b/Mono.Cecil/MetadataResolver.cs
index 630ec8a..6511b41 100644
--- a/Mono.Cecil/MetadataResolver.cs
+++ b/Mono.Cecil/MetadataResolver.cs
@@ -115,6 +115,9 @@ namespace Mono.Cecil {
case MetadataScopeType.ModuleDefinition:
return GetType ((ModuleDefinition) scope, type);
case MetadataScopeType.ModuleReference:
+ if (type.Module.Assembly == null)
+ return null;
+
var modules = type.Module.Assembly.Modules;
var module_ref = (ModuleReference) scope;
for (int i = 0; i < modules.Count; i++) {
diff --git a/Test/Mono.Cecil.Tests/FieldTests.cs b/Test/Mono.Cecil.Tests/FieldTests.cs
index 05165d6..4f575de 100644
--- a/Test/Mono.Cecil.Tests/FieldTests.cs
+++ b/Test/Mono.Cecil.Tests/FieldTests.cs
@@ -122,6 +122,14 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual (2, buffer.ReadUInt32 ());
Assert.AreEqual (3, buffer.ReadUInt32 ());
Assert.AreEqual (4, buffer.ReadUInt32 ());
+
+ var intialValue = field.InitialValue;
+ field.InitialValue = null;
+ Assert.False (field.Attributes.HasFlag (FieldAttributes.HasFieldRVA));
+
+ field.InitialValue = intialValue;
+
+ Assert.True (field.Attributes.HasFlag (FieldAttributes.HasFieldRVA));
});
}
diff --git a/Test/Mono.Cecil.Tests/PortablePdbTests.cs b/Test/Mono.Cecil.Tests/PortablePdbTests.cs
index b0c1f32..43b8cfe 100644
--- a/Test/Mono.Cecil.Tests/PortablePdbTests.cs
+++ b/Test/Mono.Cecil.Tests/PortablePdbTests.cs
@@ -491,9 +491,12 @@ namespace Mono.Cecil.Tests {
public void EmbeddedSource ()
{
TestModule ("embedcs.exe", module => {
+ }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider));
+
+ TestModule ("embedcs.exe", module => {
var program = GetDocument (module.GetType ("Program"));
var program_src = GetSourceDebugInfo (program);
- Assert.IsTrue (program_src.compress);
+ Assert.IsTrue (program_src.Compress);
var program_src_content = Encoding.UTF8.GetString (program_src.Content);
Assert.AreEqual (Normalize (@"using System;
@@ -533,7 +536,7 @@ class Program
var a = GetDocument (module.GetType ("A"));
var a_src = GetSourceDebugInfo (a);
- Assert.IsFalse (a_src.compress);
+ Assert.IsFalse (a_src.Compress);
var a_src_content = Encoding.UTF8.GetString (a_src.Content);
Assert.AreEqual (Normalize (@"class A
{
diff --git a/Test/Mono.Cecil.Tests/ResolveTests.cs b/Test/Mono.Cecil.Tests/ResolveTests.cs
index bb57570..bce0003 100644
--- a/Test/Mono.Cecil.Tests/ResolveTests.cs
+++ b/Test/Mono.Cecil.Tests/ResolveTests.cs
@@ -247,6 +247,41 @@ namespace Mono.Cecil.Tests {
}
}
+ [Test]
+ public void ResolveModuleReferenceFromMemberReferenceTest ()
+ {
+ using (var mma = AssemblyDefinition.ReadAssembly (GetAssemblyResourcePath ("mma.exe"))) {
+ var modB = mma.Modules [2];
+ var bazType = modB.GetType ("Module.B.Baz");
+ var gazonkMethod = bazType.Methods.First (m => m.Name.Equals ("Gazonk"));
+ var callInstr = gazonkMethod.Body.Instructions [1];
+
+ var methodRef = callInstr.Operand as MethodReference;
+ var methodTypeRef = methodRef.DeclaringType;
+
+ Assert.AreEqual (mma, methodTypeRef.Module.Assembly);
+
+ var def = methodTypeRef.Resolve ();
+ Assert.IsNotNull (def);
+ Assert.AreEqual ("Module.A.Foo", def.FullName);
+ }
+ }
+
+ [Test]
+ public void ResolveModuleReferenceFromMemberReferenceOfSingleNetModuleTest ()
+ {
+ using (var modb = ModuleDefinition.ReadModule (GetAssemblyResourcePath ("modb.netmodule"))) {
+ var bazType = modb.GetType ("Module.B.Baz");
+ var gazonkMethod = bazType.Methods.First (m => m.Name.Equals ("Gazonk"));
+ var callInstr = gazonkMethod.Body.Instructions [1];
+
+ var methodRef = callInstr.Operand as MethodReference;
+ var methodTypeRef = methodRef.DeclaringType;
+
+ Assert.IsNull (methodTypeRef.Module.Assembly);
+ Assert.IsNull (methodTypeRef.Resolve ());
+ }
+ }
TRet GetReference<TDel, TRet> (TDel code)
{
var @delegate = code as Delegate;
diff --git a/Test/Mono.Cecil.Tests/SymbolTests.cs b/Test/Mono.Cecil.Tests/SymbolTests.cs
index 941f4a1..691581e 100644
--- a/Test/Mono.Cecil.Tests/SymbolTests.cs
+++ b/Test/Mono.Cecil.Tests/SymbolTests.cs
@@ -128,5 +128,14 @@ namespace Mono.Cecil.Tests {
}
}
}
+
+ [Test]
+ public void MultipleCodeViewEntries ()
+ {
+ using (var module = GetResourceModule ("System.Private.Xml.dll", new ReaderParameters { ReadSymbols = true })) {
+ Assert.IsTrue (module.HasSymbols);
+ Assert.IsNotNull (module.SymbolReader);
+ }
+ }
}
}
diff --git a/Test/Resources/assemblies/System.Private.Xml.dll b/Test/Resources/assemblies/System.Private.Xml.dll
new file mode 100644
index 0000000..82bc088
--- /dev/null
+++ b/Test/Resources/assemblies/System.Private.Xml.dll
Binary files differ
diff --git a/Test/Resources/assemblies/System.Private.Xml.pdb b/Test/Resources/assemblies/System.Private.Xml.pdb
new file mode 100644
index 0000000..9790d8d
--- /dev/null
+++ b/Test/Resources/assemblies/System.Private.Xml.pdb
Binary files differ
diff --git a/symbols/pdb/Mono.Cecil.Pdb.csproj b/symbols/pdb/Mono.Cecil.Pdb.csproj
index 265159d..8e7d08c 100644
--- a/symbols/pdb/Mono.Cecil.Pdb.csproj
+++ b/symbols/pdb/Mono.Cecil.Pdb.csproj
@@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net40</TargetFrameworks>
<NoWarn>0649</NoWarn>
+ <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil.csproj">
diff --git a/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs b/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs
index 297df0c..0bc32dc 100644
--- a/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs
+++ b/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs
@@ -5,8 +5,10 @@ using System.Text;
namespace Mono.Cecil.Pdb {
+ // WARNING: most methods should be reworked into PreserveSig methods
+
[ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("BA3FEE4C-ECB9-4e41-83B7-183FA41CD859")]
- interface IMetaDataEmit {
+ unsafe interface IMetaDataEmit {
void SetModuleProps (string szName);
void Save (string szFile, uint dwSaveFlags);
void SaveToStream (IntPtr pIStream, uint dwSaveFlags);
@@ -63,7 +65,7 @@ namespace Mono.Cecil.Pdb {
}
[ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
- interface IMetaDataImport {
+ unsafe interface IMetaDataImport {
[PreserveSig]
void CloseEnum (uint hEnum);
uint CountEnum (uint hEnum);
@@ -74,7 +76,9 @@ namespace Mono.Cecil.Pdb {
uint FindTypeDefByName (string szTypeDef, uint tkEnclosingClass);
Guid GetScopeProps (StringBuilder szName, uint cchName, out uint pchName);
uint GetModuleFromScope ();
- uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags);
+
+ [PreserveSig]
+ uint GetTypeDefProps (uint td, char* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends);
uint GetInterfaceImplProps (uint iiImpl, out uint pClass);
uint GetTypeRefProps (uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName);
uint ResolveTypeRef (uint tr, [In] ref Guid riid, [MarshalAs (UnmanagedType.Interface)] out object ppIScope);
@@ -94,7 +98,9 @@ namespace Mono.Cecil.Pdb {
uint FindMethod (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
uint FindField (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
uint FindMemberRef (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob);
- uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);
+
+ [PreserveSig]
+ uint GetMethodProps (uint mb, uint* pClass, char* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags);
uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr /* byte* */ ppvSigBlob);
uint EnumProperties (ref uint phEnum, uint td, IntPtr /* uint* */ rProperties, uint cMax);
uint EnumEvents (ref uint phEnum, uint td, IntPtr /* uint* */ rEvents, uint cMax);
@@ -136,18 +142,22 @@ namespace Mono.Cecil.Pdb {
[PreserveSig]
[return: MarshalAs (UnmanagedType.Bool)]
bool IsValidToken (uint tk);
- uint GetNestedClassProps (uint tdNestedClass);
+ [PreserveSig]
+ uint GetNestedClassProps (uint tdNestedClass, uint* ptdEnclosingClass);
uint GetNativeCallConvFromSig (IntPtr /* void* */ pvSig, uint cbSig);
int IsGlobal (uint pd);
}
- class ModuleMetadata : IMetaDataEmit, IMetaDataImport {
+ unsafe class ModuleMetadata : IMetaDataEmit, IMetaDataImport {
readonly ModuleDefinition module;
Dictionary<uint, TypeDefinition> types;
Dictionary<uint, MethodDefinition> methods;
+ const uint S_OK = 0x00000000;
+ const uint E_FAIL = 0x80004005;
+
public ModuleMetadata (ModuleDefinition module)
{
this.module = module;
@@ -476,40 +486,22 @@ namespace Mono.Cecil.Pdb {
throw new NotImplementedException ();
}
- public uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags)
+ public uint GetTypeDefProps (uint td, char* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends)
{
TypeDefinition type;
- if (!TryGetType (td, out type)) {
- Marshal.WriteInt16 (szTypeDef, 0);
- pchTypeDef = 1;
- return 0;
- }
-
- WriteString (type.IsNested ? type.Name : type.FullName, szTypeDef, cchTypeDef, out pchTypeDef);
- WriteIntPtr (pdwTypeDefFlags, (uint) type.Attributes);
- return type.BaseType != null ? type.BaseType.MetadataToken.ToUInt32 () : 0;
- }
-
- static void WriteIntPtr (IntPtr ptr, uint value)
- {
- if (ptr == IntPtr.Zero)
- return;
+ if (!TryGetType (td, out type))
+ return E_FAIL;
- Marshal.WriteInt32 (ptr, (int) value);
- }
+ var name = type.IsNested ? type.Name : type.FullName;
- static void WriteString (string str, IntPtr buffer, uint bufferSize, out uint chars)
- {
- var length = str.Length + 1 >= bufferSize ? bufferSize - 1 : (uint) str.Length;
- chars = length + 1;
- var offset = 0;
+ WriteNameBuffer (name, szTypeDef, cchTypeDef, pchTypeDef);
- for (int i = 0; i < length; i++) {
- Marshal.WriteInt16 (buffer, offset, str [i]);
- offset += 2;
- }
+ if (pdwTypeDefFlags != null)
+ *pdwTypeDefFlags = (uint) type.Attributes;
+ if (ptkExtends != null)
+ *ptkExtends = type.BaseType != null ? type.BaseType.MetadataToken.ToUInt32 () : 0;
- Marshal.WriteInt16 (buffer, offset, 0);
+ return S_OK;
}
public uint GetInterfaceImplProps (uint iiImpl, out uint pClass)
@@ -597,22 +589,38 @@ namespace Mono.Cecil.Pdb {
throw new NotImplementedException ();
}
- public uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA)
+ public uint GetMethodProps (uint mb, uint* pClass, char* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags)
{
MethodDefinition method;
- if (!TryGetMethod (mb, out method)) {
- Marshal.WriteInt16 (szMethod, 0);
- pchMethod = 1;
- pClass = 0;
- return 0;
- }
+ if (!TryGetMethod (mb, out method))
+ return E_FAIL;
+
+ if (pClass != null)
+ *pClass = method.DeclaringType.MetadataToken.ToUInt32 ();
+
+ WriteNameBuffer (method.Name, szMethod, cchMethod, pchMethod);
- pClass = method.DeclaringType.MetadataToken.ToUInt32 ();
- WriteString (method.Name, szMethod, cchMethod, out pchMethod);
- WriteIntPtr (pdwAttr, (uint) method.Attributes);
- WriteIntPtr (pulCodeRVA, (uint) method.RVA);
+ if (pdwAttr != null)
+ *pdwAttr = (uint) method.Attributes;
+ if (pulCodeRVA != null)
+ *pulCodeRVA = (uint) method.RVA;
+ if (pdwImplFlags != null)
+ *pdwImplFlags = (uint) method.ImplAttributes;
- return (uint) method.ImplAttributes;
+ return S_OK;
+ }
+
+ static void WriteNameBuffer(string name, char* buffer, uint bufferLength, uint* actualLength)
+ {
+ var length = Math.Min (name.Length, bufferLength - 1);
+ if (actualLength != null)
+ *actualLength = (uint) length;
+
+ if (buffer != null && bufferLength > 0) {
+ for (int i = 0; i < length; i++)
+ buffer [i] = name [i];
+ buffer [length + 1] = '\0';
+ }
}
public uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob)
@@ -770,13 +778,16 @@ namespace Mono.Cecil.Pdb {
throw new NotImplementedException ();
}
- public uint GetNestedClassProps (uint tdNestedClass)
+ public uint GetNestedClassProps (uint tdNestedClass, uint* ptdEnclosingClass)
{
TypeDefinition type;
if (!TryGetType (tdNestedClass, out type))
- return 0;
+ return E_FAIL;
+
+ if (ptdEnclosingClass != null)
+ *ptdEnclosingClass = type.IsNested ? type.DeclaringType.MetadataToken.ToUInt32 () : 0;
- return type.IsNested ? type.DeclaringType.MetadataToken.ToUInt32 () : 0;
+ return S_OK;
}
public uint GetNativeCallConvFromSig (IntPtr pvSig, uint cbSig)
diff --git a/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs b/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs
index 2d6b1ba..91f1f3e 100644
--- a/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs
+++ b/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs
@@ -22,7 +22,6 @@ namespace Mono.Cecil.Pdb {
public class NativePdbReader : ISymbolReader {
- int age;
Guid guid;
readonly Disposable<Stream> pdb_file;
@@ -52,13 +51,26 @@ namespace Mono.Cecil.Pdb {
if (!header.HasEntries)
return false;
- var entry = header.GetCodeViewEntry ();
- if (entry == null)
- return false;
+ using (pdb_file) {
+ var info = PdbFile.LoadFunctions (pdb_file.value);
+
+ foreach (var entry in header.Entries) {
+ if (!IsMatchingEntry (info, entry))
+ continue;
+
+ foreach (var function in info.Functions)
+ functions.Add (function.token, function);
- var directory = entry.Directory;
+ return true;
+ }
+ }
+
+ return false;
+ }
- if (directory.Type != ImageDebugType.CodeView)
+ static bool IsMatchingEntry (PdbInfo info, ImageDebugHeaderEntry entry)
+ {
+ if (entry.Directory.Type != ImageDebugType.CodeView)
return false;
var data = entry.Data;
@@ -73,10 +85,7 @@ namespace Mono.Cecil.Pdb {
var guid_bytes = new byte [16];
Buffer.BlockCopy (data, 4, guid_bytes, 0, 16);
- this.guid = new Guid (guid_bytes);
- this.age = ReadInt32 (data, 20);
-
- return PopulateFunctions ();
+ return info.Guid == new Guid (guid_bytes);
}
static int ReadInt32 (byte [] bytes, int start)
@@ -87,20 +96,6 @@ namespace Mono.Cecil.Pdb {
| (bytes [start + 3] << 24));
}
- bool PopulateFunctions ()
- {
- using (pdb_file) {
- var info = PdbFile.LoadFunctions (pdb_file.value);
-
- if (this.guid != info.Guid)
- return false;
-
- foreach (PdbFunction function in info.Functions)
- functions.Add (function.token, function);
- }
-
- return true;
- }
public MethodDebugInformation Read (MethodDefinition method)
{
diff --git a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs
index 797f680..6f2d2fa 100644
--- a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs
+++ b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs
@@ -465,5 +465,16 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual ("temp", method.DebugInformation.Scope.Variables [0].Name);
}
+
+ [Test]
+ public void TypeNameExceedingMaxPdbPath ()
+ {
+ if (!Platform.HasNativePdbSupport)
+ Assert.Ignore ();
+
+ TestModule ("longtypename.dll", module => {
+ Assert.IsTrue (module.HasSymbols);
+ }, symbolReaderProvider: typeof (NativePdbReaderProvider), symbolWriterProvider: typeof (NativePdbWriterProvider));
+ }
}
}
diff --git a/symbols/pdb/Test/Resources/assemblies/longtypename.dll b/symbols/pdb/Test/Resources/assemblies/longtypename.dll
new file mode 100644
index 0000000..803757f
--- /dev/null
+++ b/symbols/pdb/Test/Resources/assemblies/longtypename.dll
Binary files differ
diff --git a/symbols/pdb/Test/Resources/assemblies/longtypename.pdb b/symbols/pdb/Test/Resources/assemblies/longtypename.pdb
new file mode 100644
index 0000000..0c5ca89
--- /dev/null
+++ b/symbols/pdb/Test/Resources/assemblies/longtypename.pdb
Binary files differ