From c151450d9f3b61baf47a9e96c38cca7f3705ca10 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Fri, 18 Sep 2026 22:00:27 -0400 Subject: [PATCH] Fix underflowing `SECTION FRAGMENT` fixed address in RGBLINK (#2122) --- src/link/section.cpp | 12 ++++++++++++ test/link/section-fragment/org-beyond-size/a.asm | 2 ++ test/link/section-fragment/org-beyond-size/b.asm | 2 ++ test/link/section-fragment/org-beyond-size/out.err | 5 +++++ test/link/test.sh | 9 +++++++++ 5 files changed, 30 insertions(+) create mode 100644 test/link/section-fragment/org-beyond-size/a.asm create mode 100644 test/link/section-fragment/org-beyond-size/b.asm create mode 100644 test/link/section-fragment/org-beyond-size/out.err diff --git a/src/link/section.cpp b/src/link/section.cpp index 240d4341..618d519c 100644 --- a/src/link/section.cpp +++ b/src/link/section.cpp @@ -56,6 +56,18 @@ static void checkPieceCompat(Section &target, Section const &other, size_t delta other.org ); } + } else if (other.org < delta) { + // Check that `org` 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. + fatalTwoAt( + target, + other, + "Section \"%s\" contains %" PRIu16 + " bytes, but is also defined with a lower fixed address $%04" PRIx16, + target.name.c_str(), + target.size, + other.org + ); } target.isAddressFixed = true; diff --git a/test/link/section-fragment/org-beyond-size/a.asm b/test/link/section-fragment/org-beyond-size/a.asm new file mode 100644 index 00000000..ec4d68e2 --- /dev/null +++ b/test/link/section-fragment/org-beyond-size/a.asm @@ -0,0 +1,2 @@ +SECTION FRAGMENT "f", ROM0 +ds 32, 0 diff --git a/test/link/section-fragment/org-beyond-size/b.asm b/test/link/section-fragment/org-beyond-size/b.asm new file mode 100644 index 00000000..797c330c --- /dev/null +++ b/test/link/section-fragment/org-beyond-size/b.asm @@ -0,0 +1,2 @@ +SECTION FRAGMENT "f", ROM0[$10] +db 42 diff --git a/test/link/section-fragment/org-beyond-size/out.err b/test/link/section-fragment/org-beyond-size/out.err new file mode 100644 index 00000000..1e46c243 --- /dev/null +++ b/test/link/section-fragment/org-beyond-size/out.err @@ -0,0 +1,5 @@ +FATAL: Section "f" contains 32 bytes, but is also defined with a lower fixed address $0010 + at section-fragment/org-beyond-size/a.asm(1) + and also: + at section-fragment/org-beyond-size/b.asm(1) +Linking aborted with 1 error diff --git a/test/link/test.sh b/test/link/test.sh index 945daaee..419485fd 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -417,6 +417,15 @@ rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" tryCmpRom "$test"/ref.out.bin evaluateTest +test="section-fragment/org-beyond-size" +startTest +"$RGBASM" -o "$otemp" "$test"/a.asm +"$RGBASM" -o "$gbtemp" "$test"/b.asm +continueTest +rgblinkQuiet "$otemp" "$gbtemp" 2>"$outtemp" +tryDiff "$test"/out.err "$outtemp" +evaluateTest + test="section-normal/same-name" startTest "$RGBASM" -o "$otemp" "$test"/a.asm