Imported Upstream version 5.2.0.175

Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-06-07 13:16:24 +00:00
parent 4bdbaf4a88
commit 966bba02bb
8776 changed files with 346420 additions and 149650 deletions

5
external/linker/.editorconfig vendored Normal file
View File

@@ -0,0 +1,5 @@
# top-most EditorConfig file
root = true
[*.cs]
indent_style = tab

8
external/linker/.gitattributes vendored Normal file
View File

@@ -0,0 +1,8 @@
# Autodetect text files
* text=auto
# Declare files that will always have LF line endings on checkout.
*.cs text eol=lf
*.csproj text eol=lf
*.sln text eol=lf
*.xml text eol=lf

23
external/linker/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
.vs/
# Build results
linker/obj
linker/bin
.DS_Store
*.force
*.FileListAbsolute.txt

6
external/linker/NuGet.Config vendored Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
</packageSources>
</configuration>

5
external/linker/cecil/.editorconfig vendored Normal file
View File

@@ -0,0 +1,5 @@
# top-most EditorConfig file
root = true
[*.cs]
indent_style = tab

View File

@@ -159,17 +159,20 @@ namespace Mono.Cecil.Cil {
void ReadScope (ScopeDebugInformation scope)
{
scope.Start = new InstructionOffset (GetInstruction (scope.Start.Offset));
var start_instruction = GetInstruction (scope.Start.Offset);
if (start_instruction != null)
scope.Start = new InstructionOffset (start_instruction);
var end_instruction = GetInstruction (scope.End.Offset);
scope.End = end_instruction == null
? new InstructionOffset ()
: new InstructionOffset (end_instruction);
if (end_instruction != null)
scope.End = new InstructionOffset (end_instruction);
if (!scope.variables.IsNullOrEmpty ()) {
for (int i = 0; i < scope.variables.Count; i++) {
var variable = scope.variables [i];
variable.index = new VariableIndex (GetVariable (variable.Index));
var variable_info = scope.variables [i];
var variable = GetVariable (variable_info.Index);
if (variable != null)
variable_info.index = new VariableIndex (variable);
}
}
@@ -315,9 +318,7 @@ namespace Mono.Cecil.Cil {
switch (instruction.opcode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:
var targetInstruction = GetInstruction ((int) instruction.operand);
if (targetInstruction != null)
instruction.operand = targetInstruction;
instruction.operand = GetInstruction ((int) instruction.operand);
break;
case OperandType.InlineSwitch:
var offsets = (int []) instruction.operand;
@@ -435,13 +436,6 @@ namespace Mono.Cecil.Cil {
}
}
void Align (int align)
{
align--;
var position = Position;
Advance (((position + align) & ~align) - position);
}
public MetadataToken ReadToken ()
{
return new MetadataToken (ReadUInt32 ());

View File

@@ -27,38 +27,35 @@ namespace Mono.Cecil.Cil {
readonly RVA code_base;
internal readonly MetadataBuilder metadata;
readonly Dictionary<uint, MetadataToken> standalone_signatures;
readonly Dictionary<ByteBuffer, RVA> tiny_method_bodies;
RVA current;
MethodBody body;
public CodeWriter (MetadataBuilder metadata)
: base (0)
{
this.code_base = metadata.text_map.GetNextRVA (TextSegment.CLIHeader);
this.current = code_base;
this.metadata = metadata;
this.standalone_signatures = new Dictionary<uint, MetadataToken> ();
this.tiny_method_bodies = new Dictionary<ByteBuffer, RVA> (new ByteBufferEqualityComparer ());
}
public RVA WriteMethodBody (MethodDefinition method)
{
var rva = BeginMethod ();
RVA rva;
if (IsUnresolved (method)) {
if (method.rva == 0)
return 0;
WriteUnresolvedMethodBody (method);
rva = WriteUnresolvedMethodBody (method);
} else {
if (IsEmptyMethodBody (method.Body))
return 0;
WriteResolvedMethodBody (method);
rva = WriteResolvedMethodBody (method);
}
Align (4);
EndMethod ();
return rva;
}
@@ -73,18 +70,25 @@ namespace Mono.Cecil.Cil {
return method.HasBody && method.HasImage && method.body == null;
}
void WriteUnresolvedMethodBody (MethodDefinition method)
RVA WriteUnresolvedMethodBody (MethodDefinition method)
{
var code_reader = metadata.module.reader.code;
int code_size;
MetadataToken local_var_token;
var buffer = code_reader.PatchRawMethodBody (method, this, out code_size, out local_var_token);
var raw_body = code_reader.PatchRawMethodBody (method, this, out code_size, out local_var_token);
var fat_header = (raw_body.buffer [0] & 0x3) == 0x3;
if (fat_header)
Align (4);
WriteBytes (buffer);
var rva = BeginMethod ();
if (fat_header || !GetOrMapTinyMethodBody (raw_body, ref rva)) {
WriteBytes (raw_body);
}
if (method.debug_info == null)
return;
return rva;
var symbol_writer = metadata.symbol_writer;
if (symbol_writer != null) {
@@ -92,21 +96,38 @@ namespace Mono.Cecil.Cil {
method.debug_info.local_var_token = local_var_token;
symbol_writer.Write (method.debug_info);
}
return rva;
}
void WriteResolvedMethodBody (MethodDefinition method)
RVA WriteResolvedMethodBody(MethodDefinition method)
{
RVA rva;
body = method.Body;
ComputeHeader ();
if (RequiresFatHeader ())
if (RequiresFatHeader ()) {
Align (4);
rva = BeginMethod ();
WriteFatHeader ();
else
WriteInstructions ();
if (body.HasExceptionHandlers)
WriteExceptionHandlers ();
} else {
rva = BeginMethod ();
WriteByte ((byte) (0x2 | (body.CodeSize << 2))); // tiny
WriteInstructions ();
WriteInstructions ();
var start_position = (int) (rva - code_base);
var body_size = position - start_position;
var body_bytes = new byte [body_size];
if (body.HasExceptionHandlers)
WriteExceptionHandlers ();
Array.Copy (buffer, start_position, body_bytes, 0, body_size);
if (GetOrMapTinyMethodBody (new ByteBuffer (body_bytes), ref rva))
position = start_position;
}
var symbol_writer = metadata.symbol_writer;
if (symbol_writer != null && method.debug_info != null) {
@@ -114,6 +135,20 @@ namespace Mono.Cecil.Cil {
method.debug_info.local_var_token = body.local_var_token;
symbol_writer.Write (method.debug_info);
}
return rva;
}
bool GetOrMapTinyMethodBody (ByteBuffer body, ref RVA rva)
{
RVA existing_rva;
if (tiny_method_bodies.TryGetValue (body, out existing_rva)) {
rva = existing_rva;
return true;
}
tiny_method_bodies.Add (body, rva);
return false;
}
void WriteFatHeader ()
@@ -166,8 +201,9 @@ namespace Mono.Cecil.Cil {
return;
var operand = instruction.operand;
if (operand == null)
if (operand == null && !(operand_type == OperandType.InlineBrTarget || operand_type == OperandType.ShortInlineBrTarget)) {
throw new ArgumentException ();
}
switch (operand_type) {
case OperandType.InlineSwitch: {
@@ -179,11 +215,15 @@ namespace Mono.Cecil.Cil {
break;
}
case OperandType.ShortInlineBrTarget: {
WriteSByte ((sbyte) (GetTargetOffset (operand) - (instruction.Offset + opcode.Size + 1)));
var target = (Instruction) operand;
var offset = target != null ? GetTargetOffset (target) : body.code_size;
WriteSByte ((sbyte) (offset - (instruction.Offset + opcode.Size + 1)));
break;
}
case OperandType.InlineBrTarget: {
WriteInt32 (GetTargetOffset (operand) - (instruction.Offset + opcode.Size + 4));
var target = (Instruction) operand;
var offset = target != null ? GetTargetOffset (target) : body.code_size;
WriteInt32 (offset - (instruction.Offset + opcode.Size + 4));
break;
}
case OperandType.ShortInlineVar:
@@ -236,12 +276,8 @@ namespace Mono.Cecil.Cil {
}
}
int GetTargetOffset (object o)
int GetTargetOffset (Instruction instruction)
{
if (o is int)
return (int) o;
Instruction instruction = o as Instruction;
if (instruction == null) {
var last = body.instructions [body.instructions.size - 1];
return last.offset + last.GetSize ();
@@ -365,7 +401,7 @@ namespace Mono.Cecil.Cil {
CopyBranchStackSize (ref stack_sizes, (Instruction) instruction.operand, stack_size);
break;
case OperandType.InlineSwitch:
var targets = (Instruction[]) instruction.operand;
var targets = (Instruction []) instruction.operand;
for (int i = 0; i < targets.Length; i++)
CopyBranchStackSize (ref stack_sizes, targets [i], stack_size);
break;
@@ -604,7 +640,7 @@ namespace Mono.Cecil.Cil {
RVA BeginMethod ()
{
return current;
return (RVA)(code_base + position);
}
void WriteMetadataToken (MetadataToken token)
@@ -617,11 +653,6 @@ namespace Mono.Cecil.Cil {
align--;
WriteBytes (((position + align) & ~align) - position);
}
void EndMethod ()
{
current = (RVA) (code_base + position);
}
}
}

View File

@@ -109,7 +109,7 @@ namespace Mono.Cecil.Cil {
switch (opcode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:
AppendLabel (instruction, operand);
AppendLabel (instruction, (Instruction) operand);
break;
case OperandType.InlineSwitch:
var labels = (Instruction []) operand;
@@ -133,15 +133,10 @@ namespace Mono.Cecil.Cil {
return instruction.ToString ();
}
static void AppendLabel (StringBuilder builder, object o)
static void AppendLabel (StringBuilder builder, Instruction instruction)
{
builder.Append ("IL_");
if (o is Instruction)
builder.Append ((o as Instruction).offset.ToString ("x4"));
else if (o is int) {
builder.Append (((int)o).ToString ("x4"));
builder.Append (" (invalid)");
}
builder.Append (instruction.offset.ToString ("x4"));
}
public static Instruction Create (OpCode opcode)

View File

@@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
@@ -19,7 +20,6 @@ namespace Mono.Cecil.Cil {
public sealed class PortablePdbReaderProvider : ISymbolReaderProvider {
#if !PCL
public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
@@ -28,7 +28,6 @@ namespace Mono.Cecil.Cil {
var file = File.OpenRead (Mixin.GetPdbFileName (fileName));
return GetSymbolReader (module, Disposable.Owned (file as Stream), file.Name);
}
#endif
public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
{
@@ -61,20 +60,31 @@ namespace Mono.Cecil.Cil {
this.debug_reader = new MetadataReader (image, module, this.reader);
}
public bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header)
public ISymbolWriterProvider GetWriterProvider ()
{
return new PortablePdbWriterProvider ();
}
public bool ProcessDebugHeader (ImageDebugHeader header)
{
if (image == module.Image)
return true;
if (header.Length < 24)
var entry = header.GetCodeViewEntry ();
if (entry == null)
return false;
var magic = ReadInt32 (header, 0);
var data = entry.Data;
if (data.Length < 24)
return false;
var magic = ReadInt32 (data, 0);
if (magic != 0x53445352)
return false;
var buffer = new byte [16];
Buffer.BlockCopy (header, 4, buffer, 0, 16);
Buffer.BlockCopy (data, 4, buffer, 0, 16);
var module_guid = new Guid (buffer);
@@ -132,11 +142,80 @@ namespace Mono.Cecil.Cil {
}
}
public sealed class EmbeddedPortablePdbReaderProvider : ISymbolReaderProvider {
public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
var header = module.GetDebugHeader ();
var entry = header.GetEmbeddedPortablePdbEntry ();
if (entry == null)
throw new InvalidOperationException ();
return new EmbeddedPortablePdbReader (
(PortablePdbReader) new PortablePdbReaderProvider ().GetSymbolReader (module, GetPortablePdbStream (entry)));
}
static Stream GetPortablePdbStream (ImageDebugHeaderEntry entry)
{
var compressed_stream = new MemoryStream (entry.Data);
var reader = new BinaryStreamReader (compressed_stream);
reader.ReadInt32 (); // signature
var length = reader.ReadInt32 ();
var decompressed_stream = new MemoryStream (length);
using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
deflate_stream.CopyTo (decompressed_stream);
return decompressed_stream;
}
public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
{
throw new NotSupportedException ();
}
}
public sealed class EmbeddedPortablePdbReader : ISymbolReader
{
private readonly PortablePdbReader reader;
internal EmbeddedPortablePdbReader (PortablePdbReader reader)
{
if (reader == null)
throw new ArgumentNullException ();
this.reader = reader;
}
public ISymbolWriterProvider GetWriterProvider ()
{
return new EmbeddedPortablePdbWriterProvider ();
}
public bool ProcessDebugHeader (ImageDebugHeader header)
{
return reader.ProcessDebugHeader (header);
}
public MethodDebugInformation Read (MethodDefinition method)
{
return reader.Read (method);
}
public void Dispose ()
{
reader.Dispose ();
}
}
#if !READ_ONLY
public sealed class PortablePdbWriterProvider : ISymbolWriterProvider
{
#if !PCL
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
@@ -145,7 +224,6 @@ namespace Mono.Cecil.Cil {
var file = File.OpenWrite (Mixin.GetPdbFileName (fileName));
return GetSymbolWriter (module, Disposable.Owned (file as Stream));
}
#endif
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
{
@@ -164,7 +242,11 @@ namespace Mono.Cecil.Cil {
}
}
sealed class PortablePdbWriter : ISymbolWriter {
interface IMetadataSymbolWriter : ISymbolWriter {
void SetMetadata (MetadataBuilder metadata);
}
public sealed class PortablePdbWriter : ISymbolWriter, IMetadataSymbolWriter {
readonly MetadataBuilder pdb_metadata;
readonly ModuleDefinition module;
@@ -174,19 +256,19 @@ namespace Mono.Cecil.Cil {
bool IsEmbedded { get { return writer == null; } }
public PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module)
internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module)
{
this.pdb_metadata = pdb_metadata;
this.module = module;
}
public PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module, ImageWriter writer)
internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module, ImageWriter writer)
: this (pdb_metadata, module)
{
this.writer = writer;
}
public void SetModuleMetadata (MetadataBuilder metadata)
void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata)
{
this.module_metadata = metadata;
@@ -194,18 +276,21 @@ namespace Mono.Cecil.Cil {
this.pdb_metadata.metadata_builder = metadata;
}
public bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] header)
public ISymbolReaderProvider GetReaderProvider ()
{
if (IsEmbedded) {
directory = new ImageDebugDirectory ();
header = Empty<byte>.Array;
return false;
}
return new PortablePdbReaderProvider ();
}
directory = new ImageDebugDirectory () {
public ImageDebugHeader GetDebugHeader ()
{
if (IsEmbedded)
return new ImageDebugHeader ();
var directory = new ImageDebugDirectory () {
MajorVersion = 256,
MinorVersion = 20577,
Type = 2,
MinorVersion = 20557,
Type = ImageDebugType.CodeView,
TimeDateStamp = (int) module.timestamp,
};
var buffer = new ByteBuffer ();
@@ -219,10 +304,11 @@ namespace Mono.Cecil.Cil {
buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (writer.BaseStream.GetFileName ()));
buffer.WriteByte (0);
header = new byte [buffer.length];
Buffer.BlockCopy (buffer.buffer, 0, header, 0, buffer.length);
directory.SizeOfData = header.Length;
return true;
var data = new byte [buffer.length];
Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length);
directory.SizeOfData = data.Length;
return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data));
}
public void Write (MethodDebugInformation info)
@@ -248,13 +334,20 @@ namespace Mono.Cecil.Cil {
if (IsEmbedded)
return;
WritePdbFile ();
}
void WritePdbFile ()
{
WritePdbHeap ();
WriteTableHeap ();
writer.BuildMetadataTextMap ();
writer.WriteMetadataHeader ();
writer.WriteMetadata ();
writer.Flush ();
writer.stream.Dispose ();
}
@@ -263,7 +356,7 @@ namespace Mono.Cecil.Cil {
var pdb_heap = pdb_metadata.pdb_heap;
pdb_heap.WriteBytes (module.Mvid.ToByteArray ());
pdb_heap.WriteUInt32 (module_metadata.time_stamp);
pdb_heap.WriteUInt32 (module_metadata.timestamp);
pdb_heap.WriteUInt32 (module_metadata.entry_point.ToUInt32 ());
@@ -290,10 +383,92 @@ namespace Mono.Cecil.Cil {
void WriteTableHeap ()
{
pdb_metadata.table_heap.string_offsets = pdb_metadata.string_heap.WriteStrings ();
pdb_metadata.table_heap.ComputeTableInformations ();
pdb_metadata.table_heap.WriteTableHeap ();
}
}
public sealed class EmbeddedPortablePdbWriterProvider : ISymbolWriterProvider {
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
var stream = new MemoryStream ();
var pdb_writer = (PortablePdbWriter) new PortablePdbWriterProvider ().GetSymbolWriter (module, stream);
return new EmbeddedPortablePdbWriter (stream, pdb_writer);
}
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
{
throw new NotSupportedException ();
}
}
public sealed class EmbeddedPortablePdbWriter : ISymbolWriter, IMetadataSymbolWriter {
readonly Stream stream;
readonly PortablePdbWriter writer;
internal EmbeddedPortablePdbWriter (Stream stream, PortablePdbWriter writer)
{
this.stream = stream;
this.writer = writer;
}
public ISymbolReaderProvider GetReaderProvider ()
{
return new EmbeddedPortablePdbReaderProvider ();
}
public ImageDebugHeader GetDebugHeader ()
{
writer.Dispose ();
var directory = new ImageDebugDirectory {
Type = ImageDebugType.EmbeddedPortablePdb,
};
var data = new MemoryStream ();
var w = new BinaryStreamWriter (data);
w.WriteByte (0x4d);
w.WriteByte (0x50);
w.WriteByte (0x44);
w.WriteByte (0x42);
w.WriteInt32 ((int) stream.Length);
stream.Position = 0;
using (var compress_stream = new DeflateStream (data, CompressionMode.Compress, leaveOpen: true))
stream.CopyTo (compress_stream);
directory.SizeOfData = (int) data.Length;
return new ImageDebugHeader (new [] {
writer.GetDebugHeader ().Entries [0],
new ImageDebugHeaderEntry (directory, data.ToArray ())
});
}
public void Write (MethodDebugInformation info)
{
writer.Write (info);
}
public void Dispose ()
{
}
void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata)
{
((IMetadataSymbolWriter) writer).SetMetadata (metadata);
}
}
#endif
static class PdbGuidMapping {

View File

@@ -47,7 +47,7 @@ namespace Mono.Cecil.Cil {
}
public bool IsHidden {
get { return start_line == 0xfeefee && start_line == start_column; }
get { return start_line == 0xfeefee && start_line == end_line; }
}
public Document Document {

View File

@@ -15,21 +15,79 @@ using System.Runtime.InteropServices;
using SR = System.Reflection;
using Mono.Collections.Generic;
using Mono.Cecil.Cil;
namespace Mono.Cecil.Cil {
[StructLayout (LayoutKind.Sequential)]
public struct ImageDebugDirectory {
public const int Size = 28;
public int Characteristics;
public int TimeDateStamp;
public short MajorVersion;
public short MinorVersion;
public int Type;
public ImageDebugType Type;
public int SizeOfData;
public int AddressOfRawData;
public int PointerToRawData;
}
public enum ImageDebugType {
CodeView = 2,
Deterministic = 16,
EmbeddedPortablePdb = 17,
}
public sealed class ImageDebugHeader {
readonly ImageDebugHeaderEntry [] entries;
public bool HasEntries {
get { return !entries.IsNullOrEmpty (); }
}
public ImageDebugHeaderEntry [] Entries {
get { return entries; }
}
public ImageDebugHeader (ImageDebugHeaderEntry [] entries)
{
this.entries = entries ?? Empty<ImageDebugHeaderEntry>.Array;
}
public ImageDebugHeader ()
: this (Empty<ImageDebugHeaderEntry>.Array)
{
}
public ImageDebugHeader (ImageDebugHeaderEntry entry)
: this (new [] { entry })
{
}
}
public sealed class ImageDebugHeaderEntry {
ImageDebugDirectory directory;
readonly byte [] data;
public ImageDebugDirectory Directory {
get { return directory; }
internal set { directory = value; }
}
public byte [] Data {
get { return data; }
}
public ImageDebugHeaderEntry (ImageDebugDirectory directory, byte [] data)
{
this.directory = directory;
this.data = data ?? Empty<byte>.Array;
}
}
public sealed class ScopeDebugInformation : DebugInformation {
internal InstructionOffset start;
@@ -364,7 +422,7 @@ namespace Mono.Cecil.Cil {
}
}
interface ICustomDebugInformationProvider : IMetadataTokenProvider {
public interface ICustomDebugInformationProvider : IMetadataTokenProvider {
bool HasCustomDebugInformations { get; }
Collection<CustomDebugInformation> CustomDebugInformations { get; }
}
@@ -381,8 +439,10 @@ namespace Mono.Cecil.Cil {
Guid identifier;
public Guid Identifier { get { return identifier; } }
public Guid Identifier {
get { return identifier; }
}
public abstract CustomDebugInformationKind Kind { get; }
internal CustomDebugInformation (Guid identifier)
@@ -454,6 +514,12 @@ namespace Mono.Cecil.Cil {
{
this.catch_handler = new InstructionOffset (catchHandler);
}
public AsyncMethodBodyDebugInformation ()
: base (KindIdentifier)
{
this.catch_handler = new InstructionOffset (-1);
}
}
public sealed class StateMachineScopeDebugInformation : CustomDebugInformation {
@@ -488,7 +554,7 @@ namespace Mono.Cecil.Cil {
: base (KindIdentifier)
{
this.start = new InstructionOffset (start);
this.end = new InstructionOffset (end);
this.end = end != null ? new InstructionOffset (end) : new InstructionOffset ();
}
}
@@ -618,28 +684,85 @@ namespace Mono.Cecil.Cil {
public interface ISymbolReader : IDisposable {
bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header);
ISymbolWriterProvider GetWriterProvider ();
bool ProcessDebugHeader (ImageDebugHeader header);
MethodDebugInformation Read (MethodDefinition method);
}
public interface ISymbolReaderProvider {
#if !PCL
ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName);
#endif
ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream);
}
#if !PCL
public class DefaultSymbolReaderProvider : ISymbolReaderProvider {
readonly bool throw_if_no_symbol;
public DefaultSymbolReaderProvider ()
: this (throwIfNoSymbol: true)
{
}
public DefaultSymbolReaderProvider (bool throwIfNoSymbol)
{
throw_if_no_symbol = throwIfNoSymbol;
}
public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
{
if (module.Image.HasDebugTables ())
return null;
if (module.HasDebugHeader) {
var header = module.GetDebugHeader ();
var entry = header.GetEmbeddedPortablePdbEntry ();
if (entry != null)
return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName);
}
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 ();
}
}
enum SymbolKind {
NativePdb,
PortablePdb,
EmbeddedPortablePdb,
Mdb,
}
static class SymbolProvider {
static readonly string symbol_kind = Type.GetType ("Mono.Runtime") != null ? "Mdb" : "Pdb";
static SR.AssemblyName GetPlatformSymbolAssemblyName ()
static SR.AssemblyName GetSymbolAssemblyName (SymbolKind kind)
{
var cecil_name = typeof (SymbolProvider).GetAssembly ().GetName ();
if (kind == SymbolKind.PortablePdb)
throw new ArgumentException ();
var suffix = GetSymbolNamespace (kind);
var cecil_name = typeof (SymbolProvider).Assembly ().GetName ();
var name = new SR.AssemblyName {
Name = "Mono.Cecil." + symbol_kind,
Name = cecil_name.Name + "." + suffix,
Version = cecil_name.Version,
};
@@ -648,13 +771,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,70 +794,122 @@ 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 ();
if (kind == SymbolKind.EmbeddedPortablePdb)
return new EmbeddedPortablePdbReaderProvider ();
var type = GetPlatformType (GetProviderTypeName ("ReaderProvider"));
var provider_name = GetSymbolTypeName (kind, "ReaderProvider");
var type = GetSymbolType (kind, provider_name);
if (type == null)
return null;
throw new TypeLoadException ("Could not find symbol provider type " + provider_name);
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;
return "Mono.Cecil" + "." + GetSymbolNamespace (kind) + "." + kind + name;
}
#if !READ_ONLY
static ISymbolWriterProvider writer_provider;
public static ISymbolWriterProvider GetPlatformWriterProvider ()
static string GetSymbolNamespace (SymbolKind kind)
{
if (writer_provider != null)
return writer_provider;
if (kind == SymbolKind.PortablePdb || kind == SymbolKind.EmbeddedPortablePdb)
return "Cil";
if (kind == SymbolKind.NativePdb)
return "Pdb";
if (kind == SymbolKind.Mdb)
return "Mdb";
var type = GetPlatformType (GetProviderTypeName ("WriterProvider"));
if (type == null)
return null;
return writer_provider = (ISymbolWriterProvider) Activator.CreateInstance (type);
throw new ArgumentException ();
}
#endif
}
#endif
#if !READ_ONLY
public interface ISymbolWriter : IDisposable {
bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] header);
ISymbolReaderProvider GetReaderProvider ();
ImageDebugHeader GetDebugHeader ();
void Write (MethodDebugInformation info);
}
public interface ISymbolWriterProvider {
#if !PCL
ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName);
#endif
ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream);
}
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;
return reader.GetWriterProvider ().GetSymbolWriter (module, fileName);
}
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
{
throw new NotSupportedException ();
}
}
#endif
}
#if !PCL
namespace Mono.Cecil {
static partial class Mixin {
public static ImageDebugHeaderEntry GetCodeViewEntry (this ImageDebugHeader header)
{
return GetEntry (header, ImageDebugType.CodeView);
}
public static ImageDebugHeaderEntry GetDeterministicEntry (this ImageDebugHeader header)
{
return GetEntry (header, ImageDebugType.Deterministic);
}
public static ImageDebugHeader AddDeterministicEntry (this ImageDebugHeader header)
{
var entry = new ImageDebugHeaderEntry (new ImageDebugDirectory { Type = ImageDebugType.Deterministic }, Empty<byte>.Array);
if (header == null)
return new ImageDebugHeader (entry);
var entries = new ImageDebugHeaderEntry [header.Entries.Length + 1];
Array.Copy (header.Entries, entries, header.Entries.Length);
entries [entries.Length - 1] = entry;
return new ImageDebugHeader (entries);
}
public static ImageDebugHeaderEntry GetEmbeddedPortablePdbEntry (this ImageDebugHeader header)
{
return GetEntry (header, ImageDebugType.EmbeddedPortablePdb);
}
private static ImageDebugHeaderEntry GetEntry (this ImageDebugHeader header, ImageDebugType type)
{
if (!header.HasEntries)
return null;
for (var i = 0; i < header.Entries.Length; i++) {
var entry = header.Entries [i];
if (entry.Directory.Type == type)
return entry;
}
return null;
}
public static string GetPdbFileName (string assemblyFileName)
{
return Path.ChangeExtension (assemblyFileName, ".pdb");
@@ -744,7 +919,24 @@ 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;
}
}
}
}
#endif

View File

@@ -25,7 +25,8 @@ namespace Mono.Cecil.Metadata {
readonly ModuleDefinition module;
readonly MetadataBuilder metadata;
internal MetadataTable [] tables = new MetadataTable [Mixin.TableCount];
readonly internal TableInformation [] table_infos = new TableInformation [Mixin.TableCount];
readonly internal MetadataTable [] tables = new MetadataTable [Mixin.TableCount];
bool large_string;
bool large_blob;
@@ -34,6 +35,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; }
}
@@ -48,8 +51,7 @@ namespace Mono.Cecil.Metadata {
int GetTableLength (Table table)
{
var md_table = tables [(int) table];
return md_table != null ? md_table.Length : 0;
return (int) table_infos [(int) table].Length;
}
public TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
@@ -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)
@@ -96,8 +98,7 @@ namespace Mono.Cecil.Metadata {
public void WriteRID (uint rid, Table table)
{
var md_table = tables [(int) table];
WriteBySize (rid, md_table == null ? false : md_table.IsLarge);
WriteBySize (rid, table_infos [(int) table].IsLarge);
}
int GetCodedIndexSize (CodedIndex coded_index)
@@ -167,6 +168,24 @@ namespace Mono.Cecil.Metadata {
return valid;
}
public void ComputeTableInformations ()
{
if (metadata.metadata_builder != null)
ComputeTableInformations (metadata.metadata_builder.table_heap);
ComputeTableInformations (metadata.table_heap);
}
void ComputeTableInformations (TableHeapBuffer table_heap)
{
var tables = table_heap.tables;
for (int i = 0; i < tables.Length; i++) {
var table = tables [i];
if (table != null && table.Length > 0)
table_infos [i].Length = (uint) table.Length;
}
}
byte GetHeapSizes ()
{
byte heap_sizes = 0;
@@ -299,7 +318,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 +330,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 +448,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);

View File

@@ -14,7 +14,7 @@ namespace Mono.Cecil.Metadata {
public int IndexSize;
internal byte [] data;
readonly internal byte [] data;
protected Heap (byte [] data)
{

View File

@@ -74,6 +74,10 @@ namespace Mono.Cecil.Metadata {
public uint Offset;
public uint Length;
public uint RowSize;
public bool IsLarge {
get { return Length > ushort.MaxValue; }
}
}
sealed class TableHeap : Heap {

View File

@@ -39,6 +39,13 @@ namespace Mono.Cecil.PE {
BaseStream.Seek (position, SeekOrigin.Begin);
}
public void Align (int align)
{
align--;
var position = Position;
Advance (((position + align) & ~align) - position);
}
public DataDirectory ReadDataDirectory ()
{
return new DataDirectory (ReadUInt32 (), ReadUInt32 ());

View File

@@ -17,6 +17,11 @@ namespace Mono.Cecil.PE {
class BinaryStreamWriter : BinaryWriter {
public int Position {
get { return (int) BaseStream.Position; }
set { BaseStream.Position = value; }
}
public BinaryStreamWriter (Stream stream)
: base (stream)
{
@@ -72,6 +77,16 @@ namespace Mono.Cecil.PE {
{
BaseStream.Seek (bytes, SeekOrigin.Current);
}
public void Align (int align)
{
align--;
var position = Position;
var bytes = ((position + align) & ~align) - position;
for (int i = 0; i < bytes; i++)
WriteByte (0);
}
}
}

View File

@@ -32,29 +32,17 @@ namespace Mono.Cecil.PE {
public int GetHashCode (ByteBuffer buffer)
{
#if !BYTE_BUFFER_WELL_DISTRIBUTED_HASH
var hash = 0;
// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
const int fnv_offset_bias = unchecked((int)2166136261);
const int fnv_prime = 16777619;
var hash_code = fnv_offset_bias;
var bytes = buffer.buffer;
for (int i = 0; i < buffer.length; i++)
hash = (hash * 37) ^ bytes [i];
hash_code = unchecked ((hash_code ^ bytes [i]) * fnv_prime);
return hash;
#else
const uint p = 16777619;
uint hash = 2166136261;
var bytes = buffer.buffer;
for (int i = 0; i < buffer.length; i++)
hash = (hash ^ bytes [i]) * p;
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
return (int) hash;
#endif
}
return hash_code;
}
}
}

View File

@@ -13,6 +13,7 @@ using System.IO;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
using RVA = System.UInt32;
@@ -28,11 +29,14 @@ namespace Mono.Cecil.PE {
public TargetArchitecture Architecture;
public ModuleCharacteristics Characteristics;
public ImageDebugHeader DebugHeader;
public Section [] Sections;
public Section MetadataSection;
public uint EntryPointToken;
public uint Timestamp;
public ModuleAttributes Attributes;
public DataDirectory Debug;
@@ -143,33 +147,6 @@ namespace Mono.Cecil.PE {
}
}
public ImageDebugDirectory GetDebugHeader (out byte [] header)
{
var reader = GetReaderAt (Debug.VirtualAddress);
if (reader == null) {
header = Empty<byte>.Array;
return new ImageDebugDirectory ();
}
var directory = new ImageDebugDirectory {
Characteristics = reader.ReadInt32 (),
TimeDateStamp = reader.ReadInt32 (),
MajorVersion = reader.ReadInt16 (),
MinorVersion = reader.ReadInt16 (),
Type = reader.ReadInt32 (),
SizeOfData = reader.ReadInt32 (),
AddressOfRawData = reader.ReadInt32 (),
PointerToRawData = reader.ReadInt32 (),
};
reader = GetReaderAt ((uint) directory.AddressOfRawData);
header = reader != null
? reader.ReadBytes (directory.SizeOfData)
: Empty<byte>.Array;
return directory;
}
public bool HasDebugTables ()
{
return HasTable (Table.Document)

View File

@@ -11,7 +11,9 @@
using System;
using System.IO;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
using RVA = System.UInt32;
@@ -70,10 +72,11 @@ namespace Mono.Cecil.PE {
ushort sections = ReadUInt16 ();
// TimeDateStamp 4
image.Timestamp = ReadUInt32 ();
// PointerToSymbolTable 4
// NumberOfSymbols 4
// OptionalHeaderSize 2
Advance (14);
Advance (10);
// Characteristics 2
ushort characteristics = ReadUInt16 ();
@@ -83,6 +86,7 @@ namespace Mono.Cecil.PE {
ReadSections (sections);
ReadCLIHeader ();
ReadMetadata ();
ReadDebugHeader ();
image.Kind = GetModuleKind (characteristics, subsystem);
image.Characteristics = (ModuleCharacteristics) dll_characteristics;
@@ -90,19 +94,7 @@ namespace Mono.Cecil.PE {
TargetArchitecture ReadArchitecture ()
{
var machine = ReadUInt16 ();
switch (machine) {
case 0x014c:
return TargetArchitecture.I386;
case 0x8664:
return TargetArchitecture.AMD64;
case 0x0200:
return TargetArchitecture.IA64;
case 0x01c4:
return TargetArchitecture.ARMv7;
}
throw new NotSupportedException ();
return (TargetArchitecture) ReadUInt16 ();
}
static ModuleKind GetModuleKind (ushort characteristics, ushort subsystem)
@@ -318,11 +310,52 @@ namespace Mono.Cecil.PE {
for (int i = 0; i < streams; i++)
ReadMetadataStream (section);
if (image.TableHeap != null)
ReadTableHeap ();
if (image.PdbHeap != null)
ReadPdbHeap ();
if (image.TableHeap != null)
ReadTableHeap ();
}
void ReadDebugHeader ()
{
if (image.Debug.IsZero) {
image.DebugHeader = new ImageDebugHeader (Empty<ImageDebugHeaderEntry>.Array);
return;
}
MoveTo (image.Debug);
var entries = new ImageDebugHeaderEntry [(int) image.Debug.Size / ImageDebugDirectory.Size];
for (int i = 0; i < entries.Length; i++) {
var directory = new ImageDebugDirectory {
Characteristics = ReadInt32 (),
TimeDateStamp = ReadInt32 (),
MajorVersion = ReadInt16 (),
MinorVersion = ReadInt16 (),
Type = (ImageDebugType) ReadInt32 (),
SizeOfData = ReadInt32 (),
AddressOfRawData = ReadInt32 (),
PointerToRawData = ReadInt32 (),
};
if (directory.AddressOfRawData == 0) {
entries [i] = new ImageDebugHeaderEntry (directory, Empty<byte>.Array);
continue;
}
var position = Position;
try {
MoveTo ((uint) directory.PointerToRawData);
var data = ReadBytes (directory.SizeOfData);
entries [i] = new ImageDebugHeaderEntry (directory, data);
} finally {
Position = position;
}
}
image.DebugHeader = new ImageDebugHeader (entries);
}
void ReadMetadataStream (Section section)
@@ -393,6 +426,15 @@ namespace Mono.Cecil.PE {
// Sorted 8
heap.Sorted = ReadInt64 ();
if (image.PdbHeap != null) {
for (int i = 0; i < Mixin.TableCount; i++) {
if (!image.PdbHeap.HasTable ((Table) i))
continue;
heap.Tables [i].Length = image.PdbHeap.TypeSystemTableRows [i];
}
}
for (int i = 0; i < Mixin.TableCount; i++) {
if (!heap.HasTable ((Table) i))
continue;
@@ -430,7 +472,7 @@ namespace Mono.Cecil.PE {
uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header
int stridx_size = image.StringHeap.IndexSize;
int guididx_size = image.GuidHeap.IndexSize;
int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2;
int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2;
var heap = image.TableHeap;

View File

@@ -29,8 +29,7 @@ namespace Mono.Cecil.PE {
readonly string runtime_version;
ImageDebugDirectory debug_directory;
byte [] debug_data;
ImageDebugHeader debug_header;
ByteBuffer win32_resources;
@@ -62,7 +61,7 @@ namespace Mono.Cecil.PE {
if (metadataOnly)
return;
this.pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64;
this.pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64 || module.Architecture == TargetArchitecture.ARM64;
this.has_reloc = module.Architecture == TargetArchitecture.I386;
this.GetDebugHeader ();
this.GetWin32Resources ();
@@ -73,11 +72,17 @@ namespace Mono.Cecil.PE {
void GetDebugHeader ()
{
var symbol_writer = metadata.symbol_writer;
if (symbol_writer == null)
return;
if (symbol_writer != null)
debug_header = symbol_writer.GetDebugHeader ();
if (!symbol_writer.GetDebugHeader (out debug_directory, out debug_data))
debug_data = Empty<byte>.Array;
if (module.HasDebugHeader) {
var header = module.GetDebugHeader ();
var deterministic = header.GetDeterministicEntry ();
if (deterministic == null)
return;
debug_header = debug_header.AddDeterministicEntry ();
}
}
void GetWin32Resources ()
@@ -108,7 +113,7 @@ namespace Mono.Cecil.PE {
public static ImageWriter CreateDebugWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream)
{
var writer = new ImageWriter (module, "PDB V1.0", metadata, stream, metadataOnly: true);
var writer = new ImageWriter (module, "PDB v1.0", metadata, stream, metadataOnly: true);
var length = metadata.text_map.GetLength ();
writer.text = new Section { SizeOfRawData = length, VirtualSize = length };
return writer;
@@ -194,7 +199,7 @@ namespace Mono.Cecil.PE {
WriteUInt32 (0x00004550); // Magic
WriteUInt16 (GetMachine ()); // Machine
WriteUInt16 (sections); // NumberOfSections
WriteUInt32 (metadata.time_stamp);
WriteUInt32 (metadata.timestamp);
WriteUInt32 (0); // PointerToSymbolTable
WriteUInt32 (0); // NumberOfSymbols
WriteUInt16 (SizeOfOptionalHeader ()); // SizeOfOptionalHeader
@@ -308,7 +313,7 @@ namespace Mono.Cecil.PE {
if (text_map.GetLength (TextSegment.DebugDirectory) > 0) {
WriteUInt32 (text_map.GetRVA (TextSegment.DebugDirectory));
WriteUInt32 (28u);
WriteUInt32 ((uint) (debug_header.Entries.Length * ImageDebugDirectory.Size));
} else
WriteZeroDataDirectory ();
@@ -526,7 +531,7 @@ namespace Mono.Cecil.PE {
1 // #~
+ 1 // #Strings
+ (metadata.user_string_heap.IsEmpty ? 0 : 1) // #US
+ 1 // GUID
+ (metadata.guid_heap.IsEmpty ? 0 : 1) // GUID
+ (metadata.blob_heap.IsEmpty ? 0 : 1)
+ (metadata.pdb_heap == null ? 0 : 1)); // #Blob
}
@@ -588,16 +593,27 @@ namespace Mono.Cecil.PE {
void WriteDebugDirectory ()
{
WriteInt32 (debug_directory.Characteristics);
WriteUInt32 (metadata.time_stamp);
WriteInt16 (debug_directory.MajorVersion);
WriteInt16 (debug_directory.MinorVersion);
WriteInt32 (debug_directory.Type);
WriteInt32 (debug_directory.SizeOfData);
WriteInt32 (debug_directory.AddressOfRawData);
WriteInt32 ((int) BaseStream.Position + 4);
var data_start = (int) BaseStream.Position + (debug_header.Entries.Length * ImageDebugDirectory.Size);
WriteBytes (debug_data);
for (var i = 0; i < debug_header.Entries.Length; i++) {
var entry = debug_header.Entries [i];
var directory = entry.Directory;
WriteInt32 (directory.Characteristics);
WriteInt32 (directory.TimeDateStamp);
WriteInt16 (directory.MajorVersion);
WriteInt16 (directory.MinorVersion);
WriteInt32 ((int) directory.Type);
WriteInt32 (directory.SizeOfData);
WriteInt32 (directory.AddressOfRawData);
WriteInt32 (data_start);
data_start += entry.Data.Length;
}
for (var i = 0; i < debug_header.Entries.Length; i++) {
var entry = debug_header.Entries [i];
WriteBytes (entry.Data);
}
}
void WriteImportDirectory ()
@@ -678,6 +694,7 @@ namespace Mono.Cecil.PE {
WriteRsrc ();
if (reloc != null)
WriteReloc ();
Flush ();
}
void BuildTextMap ()
@@ -694,11 +711,23 @@ namespace Mono.Cecil.PE {
BuildMetadataTextMap ();
int debug_dir_len = 0;
if (!debug_data.IsNullOrEmpty ()) {
const int debug_dir_header_len = 28;
if (debug_header != null && debug_header.HasEntries) {
var directories_len = debug_header.Entries.Length * ImageDebugDirectory.Size;
var data_address = (int) map.GetNextRVA (TextSegment.BlobHeap) + directories_len;
var data_len = 0;
debug_directory.AddressOfRawData = (int) map.GetNextRVA (TextSegment.BlobHeap) + debug_dir_header_len;
debug_dir_len = debug_data.Length + debug_dir_header_len;
for (var i = 0; i < debug_header.Entries.Length; i++) {
var entry = debug_header.Entries [i];
var directory = entry.Directory;
directory.AddressOfRawData = entry.Data.Length == 0 ? 0 : data_address;
entry.Directory = directory;
data_len += entry.Data.Length;
data_address += data_len;
}
debug_dir_len = directories_len + data_len;
}
map.AddMap (TextSegment.DebugDirectory, debug_dir_len, 4);

Some files were not shown because too many files have changed in this diff Show More