diff options
author | Aleksey Kliger (λgeek) <alklig@microsoft.com> | 2020-01-03 18:42:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-03 18:42:44 +0300 |
commit | 07fee8a91dbc172bacded9d2c7f7d158eb7c50f1 (patch) | |
tree | 1a6e03469830b28a4515bf532553820a68b085ae /mcs/class/PEAPI | |
parent | 22afdb80e1b1921a66cb30c2a885bf0041cf67f1 (diff) |
[metadata] Size 0 Blob heap is ok when resolving assembly refs (#18313)
* [metadata] Size 0 Blob heap is ok when resolving assembly refs
Sometimes ILasm can produce images with a Blob heap of size 0. In cases where
we're loading assembly references from such an image, the hash (which is
optional) can be at index = 0 and the Blob heap size is also 0.
Also: add the hash value to the output of `monodis --assemblyref`
* [metadata] Add a separate assertion for the index == size == 0 case
And a comment explaining how it is likely to be triggered. If the assembly is
reasonable the caller of mono_metadata_blob_heap should be updated to use
mono_metadata_blob_heap_null_ok instead
* [bcl] Allow Mono's ILASM to produce a size 0 Blob heap
ECMA 335 II.24.2.4 says that the user string and blob heaps should have an
entry at index 0 consisting of the single byte 0. However .NET Framework (and
.NET Core) ilasm will entirely omit the Blob heap (that is, create a blob heap
entry of size 0) if it is not needed. This PR changes Mono's ILASM to emit the
initial byte on demand only if one of the MetaDataStream.Add() methods is
called. Otherwise we will also emit a stream of size 0.
This is needed to compile some test cases.
* [tests] Add regression test for loading assemblies with size 0 Blob heap
Depends on ILASM that can emit a size 0 Blob heap
Diffstat (limited to 'mcs/class/PEAPI')
-rw-r--r-- | mcs/class/PEAPI/Metadata.cs | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/mcs/class/PEAPI/Metadata.cs b/mcs/class/PEAPI/Metadata.cs index 222ece4633a..98e81a42aed 100644 --- a/mcs/class/PEAPI/Metadata.cs +++ b/mcs/class/PEAPI/Metadata.cs @@ -5658,21 +5658,30 @@ namespace PEAPI { char[] name; Hashtable htable = new Hashtable(); Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ()); + bool addInitByte = false; + bool initByteAdded = false; internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream()) { - if (addInitByte) { Write((byte)0); size = 1; } + this.addInitByte = addInitByte; this.name = name; sizeOfHeader = StreamHeaderSize + (uint)name.Length; } internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc) { - if (addInitByte) { Write((byte)0); size = 1; } + this.addInitByte = addInitByte; this.name = name; sizeOfHeader = StreamHeaderSize + (uint)name.Length; } + void AddInitByte () { + if (addInitByte && !initByteAdded) { + Write((byte)0); + size += 1; + initByteAdded = true; + } + } public uint Start { get { return start; } set { start = value; } @@ -5706,6 +5715,7 @@ namespace PEAPI { internal uint Add(string str, bool prependSize) { + AddInitByte (); Object val = htable[str]; uint index = 0; if (val == null) { @@ -5723,6 +5733,7 @@ namespace PEAPI { } internal uint Add (byte[] str, bool prependSize) { + AddInitByte (); Object val = btable [str]; uint index = 0; if (val == null) { @@ -5740,6 +5751,7 @@ namespace PEAPI { internal uint Add(Guid guid, bool prependSize) { + AddInitByte (); byte [] b = guid.ToByteArray (); if (prependSize) CompressNum ((uint) b.Length); Write(guid.ToByteArray()); @@ -5749,6 +5761,7 @@ namespace PEAPI { internal uint Add(byte[] blob) { + AddInitByte (); uint ix = size; CompressNum((uint)blob.Length); Write(blob); @@ -5758,6 +5771,7 @@ namespace PEAPI { internal uint Add(byte val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (1); Write(val); @@ -5767,6 +5781,7 @@ namespace PEAPI { internal uint Add(sbyte val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (1); Write(val); @@ -5776,6 +5791,7 @@ namespace PEAPI { internal uint Add(ushort val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (2); Write(val); @@ -5785,6 +5801,7 @@ namespace PEAPI { internal uint Add(short val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (2); Write(val); @@ -5794,6 +5811,7 @@ namespace PEAPI { internal uint Add(uint val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (4); Write(val); @@ -5803,6 +5821,7 @@ namespace PEAPI { internal uint Add(int val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (4); Write (val); @@ -5812,6 +5831,7 @@ namespace PEAPI { internal uint Add(ulong val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (8); Write(val); @@ -5821,6 +5841,7 @@ namespace PEAPI { internal uint Add(long val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (8); Write(val); @@ -5830,6 +5851,7 @@ namespace PEAPI { internal uint Add(float val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (4); Write(val); @@ -5839,6 +5861,7 @@ namespace PEAPI { internal uint Add(double val, bool prependSize) { + AddInitByte (); uint ix = size; if (prependSize) CompressNum (8); Write(val); |