We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The preliminary implementation may look like this:
diff --git a/arch/aarch64/entry.S b/arch/aarch64/entry.S index 556f89ad..80615fe3 100644 --- a/arch/aarch64/entry.S +++ b/arch/aarch64/entry.S @@ -206,18 +206,16 @@ entry_serror: call_signal_handler_thunk: .type call_signal_handler_thunk, @function .cfi_startproc simple - # stack contains a signal_frame - /* - .cfi_offset reg, offset - ... - mov x0, sp - call call_signal_handler - # FIXME: fpu - - pop_pair... - add sp, sp, 16 # error_code - */ - ret + # stack contains a signal_frame + msr SPsel, #1 + ldr x0, [sp, #-40] //new sp modified in the original exception frame + mov sp, x0 + bl call_signal_handler + pop_state_from_exception_frame + ldr x30, [sp, #-40] //old sp saved in the copy of original exception frame in signal frame + mov sp, x30 + ldr x30, [x30, #-48] //restore x30 + eret .cfi_endproc // Keep fpu_state_save/load in sync with struct fpu_state in arch/aarch64/processor.hh diff --git a/arch/aarch64/signal.cc b/arch/aarch64/signal.cc index 7f3cbc15..5bded96a 100644 --- a/arch/aarch64/signal.cc +++ b/arch/aarch64/signal.cc @@ -14,6 +14,10 @@ #include <arch-cpu.hh> #include <osv/debug.hh> +namespace osv { +extern struct sigaction signal_actions[]; +}; + namespace arch { struct signal_frame { @@ -35,7 +39,23 @@ void build_signal_frame(exception_frame* ef, const siginfo_t& si, const struct sigaction& sa) { - void* sp = reinterpret_cast<void*>(ef->sp); + // If an alternative signal stack was defined for this thread with + // sigaltstack() and the SA_ONSTACK flag was specified, we should run + // the signal handler on that stack. Otherwise, we need to run further + // down the same stack the thread was using when it received the signal: + void *sp = nullptr; + if (sa.sa_flags & SA_ONSTACK) { + stack_t sigstack; + sigaltstack(nullptr, &sigstack); + if (!(sigstack.ss_flags & SS_DISABLE)) { + // ss_sp points to the beginning of the stack region, but x86 + // stacks grow downward, from the end of the region + sp = sigstack.ss_sp + sigstack.ss_size; + } + } + if (!sp) { + sp = reinterpret_cast<void*>(ef->sp); + } sp -= sizeof(signal_frame); sp = align_down(sp, 16); signal_frame* frame = static_cast<signal_frame*>(sp); @@ -50,5 +70,84 @@ void build_signal_frame(exception_frame* ef, void call_signal_handler(arch::signal_frame* frame) { - processor::halt_no_interrupts(); + sched::fpu_lock fpu; + SCOPE_LOCK(fpu); + if (frame->sa.sa_flags & SA_SIGINFO) { + ucontext_t uc = {}; + auto& mcontext = uc.uc_mcontext; + auto& f = frame->state; + mcontext.regs[0] = f.regs[0]; + mcontext.regs[1] = f.regs[1]; + mcontext.regs[2] = f.regs[2]; + mcontext.regs[3] = f.regs[3]; + mcontext.regs[4] = f.regs[4]; + mcontext.regs[5] = f.regs[5]; + mcontext.regs[6] = f.regs[6]; + mcontext.regs[7] = f.regs[7]; + mcontext.regs[8] = f.regs[8]; + mcontext.regs[9] = f.regs[9]; + mcontext.regs[10] = f.regs[20]; + mcontext.regs[11] = f.regs[21]; + mcontext.regs[12] = f.regs[22]; + mcontext.regs[13] = f.regs[23]; + mcontext.regs[14] = f.regs[24]; + mcontext.regs[15] = f.regs[25]; + mcontext.regs[16] = f.regs[26]; + mcontext.regs[17] = f.regs[27]; + mcontext.regs[18] = f.regs[28]; + mcontext.regs[19] = f.regs[29]; + mcontext.regs[20] = f.regs[20]; + mcontext.regs[21] = f.regs[21]; + mcontext.regs[22] = f.regs[22]; + mcontext.regs[23] = f.regs[23]; + mcontext.regs[24] = f.regs[24]; + mcontext.regs[25] = f.regs[25]; + mcontext.regs[26] = f.regs[26]; + mcontext.regs[27] = f.regs[27]; + mcontext.regs[28] = f.regs[28]; + mcontext.regs[29] = f.regs[29]; + mcontext.regs[30] = f.regs[30]; + mcontext.sp = f.sp; + mcontext.pc = f.elr; + mcontext.pstate = f.spsr; + mcontext.fault_address = 22345; //TODO: Just to see if it shows + //mcontext.fault_address = f.???;//Should come from far_el1 + frame->sa.sa_sigaction(frame->si.si_signo, &frame->si, &uc); + f.regs[0] = mcontext.regs[0]; + f.regs[1] = mcontext.regs[1]; + f.regs[2] = mcontext.regs[2]; + f.regs[3] = mcontext.regs[3]; + f.regs[4] = mcontext.regs[4]; + f.regs[5] = mcontext.regs[5]; + f.regs[6] = mcontext.regs[6]; + f.regs[7] = mcontext.regs[7]; + f.regs[8] = mcontext.regs[8]; + f.regs[9] = mcontext.regs[9]; + f.regs[10] = mcontext.regs[10]; + f.regs[11] = mcontext.regs[11]; + f.regs[12] = mcontext.regs[12]; + f.regs[13] = mcontext.regs[13]; + f.regs[14] = mcontext.regs[14]; + f.regs[15] = mcontext.regs[15]; + f.regs[16] = mcontext.regs[16]; + f.regs[17] = mcontext.regs[17]; + f.regs[18] = mcontext.regs[18]; + f.regs[19] = mcontext.regs[19]; + f.regs[20] = mcontext.regs[20]; + f.regs[21] = mcontext.regs[21]; + f.regs[22] = mcontext.regs[22]; + f.regs[23] = mcontext.regs[23]; + f.regs[24] = mcontext.regs[24]; + f.regs[25] = mcontext.regs[25]; + f.regs[26] = mcontext.regs[26]; + f.regs[27] = mcontext.regs[27]; + f.regs[28] = mcontext.regs[28]; + f.regs[29] = mcontext.regs[29]; + f.regs[30] = mcontext.regs[30]; + f.sp = mcontext.sp; + f.elr = mcontext.pc; + f.spsr = mcontext.pstate; + } else { + frame->sa.sa_handler(frame->si.si_signo); + } }
The text was updated successfully, but these errors were encountered:
d8d2719
No branches or pull requests
The preliminary implementation may look like this:
The text was updated successfully, but these errors were encountered: