diff --git a/libc/src/libc_start.c b/libc/src/libc_start.c index faa0268..04eca04 100644 --- a/libc/src/libc_start.c +++ b/libc/src/libc_start.c @@ -35,8 +35,3 @@ int __libc_start_main(int (*main)(int, char **, char **), int argc, char *argv[] //dbg_print("== END %-30s =======================================\n", argv[0]); return result; } - -// WARNING: This declaration must be here, because libc_start is compiled -// with all the programs, and all the programs NEED to have the `sigreturn` -// symbol. It must be this way, period. -_syscall0(int, sigreturn) diff --git a/libc/src/unistd/signal.c b/libc/src/unistd/signal.c index 0755c7c..84f4e83 100644 --- a/libc/src/unistd/signal.c +++ b/libc/src/unistd/signal.c @@ -10,6 +10,10 @@ #include "signal.h" #include "sys/bitops.h" +_syscall0(int, sigreturn) + +_syscall3(int, sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset) + static const char *sys_siglist[] = { "HUP", "INT", @@ -45,11 +49,19 @@ static const char *sys_siglist[] = { NULL, }; -_syscall2(sighandler_t, signal, int, signum, sighandler_t, handler) +sighandler_t signal(int signum, sighandler_t handler) +{ + long __res; + __inline_syscall3(__res, signal, signum, handler, (unsigned int)sigreturn); + __syscall_return(sighandler_t, __res); +} -_syscall3(int, sigaction, int, signum, const sigaction_t *, act, sigaction_t *, oldact) - -_syscall3(int, sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset) +int sigaction(int signum, const sigaction_t *act, sigaction_t *oldact) +{ + long __res; + __inline_syscall4(__res, sigaction, signum, act, oldact, (unsigned int)sigreturn); + __syscall_return(int, __res); +} const char *strsignal(int sig) { diff --git a/mentos/inc/process/process.h b/mentos/inc/process/process.h index d0e3421..6c0e032 100644 --- a/mentos/inc/process/process.h +++ b/mentos/inc/process/process.h @@ -119,9 +119,8 @@ typedef struct task_struct { /// The current working directory. char cwd[PATH_MAX]; - // struct signal_struct *signal; - /// Instruction Pointer of the LIBC Signal Handler. - uint32_t sigreturn_eip; + /// Address of the LIBC sigreturn function. + uint32_t sigreturn_addr; /// Pointer to the process’s signal handler descriptor sighand_t sighand; /// Mask of blocked signals. diff --git a/mentos/inc/system/signal.h b/mentos/inc/system/signal.h index 75da6c3..ab7b832 100644 --- a/mentos/inc/system/signal.h +++ b/mentos/inc/system/signal.h @@ -269,14 +269,14 @@ int sys_kill(pid_t pid, int sig); /// @param signum The signal number. /// @param handler The handler for the signal. /// @return The previous value of the signal handler, or SIG_ERR on error. -sighandler_t sys_signal(int signum, sighandler_t handler); +sighandler_t sys_signal(int signum, sighandler_t handler, uint32_t sigreturn_addr); /// @brief Examine and change a signal action. /// @param signum Specifies the signal and can be any valid signal except SIGKILL and SIGSTOP. /// @param act If non-NULL, the new action for signal signum is installed from act. /// @param oldact If non-NULL, the previous action is saved in oldact. /// @return returns 0 on success; on error, -1 is returned, and errno is set to indicate the error. -int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact); +int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact, uint32_t sigreturn_addr); /// @brief Examine and change blocked signals. /// @param how Determines the behavior of the call. diff --git a/mentos/src/elf/elf.c b/mentos/src/elf/elf.c index c485ce3..305191f 100644 --- a/mentos/src/elf/elf.c +++ b/mentos/src/elf/elf.c @@ -222,17 +222,6 @@ static inline void elf_dump_symbol_table(elf_header_t *header) // EXEC-RELATED FUNCTIONS // ============================================================================ -static inline int elf_set_sigreturn(elf_header_t *header, task_struct *task) -{ - elf_symbol_t *sigreturn = elf_find_symbol(header, "sigreturn"); - if (sigreturn == NULL) { - pr_err("Failed to find `sigreturn`!\n"); - return false; - } - task->sigreturn_eip = sigreturn->value; - return true; -} - /// @brief Loads an ELF executable. /// @param task The task for which we load the ELF. /// @param file The ELF file. @@ -311,11 +300,6 @@ int elf_load_file(task_struct *task, vfs_file_t *file, uint32_t *entry) pr_err("Elf file is not an executable.\n"); goto return_error_free_buffer; } - // Set the sigreturn of the task. - if (!elf_set_sigreturn(header, task)) { - pr_err("Failed to set `sigreturn` for the executable.\n"); - goto return_error_free_buffer; - } if (!elf_load_exec(header, task)) { pr_err("Failed to load the executable.\n"); goto return_error_free_buffer; diff --git a/mentos/src/fs/ext2.c b/mentos/src/fs/ext2.c index dd8ce09..bc64e20 100644 --- a/mentos/src/fs/ext2.c +++ b/mentos/src/fs/ext2.c @@ -10,7 +10,7 @@ /// Change the header. #define __DEBUG_HEADER__ "[EXT2 ]" /// Set the log level. -#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG +#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE #include "process/scheduler.h" #include "process/process.h" diff --git a/mentos/src/system/signal.c b/mentos/src/system/signal.c index e83eba0..8d6f7d7 100644 --- a/mentos/src/system/signal.c +++ b/mentos/src/system/signal.c @@ -300,7 +300,7 @@ static inline int __handle_signal(int signr, siginfo_t *info, sigaction_t *ka, s PUSH_VALUE_ON_STACK(regs->useresp, signr); // Push on the stack the function required to handle the signal return. - PUSH_VALUE_ON_STACK(regs->useresp, current->sigreturn_eip); + PUSH_VALUE_ON_STACK(regs->useresp, current->sigreturn_addr); return 1; } @@ -631,9 +631,9 @@ int sys_kill(pid_t pid, int sig) return __send_sig_info(sig, &info, current); } -sighandler_t sys_signal(int signum, sighandler_t handler) +sighandler_t sys_signal(int signum, sighandler_t handler, uint32_t sigreturn_addr) { - pr_debug("sys_signal(%d, %p)\n", signum, handler); + pr_debug("sys_signal(%d, %p, %p)\n", signum, handler, sigreturn_ptr); // Check the signal that we want to send. if ((signum < 0) || (signum >= NSIG)) { pr_err("sys_signal(%d, %p): Wrong signal number!\n", signum, handler); @@ -658,6 +658,8 @@ sighandler_t sys_signal(int signum, sighandler_t handler) sigemptyset(&new_sigaction.sa_mask); // Lock the signal handling for the given task. __lock_task_sighand(current); + // Set the address of the sigreturn. + current->sigreturn_addr = sigreturn_addr; // Get the old sigaction. sigaction_t *old_sigaction = ¤t->sighand.action[signum - 1]; pr_err("sys_signal(%d, %p): Signal action ptr %p\n", signum, handler, old_sigaction); @@ -672,9 +674,9 @@ sighandler_t sys_signal(int signum, sighandler_t handler) return old_handler; } -int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact) +int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact, uint32_t sigreturn_addr) { - pr_debug("sys_sigaction(%d, %p, %p)\n", signum, act, oldact); + pr_debug("sys_sigaction(%d, %p, %p, %p)\n", signum, act, oldact, sigreturn_ptr); // Check the signal that we want to send. if ((signum < 0) || (signum >= NSIG)) { pr_err("sys_sigaction(%d, %p, %p): Wrong signal number!\n", signum, act, oldact); @@ -691,6 +693,8 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact) } // Lock the signal handling for the given task. __lock_task_sighand(current); + // Set the address of the sigreturn. + current->sigreturn_addr = sigreturn_addr; // Get a pointer to the entry in the sighand.action array. sigaction_t *current_sigaction = ¤t->sighand.action[signum - 1]; pr_debug("sys_sigaction(%d, %p, %p): : Signal old action ptr %p\n", signum, act, oldact, current_sigaction);