Skip to content

Commit af10ce9

Browse files
authored
Fix RVA field alignment (#55)
This ensures that section starts are aligned by adjusting the previous Range's length to ensure the computed start of a new Range meets the alignment requirements. It was done this way rather than just computing an aligned start for the new Range, because the TextMap assumes that the Ranges are contiguous - see for example GetNextRVA.
1 parent 9b85631 commit af10ce9

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

Mono.Cecil.PE/TextMap.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//
1010

1111
using System;
12+
using System.Diagnostics;
1213

1314
using RVA = System.UInt32;
1415

@@ -47,11 +48,31 @@ public void AddMap (TextSegment segment, int length)
4748
map [(int) segment] = new Range (GetStart (segment), (uint) length);
4849
}
4950

50-
public void AddMap (TextSegment segment, int length, int align)
51+
uint AlignUp (uint value, uint align)
5152
{
5253
align--;
54+
return (value + align) & ~align;
55+
}
5356

54-
AddMap (segment, (length + align) & ~align);
57+
public void AddMap (TextSegment segment, int length, int align)
58+
{
59+
var index = (int) segment;
60+
uint start;
61+
if (index != 0) {
62+
// Align up the previous segment's length so that the new
63+
// segment's start will be aligned.
64+
index--;
65+
Range previous = map [index];
66+
start = AlignUp (previous.Start + previous.Length, (uint) align);
67+
map [index].Length = start - previous.Start;
68+
} else {
69+
start = ImageWriter.text_rva;
70+
// Should already be aligned.
71+
Debug.Assert (start == AlignUp (start, (uint) align));
72+
}
73+
Debug.Assert (start == GetStart (segment));
74+
75+
map [(int) segment] = new Range (start, (uint) length);
5576
}
5677

5778
public void AddMap (TextSegment segment, Range range)

Test/Mono.Cecil.Tests/FieldTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public void FieldRVAAlignment ()
160160
var priv_impl = GetPrivateImplementationType (module);
161161
Assert.IsNotNull (priv_impl);
162162

163-
Assert.AreEqual (6, priv_impl.Fields.Count);
163+
Assert.AreEqual (8, priv_impl.Fields.Count);
164164

165165
foreach (var field in priv_impl.Fields)
166166
{
@@ -170,7 +170,8 @@ public void FieldRVAAlignment ()
170170
Assert.IsNotNull (field.InitialValue);
171171

172172
int rvaAlignment = AlignmentOfInteger (field.RVA);
173-
int desiredAlignment = Math.Min(8, AlignmentOfInteger (field.InitialValue.Length));
173+
var fieldType = field.FieldType.Resolve ();
174+
int desiredAlignment = fieldType.PackingSize;
174175
Assert.GreaterOrEqual (rvaAlignment, desiredAlignment);
175176
}
176177
}

Test/Resources/il/FieldRVAAlignment.il

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,22 @@
4646
.size 6
4747
} // end of class '__StaticArrayInitTypeSize=6'
4848

49+
.class explicit ansi sealed nested private '__StaticArrayInitTypeSize=4Align=32'
50+
extends [mscorlib]System.ValueType
51+
{
52+
.pack 32
53+
.size 4
54+
}
55+
4956
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=3' '$$method0x6000001-1' at I_000020F0
5057
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=20' '$$method0x6000001-2' at I_000020F8
5158
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=5' '$$method0x6000001-3' at I_00002108
5259
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=20' '$$method0x6000001-4' at I_00002110
5360
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=6' '$$method0x6000001-5' at I_00002120
5461
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=16' '$$method0x6000001-6' at I_00002130
62+
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=3' 'separator' at I_00002140
63+
.field static assembly valuetype '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'/'__StaticArrayInitTypeSize=4Align=32' '32_align' at I_00002150
64+
5565
} // end of class '<PrivateImplementationDetails>{9B33BB20-87EF-4094-9948-34882DB2F001}'
5666

5767

@@ -69,3 +79,7 @@
6979
08 00 0C 00 0D 00)
7080
.data cil I_00002130 = bytearray (
7181
01 00 00 00 02 00 00 00 03 00 00 00 05 00 00 00)
82+
.data cil I_00002140 = bytearray (
83+
01 02 03)
84+
.data cil I_00002150 = bytearray (
85+
01 02 03 04)

0 commit comments

Comments
 (0)