diff --git a/src/riscv.c b/src/riscv.c index 3e36eda3..fd3a1646 100644 --- a/src/riscv.c +++ b/src/riscv.c @@ -647,10 +647,16 @@ riscv_t *rv_create(riscv_user_t rv_attr) #if !RV32_HAS(SYSTEM) /* set not exiting */ attr->on_exit = false; + attr->exit_addr = 0; - const struct Elf32_Sym *exit; - if ((exit = elf_get_symbol(elf, "exit"))) - attr->exit_addr = exit->st_value; + /* Try to find exit address from symbols. Check multiple names since + * different toolchains/libc implementations may use different symbols. + */ + const struct Elf32_Sym *exit_sym; + if ((exit_sym = elf_get_symbol(elf, "exit"))) + attr->exit_addr = exit_sym->st_value; + else if ((exit_sym = elf_get_symbol(elf, "_exit"))) + attr->exit_addr = exit_sym->st_value; #endif assert(elf_load(elf, attr->mem)); diff --git a/src/syscall.c b/src/syscall.c index 74dd8318..232665b5 100644 --- a/src/syscall.c +++ b/src/syscall.c @@ -222,9 +222,10 @@ static void syscall_close(riscv_t *rv) /* * The crt0 closes standard file descriptor(0, 1, 2) when * the process exits. Thus, the operations by the crt0 - * should not considered as error. + * should not be considered as error. For stripped ELFs where + * exit_addr is not found, allow close(fd<3) to succeed silently. */ - if (fd < 3 && !PRIV(rv)->on_exit) { + if (fd < 3 && !PRIV(rv)->on_exit && PRIV(rv)->exit_addr) { rv_set_reg(rv, rv_reg_a0, -1); rv_log_error( "Attempted to close a file descriptor < 3 (fd=%u). Operation "