Skip to content

RISC-V: signal frame is misaligned in signal handlers

Host environment

  • Operating system: Linux
  • OS/kernel version: 5.18.5
  • Architecture: x86_64
  • QEMU flavor: qemu-riscv64
  • QEMU version: 7.0.0
  • QEMU command line:
    ./qemu-riscv64 ./a.out

Emulated/Virtualized environment

  • Architecture: RISC-V 64

Description of problem

qemu-user misaligns the signal frame (to 4 bytes rather than 16 bytes) on RISC-V 64, e.g causing pointer misalignment diagnostics to be triggered by UBSan.

Steps to reproduce

  1. Create a C file with the following contents:
#include <signal.h>
#include <stdio.h>

void handler(int sig, siginfo_t *info, void *context) {
	printf("signal occurred, info: %p, context: %p\n", info, context);
}

int main() {
	struct sigaction act;
	act.sa_flags = SA_SIGINFO;
	act.sa_sigaction = handler;
	sigaction(SIGINT, &act, NULL);

	// Deliberately misalign the stack
	asm volatile ("addi sp, sp, -4");

	while(1);
	// Unreachable
}
  1. Compile with an appropriate RISC-V toolchain and run with qemu-riscv64 ./a.out.
  2. Send a SIGINT (e.g by hitting Ctrl-C), and observe that the signal frame will be misaligned:
signal occurred, info: 0x400080025c, context: 0x40008002dc

Additional information

This issue is alluded to in the source code, see https://gitlab.com/qemu-project/qemu/-/blob/master/linux-user/riscv/signal.c#L68-69. It should be sufficient to change that constant to 15.

Edited by Matt Taylor
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information