From 19e60d98644908b93a82bd57fc05597102a76bac Mon Sep 17 00:00:00 2001 From: Rangi Date: Tue, 14 Jul 2026 00:42:42 -0400 Subject: [PATCH] Fix large `ds` in linker script overflowing the PC --- src/link/layout.cpp | 4 +++- test/link/script-ds/a.asm | 2 ++ test/link/script-ds/b.asm | 2 ++ test/link/script-ds/out.err | 3 +++ test/link/script-ds/script.link | 5 +++++ test/link/test.sh | 9 +++++++++ 6 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test/link/script-ds/a.asm create mode 100644 test/link/script-ds/b.asm create mode 100644 test/link/script-ds/out.err create mode 100644 test/link/script-ds/script.link diff --git a/src/link/layout.cpp b/src/link/layout.cpp index 89b51465..750e22fe 100644 --- a/src/link/layout.cpp +++ b/src/link/layout.cpp @@ -204,7 +204,9 @@ void layout_Pad(uint32_t length) { uint16_t &pc = curAddr[activeType][activeBankIdx]; assume(pc >= typeInfo.startAddr); - if (uint16_t offset = pc - typeInfo.startAddr; length + offset > typeInfo.size) { + // `length + offset` can overflow `uint32_t`, so check just `length` first + if (uint16_t offset = pc - typeInfo.startAddr; + length > typeInfo.size || length + offset > typeInfo.size) { scriptError( "Cannot increase the current address by %u bytes: only %u bytes to $%04" PRIx16, length, diff --git a/test/link/script-ds/a.asm b/test/link/script-ds/a.asm new file mode 100644 index 00000000..1c186445 --- /dev/null +++ b/test/link/script-ds/a.asm @@ -0,0 +1,2 @@ +section "foo", rom0 +Foo:: dw Foo diff --git a/test/link/script-ds/b.asm b/test/link/script-ds/b.asm new file mode 100644 index 00000000..a4820cdb --- /dev/null +++ b/test/link/script-ds/b.asm @@ -0,0 +1,2 @@ +section "bar", rom0 +Bar:: dw Bar diff --git a/test/link/script-ds/out.err b/test/link/script-ds/out.err new file mode 100644 index 00000000..0324b18a --- /dev/null +++ b/test/link/script-ds/out.err @@ -0,0 +1,3 @@ +error: Cannot increase the current address by 4294967280 bytes: only 12286 bytes to $4000 + at script-ds/script.link(4) +Linking failed with 1 error diff --git a/test/link/script-ds/script.link b/test/link/script-ds/script.link new file mode 100644 index 00000000..ef46c75d --- /dev/null +++ b/test/link/script-ds/script.link @@ -0,0 +1,5 @@ +ROM0 + org $1000 + "foo" + ds $ffff_fff0 + "bar" diff --git a/test/link/test.sh b/test/link/test.sh index d82c77e6..760b136f 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -322,6 +322,15 @@ tryDiff "$test"/out.err "$outtemp" tryCmp "$test"/out.gb "$gbtemp" evaluateTest +test="script-ds" +startTest +"$RGBASM" -o "$otemp" "$test"/a.asm +"$RGBASM" -o "$gbtemp2" "$test"/b.asm +continueTest +rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2" 2>"$outtemp" +tryDiff "$test"/out.err "$outtemp" +evaluateTest + test="script-include" startTest "$RGBASM" -o "$otemp" "$test"/a.asm