From b4988afc8a5252096d0f9fc8b84c5c825aa67b00 Mon Sep 17 00:00:00 2001 From: Rangi Date: Thu, 17 Sep 2026 11:16:18 -0400 Subject: [PATCH] Fix RGBLINK ignoring alignment constraints when placing empty sections Fixes #2095 --- src/link/assign.cpp | 10 ++++++++-- test/link/zero-byte-sect-constraints.asm | 23 +++++++++++++++++++++++ test/link/zero-byte-sect-constraints.out | 0 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/link/zero-byte-sect-constraints.asm create mode 100644 test/link/zero-byte-sect-constraints.out diff --git a/src/link/assign.cpp b/src/link/assign.cpp index a4ee00f1..d9bdf967 100644 --- a/src/link/assign.cpp +++ b/src/link/assign.cpp @@ -256,12 +256,18 @@ static void placeSection(Section §ion) { // Specially handle 0-byte SECTIONs, as they can't overlap anything if (section.size == 0) { - // Unless the SECTION's address was fixed, the starting address - // is fine for any alignment, as checked in sect_DoSanityChecks. + // Unless the SECTION has a fixed address or non-zero alignment, the starting + // address is fine for any alignment, as checked in `sect_DoSanityChecks`. MemoryLocation location = { .address = section.isAddressFixed ? section.org : typeInfo.startAddr, .bank = section.isBankFixed ? section.bank : typeInfo.firstBank, }; + if (section.isAlignFixed && !section.isAddressFixed) { + if (uint16_t offset = (location.address - section.alignOfs) & section.alignMask; + offset != 0) { + location.address += section.alignMask + 1 - offset; + } + } assignSection(section, location); return; } diff --git a/test/link/zero-byte-sect-constraints.asm b/test/link/zero-byte-sect-constraints.asm new file mode 100644 index 00000000..4cd7d289 --- /dev/null +++ b/test/link/zero-byte-sect-constraints.asm @@ -0,0 +1,23 @@ +; Sections going into space already reserved. +SECTION "address", ROM0[$0135] + assert @ == $0135 + +SECTION "align16", ROM0, ALIGN[16,$0123] ; Should be equivalent to the above. + assert @ == $0123 + +SECTION "align", ROM0, ALIGN[8,42] + assert @ == 42 ; Assuming that it goes into the first suitable location. + + +SECTION "om nom nom", ROM0[0] + ds $200 ; Filling the first part of ROM0, so that the above don't land in a “free space” block but the next do. + + +SECTION "free address", ROM0[$2468] + assert @ == $2468 + +SECTION "free align16", ROM0, ALIGN[16,$2222] ; Should be equivalent to the above. + assert @ == $2222 + +SECTION "free align", ROM0, ALIGN[13,$1234] ; Has more than one suitable location, so cannot be trivially solved. + assert @ == $1234 ; Assuming that it goes into the first suitable location. diff --git a/test/link/zero-byte-sect-constraints.out b/test/link/zero-byte-sect-constraints.out new file mode 100644 index 00000000..e69de29b