* [PATCH 0/2] semihosting: Fix auto-strlen for 32-bit targets + add riscv32 test
@ 2026-06-19 9:52 Nikita Shubin
2026-06-19 9:52 ` [PATCH 1/2] semihosting/arm-compat-semi: Fix auto‑strlen detection for 32‑bit targets Nikita Shubin
2026-06-19 9:52 ` [PATCH 2/2] tests/tcg/riscv32: Add RISC-V 32-bit semihosting test Nikita Shubin
0 siblings, 2 replies; 5+ messages in thread
From: Nikita Shubin @ 2026-06-19 9:52 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée, Paolo Bonzini, Nikita Shubin
This short series fixes a regression in semihosting's automatic string length
detection for 32‑bit targets, introduced when target_ulong was replaced with
uint64_t. The first patch restores the original behaviour where passing
-1 (0xffffffff) in arg2 triggers the auto‑length logic by detecting the
32‑bit sentinel and promoting it to the 64‑bit equivalent.
The second patch extends the TCG test suite with a new RISC‑V 32‑bit
semihosting test that exercises SYS_OPEN with auto‑length, verifying that
the fix works correctly on qemu-system-riscv32.
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
Nikita Shubin (2):
semihosting/arm-compat-semi: Fix auto‑strlen detection for 32‑bit targets
tests/tcg/riscv32: Add RISC-V 32-bit semihosting test
configure | 6 +++-
semihosting/arm-compat-semi.c | 11 ++++++
tests/tcg/riscv32/Makefile.softmmu-target | 30 +++++++++++++++++
tests/tcg/riscv32/semihost.ld | 24 +++++++++++++
tests/tcg/riscv32/test-semihosting-open.S | 56 +++++++++++++++++++++++++++++++
5 files changed, 126 insertions(+), 1 deletion(-)
---
base-commit: 3b50303f9563a42538a1fd5c0ea7f952e23016e1
change-id: 20260619-fix-sign-extended-32-bit-addresses-68eba061cd9a
Best regards,
--
Nikita Shubin
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] semihosting/arm-compat-semi: Fix auto‑strlen detection for 32‑bit targets 2026-06-19 9:52 [PATCH 0/2] semihosting: Fix auto-strlen for 32-bit targets + add riscv32 test Nikita Shubin @ 2026-06-19 9:52 ` Nikita Shubin 2026-06-23 12:40 ` Alex Bennée 2026-06-19 9:52 ` [PATCH 2/2] tests/tcg/riscv32: Add RISC-V 32-bit semihosting test Nikita Shubin 1 sibling, 1 reply; 5+ messages in thread From: Nikita Shubin @ 2026-06-19 9:52 UTC (permalink / raw) To: qemu-devel; +Cc: Alex Bennée, Paolo Bonzini, Nikita Shubin The switch from target_ulong to uint64_t broke the mechanism of passing -1 (0xffffffff) in arg2 to signal validate_strlen() to compute the string length automatically. For 32‑bit semihosting, detect when arg2 is 0xffffffff and replace it with 0xffffffffffffffff. This causes an overflow to zero, restoring the original behavior of automatic length calculation. Fixes: 6dfbf9b6cfe ("semihosting/arm-compat-semi: replace target_ulong") Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> --- semihosting/arm-compat-semi.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c index 5e5f181b90..682349bd51 100644 --- a/semihosting/arm-compat-semi.c +++ b/semihosting/arm-compat-semi.c @@ -442,6 +442,17 @@ void do_common_semihosting(CPUState *cs) } } else { unlock_user(s, arg0, 0); + /* + * Due to the switch from target_ulong to uint64_t, passing -1 + * as arg2 is no longer possible. + * For 32‑bit targets, if arg2 == 0xffffffff, set it + * to 0xffffffffffffffff to trigger overflow so zero strlen + * is passed to validate_strlen(). + */ + if (!is_64bit_semihosting(env) && arg2 == (uint32_t)-1) { + arg2 = -1; + } + semihost_sys_open(cs, common_semi_cb, arg0, arg2 + 1, gdb_open_modeflags[arg1], 0644); break; -- 2.52.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] semihosting/arm-compat-semi: Fix auto‑strlen detection for 32‑bit targets 2026-06-19 9:52 ` [PATCH 1/2] semihosting/arm-compat-semi: Fix auto‑strlen detection for 32‑bit targets Nikita Shubin @ 2026-06-23 12:40 ` Alex Bennée 0 siblings, 0 replies; 5+ messages in thread From: Alex Bennée @ 2026-06-23 12:40 UTC (permalink / raw) To: Nikita Shubin; +Cc: qemu-devel, Paolo Bonzini Nikita Shubin <nikita.shubin@maquefel.me> writes: > The switch from target_ulong to uint64_t broke the mechanism of passing -1 > (0xffffffff) in arg2 to signal validate_strlen() to compute the string > length automatically. For 32‑bit semihosting, detect when arg2 is > 0xffffffff and replace it with 0xffffffffffffffff. This causes an overflow > to zero, restoring the original behavior of automatic length calculation. > > Fixes: 6dfbf9b6cfe ("semihosting/arm-compat-semi: replace target_ulong") > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> Acked-by: Alex Bennée <alex.bennee@linaro.org> -- Alex Bennée Virtualisation Tech Lead @ Linaro ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] tests/tcg/riscv32: Add RISC-V 32-bit semihosting test 2026-06-19 9:52 [PATCH 0/2] semihosting: Fix auto-strlen for 32-bit targets + add riscv32 test Nikita Shubin 2026-06-19 9:52 ` [PATCH 1/2] semihosting/arm-compat-semi: Fix auto‑strlen detection for 32‑bit targets Nikita Shubin @ 2026-06-19 9:52 ` Nikita Shubin 2026-06-22 4:32 ` Alistair Francis 1 sibling, 1 reply; 5+ messages in thread From: Nikita Shubin @ 2026-06-19 9:52 UTC (permalink / raw) To: qemu-devel; +Cc: Alex Bennée, Paolo Bonzini, Nikita Shubin Extend the TCG test infrastructure to support 32-bit RISC-V (riscv32) system tests. - configure: Add riscv32 to probe_target_compiler() using the same container (debian-all-test-cross) as riscv64, with cross prefix riscv64-linux-gnu- (the compiler can generate 32-bit code with -march=rv32imafdch -mabi=ilp32d). - tests/tcg/riscv32/: New directory with: * Makefile.softmmu-target – build rules for 32-bit softmmu tests * semihost.ld – linker script (same as riscv64, RAM at 0x80000000) * test-semihosting-open.S – test for SYS_OPEN with auto length (-1) The semihosting test validates the fix for sign-extended 32-bit pointers when running riscv32 guests on qemu-system-riscv32. CFLAGS and LDFLAGS are explicitly set for rv32imafdch/ilp32d ABI, and LDFLAGS includes -melf32lriscv to produce 32-bit ELF. Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> --- configure | 6 +++- tests/tcg/riscv32/Makefile.softmmu-target | 30 +++++++++++++++++ tests/tcg/riscv32/semihost.ld | 24 +++++++++++++ tests/tcg/riscv32/test-semihosting-open.S | 56 +++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/configure b/configure index d8bc10060e..2df0811b5d 100755 --- a/configure +++ b/configure @@ -1405,7 +1405,7 @@ probe_target_compiler() { mips) container_hosts=x86_64 ;; ppc) container_hosts=x86_64 ;; ppc64|ppc64le) container_hosts=x86_64 ;; - riscv64) container_hosts=x86_64 ;; + riscv32|riscv64) container_hosts=x86_64 ;; s390x) container_hosts=x86_64 ;; sh4) container_hosts=x86_64 ;; sparc64) container_hosts=x86_64 ;; @@ -1424,6 +1424,10 @@ probe_target_compiler() { container_image=debian-all-test-cross container_cross_prefix=aarch64-linux-gnu- ;; + riscv32) + container_image=debian-all-test-cross + container_cross_prefix=riscv64-linux-gnu- + ;; alpha|hppa|m68k|mips|mipsel|riscv64|sh4|sparc64) container_image=debian-all-test-cross ;; diff --git a/tests/tcg/riscv32/Makefile.softmmu-target b/tests/tcg/riscv32/Makefile.softmmu-target new file mode 100644 index 0000000000..eff5b000f0 --- /dev/null +++ b/tests/tcg/riscv32/Makefile.softmmu-target @@ -0,0 +1,30 @@ +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# RISC-V 32-bit system tests +# + +TEST_SRC = $(SRC_PATH)/tests/tcg/riscv32 +VPATH += $(TEST_SRC) + +LINK_SCRIPT = $(TEST_SRC)/semihost.ld +LDFLAGS = -T $(LINK_SCRIPT) +CFLAGS += -g -Og + +%.o: %.S + $(CC) $(CFLAGS) $< -Wa,--noexecstack -c -o $@ +%: %.o $(LINK_SCRIPT) + $(LD) $(LDFLAGS) $< -o $@ + +QEMU_OPTS += -M virt -display none -semihosting -device loader,file= +# provide flags for riscv32 as we are using riscv64-linux-gnu- +CFLAGS += -march=rv32imafdch -mabi=ilp32d +LDFLAGS += -melf32lriscv + +EXTRA_RUNS += run-semihosting-open +run-semihosting-open: test-semihosting-open + $(call run-test, $<, \ + $(QEMU) $(QEMU_OPTS)$<) + +# We don't currently support the multiarch system tests +undefine MULTIARCH_TESTS \ No newline at end of file diff --git a/tests/tcg/riscv32/semihost.ld b/tests/tcg/riscv32/semihost.ld new file mode 100644 index 0000000000..ff3b786481 --- /dev/null +++ b/tests/tcg/riscv32/semihost.ld @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + */ +ENTRY(_start) + +SECTIONS +{ + /* virt machine, RAM starts at 2gb */ + . = 0x80000000; + .text : { + *(.text) + } + .rodata : { + *(.rodata) + } + /* align r/w section to next 2mb */ + . = ALIGN(1 << 21); + .data : { + *(.data) + } + .bss : { + *(.bss) + } +} diff --git a/tests/tcg/riscv32/test-semihosting-open.S b/tests/tcg/riscv32/test-semihosting-open.S new file mode 100644 index 0000000000..acbb31c558 --- /dev/null +++ b/tests/tcg/riscv32/test-semihosting-open.S @@ -0,0 +1,56 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + */ +.option norvc +.text +.global _start +_start: + # Argument block for SYS_OPEN (each arg is 4 bytes in RV32) + la a1, open_args + la t0, test_filename + sw t0, 0(a1) # arg0: pointer to filename + li t0, 4 # arg1: "w" (write, create, truncate) + sw t0, 4(a1) + li t0, -1 # arg2: auto length (-1 = 0xffffffff) + sw t0, 8(a1) + + # SYS_OPEN semihosting call + li a0, 0x01 + .balign 16 + slli zero, zero, 0x1f + ebreak + srai zero, zero, 0x7 + + # Check result: a0 should be a valid file descriptor (not -1) + li t0, -1 + beq a0, t0, fail + + # Success + li a0, 0 + j exit + +fail: + li a0, 1 + +exit: + # Extended semihosting exit + la a1, semiargs + li t0, 0x20026 # ADP_Stopped_ApplicationExit + sw t0, 0(a1) + sw a0, 4(a1) + li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED + .balign 16 + slli zero, zero, 0x1f + ebreak + srai zero, zero, 0x7 + + j . + +.data +.balign 16 +test_filename: + .string "testfile.txt" +open_args: + .space 12 # 3 * 4 bytes +semiargs: + .space 8 # 2 * 4 bytes -- 2.52.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] tests/tcg/riscv32: Add RISC-V 32-bit semihosting test 2026-06-19 9:52 ` [PATCH 2/2] tests/tcg/riscv32: Add RISC-V 32-bit semihosting test Nikita Shubin @ 2026-06-22 4:32 ` Alistair Francis 0 siblings, 0 replies; 5+ messages in thread From: Alistair Francis @ 2026-06-22 4:32 UTC (permalink / raw) To: Nikita Shubin; +Cc: qemu-devel, Alex Bennée, Paolo Bonzini On Fri, Jun 19, 2026 at 7:53 PM Nikita Shubin <nikita.shubin@maquefel.me> wrote: > > Extend the TCG test infrastructure to support 32-bit RISC-V (riscv32) > system tests. > > - configure: Add riscv32 to probe_target_compiler() using the same > container (debian-all-test-cross) as riscv64, with cross prefix > riscv64-linux-gnu- (the compiler can generate 32-bit code with > -march=rv32imafdch -mabi=ilp32d). > > - tests/tcg/riscv32/: New directory with: > * Makefile.softmmu-target – build rules for 32-bit softmmu tests > * semihost.ld – linker script (same as riscv64, RAM at 0x80000000) > * test-semihosting-open.S – test for SYS_OPEN with auto length (-1) > > The semihosting test validates the fix for sign-extended 32-bit > pointers when running riscv32 guests on qemu-system-riscv32. > > CFLAGS and LDFLAGS are explicitly set for rv32imafdch/ilp32d ABI, > and LDFLAGS includes -melf32lriscv to produce 32-bit ELF. > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > configure | 6 +++- > tests/tcg/riscv32/Makefile.softmmu-target | 30 +++++++++++++++++ > tests/tcg/riscv32/semihost.ld | 24 +++++++++++++ > tests/tcg/riscv32/test-semihosting-open.S | 56 +++++++++++++++++++++++++++++++ > 4 files changed, 115 insertions(+), 1 deletion(-) > > diff --git a/configure b/configure > index d8bc10060e..2df0811b5d 100755 > --- a/configure > +++ b/configure > @@ -1405,7 +1405,7 @@ probe_target_compiler() { > mips) container_hosts=x86_64 ;; > ppc) container_hosts=x86_64 ;; > ppc64|ppc64le) container_hosts=x86_64 ;; > - riscv64) container_hosts=x86_64 ;; > + riscv32|riscv64) container_hosts=x86_64 ;; > s390x) container_hosts=x86_64 ;; > sh4) container_hosts=x86_64 ;; > sparc64) container_hosts=x86_64 ;; > @@ -1424,6 +1424,10 @@ probe_target_compiler() { > container_image=debian-all-test-cross > container_cross_prefix=aarch64-linux-gnu- > ;; > + riscv32) > + container_image=debian-all-test-cross > + container_cross_prefix=riscv64-linux-gnu- > + ;; > alpha|hppa|m68k|mips|mipsel|riscv64|sh4|sparc64) > container_image=debian-all-test-cross > ;; > diff --git a/tests/tcg/riscv32/Makefile.softmmu-target b/tests/tcg/riscv32/Makefile.softmmu-target > new file mode 100644 > index 0000000000..eff5b000f0 > --- /dev/null > +++ b/tests/tcg/riscv32/Makefile.softmmu-target > @@ -0,0 +1,30 @@ > +# > +# SPDX-License-Identifier: GPL-2.0-or-later > +# > +# RISC-V 32-bit system tests > +# > + > +TEST_SRC = $(SRC_PATH)/tests/tcg/riscv32 > +VPATH += $(TEST_SRC) > + > +LINK_SCRIPT = $(TEST_SRC)/semihost.ld > +LDFLAGS = -T $(LINK_SCRIPT) > +CFLAGS += -g -Og > + > +%.o: %.S > + $(CC) $(CFLAGS) $< -Wa,--noexecstack -c -o $@ > +%: %.o $(LINK_SCRIPT) > + $(LD) $(LDFLAGS) $< -o $@ > + > +QEMU_OPTS += -M virt -display none -semihosting -device loader,file= > +# provide flags for riscv32 as we are using riscv64-linux-gnu- > +CFLAGS += -march=rv32imafdch -mabi=ilp32d > +LDFLAGS += -melf32lriscv > + > +EXTRA_RUNS += run-semihosting-open > +run-semihosting-open: test-semihosting-open > + $(call run-test, $<, \ > + $(QEMU) $(QEMU_OPTS)$<) > + > +# We don't currently support the multiarch system tests > +undefine MULTIARCH_TESTS > \ No newline at end of file > diff --git a/tests/tcg/riscv32/semihost.ld b/tests/tcg/riscv32/semihost.ld > new file mode 100644 > index 0000000000..ff3b786481 > --- /dev/null > +++ b/tests/tcg/riscv32/semihost.ld > @@ -0,0 +1,24 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > +ENTRY(_start) > + > +SECTIONS > +{ > + /* virt machine, RAM starts at 2gb */ > + . = 0x80000000; > + .text : { > + *(.text) > + } > + .rodata : { > + *(.rodata) > + } > + /* align r/w section to next 2mb */ > + . = ALIGN(1 << 21); > + .data : { > + *(.data) > + } > + .bss : { > + *(.bss) > + } > +} > diff --git a/tests/tcg/riscv32/test-semihosting-open.S b/tests/tcg/riscv32/test-semihosting-open.S > new file mode 100644 > index 0000000000..acbb31c558 > --- /dev/null > +++ b/tests/tcg/riscv32/test-semihosting-open.S > @@ -0,0 +1,56 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > +.option norvc > +.text > +.global _start > +_start: > + # Argument block for SYS_OPEN (each arg is 4 bytes in RV32) > + la a1, open_args > + la t0, test_filename > + sw t0, 0(a1) # arg0: pointer to filename > + li t0, 4 # arg1: "w" (write, create, truncate) > + sw t0, 4(a1) > + li t0, -1 # arg2: auto length (-1 = 0xffffffff) > + sw t0, 8(a1) > + > + # SYS_OPEN semihosting call > + li a0, 0x01 > + .balign 16 > + slli zero, zero, 0x1f > + ebreak > + srai zero, zero, 0x7 > + > + # Check result: a0 should be a valid file descriptor (not -1) > + li t0, -1 > + beq a0, t0, fail > + > + # Success > + li a0, 0 > + j exit > + > +fail: > + li a0, 1 > + > +exit: > + # Extended semihosting exit > + la a1, semiargs > + li t0, 0x20026 # ADP_Stopped_ApplicationExit > + sw t0, 0(a1) > + sw a0, 4(a1) > + li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED > + .balign 16 > + slli zero, zero, 0x1f > + ebreak > + srai zero, zero, 0x7 > + > + j . > + > +.data > +.balign 16 > +test_filename: > + .string "testfile.txt" > +open_args: > + .space 12 # 3 * 4 bytes > +semiargs: > + .space 8 # 2 * 4 bytes > > -- > 2.52.0 > > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-23 12:40 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-19 9:52 [PATCH 0/2] semihosting: Fix auto-strlen for 32-bit targets + add riscv32 test Nikita Shubin 2026-06-19 9:52 ` [PATCH 1/2] semihosting/arm-compat-semi: Fix auto‑strlen detection for 32‑bit targets Nikita Shubin 2026-06-23 12:40 ` Alex Bennée 2026-06-19 9:52 ` [PATCH 2/2] tests/tcg/riscv32: Add RISC-V 32-bit semihosting test Nikita Shubin 2026-06-22 4:32 ` Alistair Francis
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.