Skip to content
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

Fix RVA field alignment #60

Merged
merged 3 commits into from Jan 10, 2023
Merged

Fix RVA field alignment #60

merged 3 commits into from Jan 10, 2023

Conversation

sbomer
Copy link
Member

@sbomer sbomer commented Jan 10, 2023

Second attempt to fix the RVA field alignment. The fix is the same as #55, with an extra fix for the issue encountered in dotnet/runtime#79449 and the upstream jbevain#888. The tests are passing upstream now.

The problem was the use of GetNextRVA to compute the Code RVA, before adding that segment to the TextMap. This meant that the alignment (only added later) wasn't taken into account when writing out the code, but then later the TextMap was modified to include the alignment.

I fixed this by first inserting an aligned zero-length Code segment before writing the code, then inserting it again once the length is known. Removing the Code alignment altogether would work too, but @vitek-karas and I were thinking it might be better to keep those alignment constants in there, because it looks like they were added intentionally, even though we don't know the reason.

Note that before this change, the start of the Code segment (at least on x64) was not 16-byte aligned in the first place, so this change will actually move the beginning of the Code segment.

Copy link
Member

@vitek-karas vitek-karas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please validate that with this change:

  • Trimmed HelloWorld actually runs
  • It's possible to R2R - again just publish HelloWorld with trimming and R2R turned on

@sbomer
Copy link
Member Author

sbomer commented Jan 10, 2023

Yes, confirmed on windows and linux.

@sbomer sbomer merged commit 2941911 into dotnet:main Jan 10, 2023
@vitek-karas
Copy link
Member

Please look at backporting the fix to 7. As per our discussion, ideally we would backport just the fix, not the rest of Cecil's changes.

agocke pushed a commit that referenced this pull request Apr 5, 2023
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.

GetNextRVA was used to compute the Code RVA, before adding that
segment to the TextMap. This meant that the alignment (only added
later) wasn't taken into account when writing out the code, but
then later the TextMap was modified to include the alignment.

This is fixed by first inserting an aligned zero-length Code
segment before writing the code, then inserting it again once the
length is known. Removing the Code alignment altogether would
work too, but the alignment constants are kept in there, because
it looks like they were added intentionally, even though the
reason is unknown.

Note that before this change, the start of the Code segment (at
least on x64) was not 16-byte aligned in the first place, so this
change will actually move the beginning of the Code segment.
// Alignment of the code segment must be set before the code is written
// These alignment values are probably not necessary, but are being left in
// for now in case something requires them.
map.AddMap (TextSegment.Code, 0, !pe64 ? 4 : 16);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look right to me. The AnyCPU binaries can run on 64-bit architectures and this is not going to guarantee sufficient alignment for them,

For example, consider static ReadOnlySpan<long> MySpan => new long[] { 1, 2, 3, 6, 7 };. The backing RVA field needs to have 8-byte alignment in this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, this extra alignment applies to IL code only (and it should not be needed it in the first place). The RVA alignment is handled elsewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We went back and forth on changing the code alignment, but eventually decided to keep the original logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants