-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[question] crossgen2 generates misaligned relocations #96066
Comments
Where do you see PadAlignment only used for Windows and not for other other platforms? |
The misaligned relocations should be produced for 32-bit x86 only. If you see misaligned relocations on other platforms, it is most likely a bug. |
@jkotas > Where do you see PadAlignment only used for Windows and not for other other platforms? I see it in source code:
|
The Win32Resource format is used as part of R2R format on all platforms today. This code is not Windows specific. This padding for alignment is part of Win32Resource format spec. Is there a specific place where you see misaligned relocations that are causing problems for you? |
We do not have any crashes caused by misalignment. During work on crossgen2 for riscv64 #95188 we found relocations are not naturally aligned and same was for arm64. Inserted alignment warnings in methods
and 4-byte value is not naturally aligned:
Relocation type print and alignment warning patchdiff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs
index 3762d1bd68f..1a716687232 100644
--- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs
+++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs
@@ -85,18 +85,24 @@ public void EmitByte(byte emit)
public void EmitShort(short emit)
{
+ AssertAlignment(sizeof(short));
+
EmitByte((byte)(emit & 0xFF));
EmitByte((byte)((emit >> 8) & 0xFF));
}
public void EmitUShort(ushort emit)
{
+ AssertAlignment(sizeof(ushort));
+
EmitByte((byte)(emit & 0xFF));
EmitByte((byte)((emit >> 8) & 0xFF));
}
public void EmitInt(int emit)
{
+ AssertAlignment(sizeof(int));
+
EmitByte((byte)(emit & 0xFF));
EmitByte((byte)((emit >> 8) & 0xFF));
EmitByte((byte)((emit >> 16) & 0xFF));
@@ -105,6 +111,8 @@ public void EmitInt(int emit)
public void EmitUInt(uint emit)
{
+ AssertAlignment(sizeof(uint));
+
EmitByte((byte)(emit & 0xFF));
EmitByte((byte)((emit >> 8) & 0xFF));
EmitByte((byte)((emit >> 16) & 0xFF));
@@ -113,6 +121,8 @@ public void EmitUInt(uint emit)
public void EmitLong(long emit)
{
+ AssertAlignment(sizeof(long));
+
EmitByte((byte)(emit & 0xFF));
EmitByte((byte)((emit >> 8) & 0xFF));
EmitByte((byte)((emit >> 16) & 0xFF));
@@ -245,6 +255,8 @@ public Reservation ReserveShort()
public void EmitShort(Reservation reservation, short emit)
{
int offset = ReturnReservationTicket(reservation);
+
+ AssertAlignment(offset, sizeof(short));
_data[offset] = (byte)(emit & 0xFF);
_data[offset + 1] = (byte)((emit >> 8) & 0xFF);
}
@@ -257,6 +269,8 @@ public Reservation ReserveInt()
public void EmitInt(Reservation reservation, int emit)
{
int offset = ReturnReservationTicket(reservation);
+
+ AssertAlignment(offset, sizeof(int));
_data[offset] = (byte)(emit & 0xFF);
_data[offset + 1] = (byte)((emit >> 8) & 0xFF);
_data[offset + 2] = (byte)((emit >> 16) & 0xFF);
@@ -266,6 +280,8 @@ public void EmitInt(Reservation reservation, int emit)
public void EmitUInt(Reservation reservation, uint emit)
{
int offset = ReturnReservationTicket(reservation);
+
+ AssertAlignment(offset, sizeof(uint));
_data[offset] = (byte)(emit & 0xFF);
_data[offset + 1] = (byte)((emit >> 8) & 0xFF);
_data[offset + 2] = (byte)((emit >> 16) & 0xFF);
@@ -285,6 +301,7 @@ public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)
_relocs.Add(new Relocation(relocType, _data.Count, symbol));
+ System.Console.WriteLine($"EmitReloc({symbol}, {relocType}, {delta})");
// And add space for the reloc
switch (relocType)
{
@@ -365,5 +382,21 @@ public void PadAlignment(int align)
EmitZeros(align - misalignment);
}
}
+
+ public void AssertAlignment(int align)
+ {
+ AssertAlignment(_data.Count, align);
+ }
+
+ public void AssertAlignment(int offset, int align)
+ {
+ if (((int)offset & (align - 1)) != 0)
+ {
+ System.Console.WriteLine($"AssertAlignment offset = {offset} align = {align}");
+
+ System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(true);
+ System.Console.WriteLine($"{st}");
+ }
+ }
}
} |
The delay load thunks for arm64 do not seem to be as compact as they can be. I think we should be able to both fix the misaligned relocs and make the arm64 delay load thunks more compact at the same time.
This looks by design. The RVA fields in ECMA-335 metadata blob are not always aligned by design. |
There is one more different type of stack:
Is it the same as |
Yes, it is the same as WriteFieldRvas. |
Crossgen2 constructs some code by
ObjectDataBuilder
class. In some cases the code includes pieces of data, for example relocation pointers. To proper align the dataObjectDataBuilder
has methodPadAlignment
:https://github.com/dotnet/runtime/blob/486142a4b87ed6e3134bd1a8726156fb3f55157a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs#L357C44-L357C44
At the same time the only platform which use
PadAlignment
method is Win32.Why crossgen2 uses
PadAlignment
only for Win32 and generates misaligned data for other platforms?On platforms there misaligned memory operations is not prohibited they may cause performance degradation in compare with aligned operations. Is there some memory/performance investigations for this misaligned/aligned data generation?
The text was updated successfully, but these errors were encountered: