diff options
author | David Wrighton <davidwr@microsoft.com> | 2022-01-20 02:05:08 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-20 02:05:08 +0300 |
commit | a56b5bda0ca83789e87bf9d34fc0a9e8d2148115 (patch) | |
tree | 19a86c4489f694025be31b28ecdf88063fa67aee /Test/Mono.Cecil.Tests | |
parent | 75372c781ee228c11406c86751d75a9d27fea291 (diff) |
FieldRVA alignment (#817)
* FieldRVA alignment
In support of dotnet/runtime#60948 the linker (an assembly rewriter) will need to be able to preserve the alignment of RVA based fields which are to be used to create the data for `CreateSpan<T>` records
This is implemented by adding a concept that RVA fields detect their required alignment by examining the PackingSize of the type of the field (if the field type is defined locally in the module)
* Update Mono.Cecil.Metadata/Buffers.cs
Co-authored-by: Aaron Robinson <arobins@microsoft.com>
* Enhace logic used to ensure type providing PackingSize is local to the module.
Co-authored-by: Aaron Robinson <arobins@microsoft.com>
Diffstat (limited to 'Test/Mono.Cecil.Tests')
-rw-r--r-- | Test/Mono.Cecil.Tests/FieldTests.cs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/Test/Mono.Cecil.Tests/FieldTests.cs b/Test/Mono.Cecil.Tests/FieldTests.cs index 4f575de..93ed350 100644 --- a/Test/Mono.Cecil.Tests/FieldTests.cs +++ b/Test/Mono.Cecil.Tests/FieldTests.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Mono.Cecil.PE; @@ -133,6 +134,49 @@ namespace Mono.Cecil.Tests { }); } + int AlignmentOfInteger(int input) + { + if (input == 0) + return 0x40000000; + if (input < 0) + Assert.Fail (); + int alignment = 1; + while ((input & alignment) == 0) + alignment *= 2; + + return alignment; + } + + [Test] + public void FieldRVAAlignment () + { + TestIL ("FieldRVAAlignment.il", ilmodule => { + + var path = Path.GetTempFileName (); + + ilmodule.Write (path); + + using (var module = ModuleDefinition.ReadModule (path, new ReaderParameters { ReadWrite = true })) { + var priv_impl = GetPrivateImplementationType (module); + Assert.IsNotNull (priv_impl); + + Assert.AreEqual (6, priv_impl.Fields.Count); + + foreach (var field in priv_impl.Fields) + { + Assert.IsNotNull (field); + + Assert.AreNotEqual (0, field.RVA); + Assert.IsNotNull (field.InitialValue); + + int rvaAlignment = AlignmentOfInteger (field.RVA); + int desiredAlignment = Math.Min(8, AlignmentOfInteger (field.InitialValue.Length)); + Assert.GreaterOrEqual (rvaAlignment, desiredAlignment); + } + } + }); + } + [Test] public void GenericFieldDefinition () { |