Fix alignment errors in EWRAM_INIT and friends when using u8, u16, etc. #5512
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
I opened a PR a while back to add EWRAM_INIT support to the project. The linker script modifications I made didn't take into account that users may define data sections that are not a multiple of 4 bytes in size. This leads the DMA transfer at init to copy garbage into the wrong sections, resulting in subtle errors at runtime when the feature is used. I've also aligned IWRAM_DATA to prevent the same error.
This is a one-line change, allow me to explain what's happening:
.ewram ORIGIN(EWRAM) : AT (__ewram_lma) ALIGN(4) { __ewram_start = .; *(.ewram*); + . = ALIGN(4); __ewram_end = .; } > EWRAM
The
.
represents an address marching ahead in memory in ld scripts as each section is defined/filled. If we added aEWRAM_INIT u8 foo = 1;
then this section would resolve*(.ewram*)
in a way that marches the pointer forward by 1 byte. The section itself will be aligned to 4 bytes because of the original and firstALIGN(4)
directive, but the __ewram_end symbol we export to the initialization assembly to tell it which sections to copy would be 1 byte ahead, not 4. This breaks assumptions in the assembly code and leads it to copy garbage into otherwise necessary sections.By adding the new line above, we force the pointer to march ahead anywhere from 0-3 bytes to ensure there is sufficient padding for the DMA copy to function.
This should resolve the issue. To test the issue and its resolution one can make a single line change to
main.c
:Without the fix, a number of issues will the occur, the first being that the default option selected after the title screen on a blank save will be "Options" instead of "New Game".
Images
Discord contact info
@luigi___