From: Alan Cox Date: Wed, 17 Feb 2016 21:47:47 +0000 (+0000) Subject: exec: add core dump support X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=8a431429227092e1b13c29bb44f12da11989f976;p=FUZIX.git exec: add core dump support This adds some minimalistic core dump support to the 16bit code base. --- diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index c5ad4ca3..ee540125 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -47,6 +47,8 @@ From UZI by Doug Braun and UZI280 by Stefan Nitschke. (udata.u_ptab->p_uid == (p)->p_uid || super()) #define pathbuf() tmpbuf() #define pathfree(tb) brelse(tb) +#define dump_core(sig) + #endif #define CPM_EMULATOR_FILENAME "/usr/cpm/emulator" @@ -445,6 +447,8 @@ typedef struct u_data { #ifdef CONFIG_LEVEL_2 uint16_t u_groups[NGROUP]; /* Group list */ uint8_t u_ngroup; + uint8_t u_flags; +#define U_FLAG_NOCORE 1 /* Set if no core dump */ struct rlimit u_rlimit[NRLIMIT]; /* Resource limits */ #endif } u_data; diff --git a/Kernel/include/level2.h b/Kernel/include/level2.h index 35f45c41..3aa77cf0 100644 --- a/Kernel/include/level2.h +++ b/Kernel/include/level2.h @@ -60,4 +60,21 @@ extern arg_t _setpgid(void); extern arg_t _setsid(void); extern arg_t _getsid(void); +/* Provided by the execve support */ +extern void write_core_image(void); + +/* This will change a lot in future ! */ +struct coredump { + uint16_t ch_magic1; +#define MAGIC1 0xDEAD + uint16_t ch_magic2; +#define MAGIC2 0xC0DE + uint8_t ch_type; /* For now 16 or 32 bit number of bits - will + change! */ + uint32_t ch_base; + uint32_t ch_break; + uint32_t ch_sp; + uint32_t ch_top; +}; + #endif diff --git a/Kernel/process.c b/Kernel/process.c index 38eb74c5..dec30727 100644 --- a/Kernel/process.c +++ b/Kernel/process.c @@ -433,6 +433,18 @@ void sgrpsig(uint16_t pgrp, uint8_t sig) } } +#ifdef CONFIG_LEVEL_2 +static void dump_core(uint8_t sig) +{ + if (!(udata.u_flags & U_FLAG_NOCORE) && ((sig == SIGQUIT || sig == SIGILL || sig == SIGTRAP || + sig == SIGABRT || sig == SIGBUS || sig == SIGFPE || + sig == SIGSEGV || sig == SIGXCPU || sig == SIGXFSZ || + sig == SIGSYS))) { + write_core_image(); + } +} +#endif + /* This sees if the current process has any signals set, and handles them. */ void chksigs(void) @@ -477,6 +489,7 @@ void chksigs(void) #ifdef DEBUG kprintf("process terminated by signal %d\n", j); #endif + dump_core(j); doexit((uint16_t)j << 8); } else if (*svec != SIG_IGN) { /* Arrange to call the user routine at return */ diff --git a/Kernel/syscall_exec16.c b/Kernel/syscall_exec16.c index 46e77e67..aa477874 100644 --- a/Kernel/syscall_exec16.c +++ b/Kernel/syscall_exec16.c @@ -111,6 +111,15 @@ arg_t _execve(void) goto nogood; } + /* Core dump and ptrace permission logic */ +#ifdef CONFIG_LEVEL_2 + if ((!getperm(ino) & OTH_RD) || + (ino->c_node.i_mode & (SET_UID | SET_GID))) + udata.u_flags |= U_FLAG_NOCORE; + else + udata.u_flags &= ~U_FLAG_NOCORE; +#endif + setftime(ino, A_TIME); if (ino->c_node.i_size == 0) { @@ -334,3 +343,56 @@ arg_t _memfree(void) udata.u_error = ENOMEM; return -1; } + +#ifdef CONFIG_LEVEL_2 + +/* + * Core dump + */ + +static struct coredump corehdr = { + 0xDEAD, + 0xC0DE, + 16, +}; + +void write_core_image(void) +{ + inoptr parent = NULLINODE; + inoptr ino; + + ino = kn_open("core", &parent); + if (ino) { + i_deref(parent); + return; + } + if (parent && (ino = newfile(parent, "core"))) { + ino->c_node.i_mode = F_REG | 0400; + setftime(ino, A_TIME | M_TIME | C_TIME); + wr_inode(ino); + f_trunc(ino); + + /* FIXME: need to add some arch specific header bits, and + also pull stuff like the true sp and registers out of + the return stack properly */ + + corehdr.ch_base = MAPBASE; + corehdr.ch_break = udata.u_break; + corehdr.ch_sp = udata.u_syscall_sp; + corehdr.ch_top = PROGTOP; + udata.u_offset = 0; + udata.u_base = (uint8_t *)&corehdr; + udata.u_sysio = true; + udata.u_count = sizeof(corehdr); + writei(ino, 0); + udata.u_sysio = false; + udata.u_base = MAPBASE; + udata.u_count = udata.u_break - MAPBASE; + writei(ino, 0); + udata.u_base = udata.u_sp; + udata.u_count = PROGTOP - udata.u_sp; + writei(ino, 0); + i_deref(ino); + } +} +#endif