From d81ab2fb23d202fb0cd74a4e8d205de8e2cf43e9 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Tue, 15 Sep 2026 20:22:19 -0400 Subject: [PATCH] Fix underflowing `SECTION FRAGMENT` fixed address (#2091) --- src/asm/section.cpp | 16 ++++++++++++---- test/asm/fragment-org-beyond-size.asm | 4 ++++ test/asm/fragment-org-beyond-size.err | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 test/asm/fragment-org-beyond-size.asm create mode 100644 test/asm/fragment-org-beyond-size.err diff --git a/src/asm/section.cpp b/src/asm/section.cpp index 8dfce013..4acf8b52 100644 --- a/src/asm/section.cpp +++ b/src/asm/section.cpp @@ -214,10 +214,8 @@ static void mergeFragments(Section §, uint32_t org, uint8_t alignment, uint1 // combination of both. // The merging is however performed at the *end* of the original section! if (org != UINT32_MAX) { - uint16_t curOrg = org - sect.size; - - // If both are fixed, they must be the same - if (sect.org != UINT32_MAX && sect.org != curOrg) { + // If both are fixed, they must be compatible + if (uint16_t curOrg = org - sect.size; sect.org != UINT32_MAX && sect.org != curOrg) { sectError( "Section \"%s\" already declared as fixed at incompatible address $%04" PRIx32, sect.name.c_str(), @@ -231,6 +229,16 @@ static void mergeFragments(Section §, uint32_t org, uint8_t alignment, uint1 sectAlignSize, sect.alignOfs ); + } else if (org < sect.size) { + // Check that `curOrg` did not underflow. Note that it's safe for the above checks to + // use an underflowed value, since their reported errors will still be accurate. + sectError( + "Section \"%s\" already contains %" PRIu32 + " bytes, higher than this fragment's fixed address $%04" PRIx32, + sect.name.c_str(), + sect.size, + org + ); } else { // Otherwise, just override sect.org = curOrg; diff --git a/test/asm/fragment-org-beyond-size.asm b/test/asm/fragment-org-beyond-size.asm new file mode 100644 index 00000000..dfab377c --- /dev/null +++ b/test/asm/fragment-org-beyond-size.asm @@ -0,0 +1,4 @@ +SECTION FRAGMENT "test", ROM0 +ds $11, 42 + +SECTION FRAGMENT "test", ROM0[$10] diff --git a/test/asm/fragment-org-beyond-size.err b/test/asm/fragment-org-beyond-size.err new file mode 100644 index 00000000..bce7ffa6 --- /dev/null +++ b/test/asm/fragment-org-beyond-size.err @@ -0,0 +1,2 @@ +FATAL: Section "test" already contains 17 bytes, higher than this fragment's fixed address $0010 + at fragment-org-beyond-size.asm(4)