From b0948566bb6e8349d8032ab714b5c0320d72728b Mon Sep 17 00:00:00 2001 From: Rangi Date: Wed, 15 Jul 2026 22:46:57 -0400 Subject: [PATCH] Fail-safe treat 16-bit alignment as a fixed address even in RGBLINK RGBASM does this itself, so should not output sections with 16-bit alignment, but an invalid object file could otherwise cause `getPlacement` to infinitely loop. --- src/link/assign.cpp | 2 ++ src/link/section.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/link/assign.cpp b/src/link/assign.cpp index 334960bd..1e3c93bd 100644 --- a/src/link/assign.cpp +++ b/src/link/assign.cpp @@ -144,6 +144,8 @@ static std::optional getPlacement(Section const §ion, MemoryLocation location.address = section.org; } else if (section.isAlignFixed) { // Move to next aligned location + // We have previously ensured alignment to 15 or fewer bits, so this will progress + assume(section.alignMask < (1 << 16) - 1); // Move back to alignment boundary location.address -= section.alignOfs; // Ensure we're there (e.g. on first check) diff --git a/src/link/section.cpp b/src/link/section.cpp index 20040cdf..907535ec 100644 --- a/src/link/section.cpp +++ b/src/link/section.cpp @@ -321,6 +321,17 @@ static void doSanityChecks(Section §ion) { ); } } + + // An alignment of 16 is impossible to output from RGBASM, since it's treated as + // fixing the address, but is still satisfiable. A fixed address different from the + // alignment offset would not be, but we checked for that already above. + if (section.isAlignFixed && section.alignMask == (1 << 16) - 1) { + assume(!section.isAddressFixed || section.org == section.alignOfs); + section.isAddressFixed = true; + section.org = section.alignOfs; + section.isAlignFixed = false; + section.alignMask = section.alignOfs = 0; + } } void sect_DoSanityChecks() {