(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"
#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;
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
}
}
+#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)
#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 */
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) {
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