diff options
Diffstat (limited to 'mem.c')
-rw-r--r-- | mem.c | 338 |
1 files changed, 338 insertions, 0 deletions
@@ -0,0 +1,338 @@ +/* + * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> + * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> + * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include "defs.h" + +#ifdef LINUXSPARC +#include <linux/mman.h> +#else +#include <sys/mman.h> +#endif +#if defined(LINUX) && defined(__i386__) +#include <asm/ldt.h> +#endif + +int +sys_brk(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%#lx", tcp->u_arg[0]); + } +#ifdef linux + return RVAL_HEX; +#else + return 0; +#endif +} + +int +sys_sbrk(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%lu", tcp->u_arg[0]); + } + return RVAL_HEX; +} + +static struct xlat mmap_prot[] = { + { PROT_NONE, "PROT_NONE", }, + { PROT_READ, "PROT_READ" }, + { PROT_WRITE, "PROT_WRITE" }, + { PROT_EXEC, "PROT_EXEC" }, + { 0, NULL }, +}; + +static struct xlat mmap_flags[] = { + { MAP_SHARED, "MAP_SHARED" }, + { MAP_PRIVATE, "MAP_PRIVATE" }, + { MAP_FIXED, "MAP_FIXED" }, +#ifdef MAP_ANONYMOUS + { MAP_ANONYMOUS,"MAP_ANONYMOUS" }, +#endif +#ifdef MAP_RENAME + { MAP_RENAME, "MAP_RENAME" }, +#endif +#ifdef MAP_NORESERVE + { MAP_NORESERVE,"MAP_NORESERVE" }, +#endif +#ifdef _MAP_NEW + { _MAP_NEW, "_MAP_NEW" }, +#endif +#ifdef MAP_GROWSDOWN + { MAP_GROWSDOWN,"MAP_GROWSDOWN" }, +#endif +#ifdef MAP_DENYWRITE + { MAP_DENYWRITE,"MAP_DENYWRITE" }, +#endif +#ifdef MAP_EXECUTABLE + { MAP_EXECUTABLE,"MAP_EXECUTABLE"}, +#endif +#ifdef MAP_FILE + { MAP_FILE,"MAP_FILE"}, +#endif +#ifdef MAP_LOCKED + { MAP_LOCKED,"MAP_LOCKED"}, +#endif + { 0, NULL }, +}; + +int +sys_mmap(tcp) +struct tcb *tcp; +{ +#ifdef LINUX +#if defined(ALPHA) || defined(sparc) + long *u_arg = tcp->u_arg; +#else /* !ALPHA */ + long u_arg[6]; +#endif /* !ALPHA */ +#else /* !LINUX */ + long *u_arg = tcp->u_arg; +#endif /* !LINUX */ + + if (entering(tcp)) { +#ifdef LINUX +#if !defined(ALPHA) && !defined(__sparc__) + if (umoven(tcp, tcp->u_arg[0], sizeof u_arg, + (char *) u_arg) == -1) + return 0; +#endif /* ALPHA/sparc */ +#endif /* LINUX */ + + /* addr */ + tprintf("%#lx, ", u_arg[0]); + /* len */ + tprintf("%lu, ", u_arg[1]); + /* prot */ + printflags(mmap_prot, u_arg[2]); + tprintf(", "); + /* flags */ + printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???"); + addflags(mmap_flags, u_arg[3] & ~MAP_TYPE); + /* fd */ + tprintf(", %ld, ", u_arg[4]); + /* offset */ + tprintf("%#lx", u_arg[5]); + } + return RVAL_HEX; +} + +int +sys_munmap(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%#lx, %lu", + tcp->u_arg[0], tcp->u_arg[1]); + } + return 0; +} + +int +sys_mprotect(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + tprintf("%#lx, %lu, ", + tcp->u_arg[0], tcp->u_arg[1]); + if (!printflags(mmap_prot, tcp->u_arg[2])) + tprintf("PROT_???"); + } + return 0; +} + +#ifdef MS_ASYNC + +static struct xlat mctl_sync[] = { + { MS_ASYNC, "MS_ASYNC" }, + { MS_INVALIDATE,"MS_INVALIDATE" }, +#ifdef MS_SYNC + { MS_SYNC, "MS_SYNC" }, +#endif + { 0, NULL }, +}; + +int +sys_msync(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + /* addr */ + tprintf("%#lx", tcp->u_arg[0]); + /* len */ + tprintf(", %lu, ", tcp->u_arg[1]); + /* flags */ + if (!printflags(mctl_sync, tcp->u_arg[2])) + tprintf("MS_???"); + } + return 0; +} + +#endif /* MS_ASYNC */ + +#ifdef MC_SYNC + +static struct xlat mctl_funcs[] = { + { MC_LOCK, "MC_LOCK" }, + { MC_LOCKAS, "MC_LOCKAS" }, + { MC_SYNC, "MC_SYNC" }, + { MC_UNLOCK, "MC_UNLOCK" }, + { MC_UNLOCKAS, "MC_UNLOCKAS" }, + { 0, NULL }, +}; + +static struct xlat mctl_lockas[] = { + { MCL_CURRENT, "MCL_CURRENT" }, + { MCL_FUTURE, "MCL_FUTURE" }, + { 0, NULL }, +}; + +int +sys_mctl(tcp) +struct tcb *tcp; +{ + int arg, function; + + if (entering(tcp)) { + /* addr */ + tprintf("%#lx", tcp->u_arg[0]); + /* len */ + tprintf(", %lu, ", tcp->u_arg[1]); + /* function */ + function = tcp->u_arg[2]; + if (!printflags(mctl_funcs, function)) + tprintf("MC_???"); + /* arg */ + arg = tcp->u_arg[3]; + tprintf(", "); + switch (function) { + case MC_SYNC: + if (!printflags(mctl_sync, arg)) + tprintf("MS_???"); + break; + case MC_LOCKAS: + if (!printflags(mctl_lockas, arg)) + tprintf("MCL_???"); + break; + default: + tprintf("%#x", arg); + break; + } + } + return 0; +} + +#endif /* MC_SYNC */ + +int +sys_mincore(tcp) +struct tcb *tcp; +{ + int i, len; + char *vec = NULL; + + if (entering(tcp)) { + tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); + } else { + len = tcp->u_arg[1]; + if (syserror(tcp) || tcp->u_arg[2] == 0 || + (vec = malloc((u_int)len)) == NULL || + umoven(tcp, tcp->u_arg[2], len, vec) < 0) + tprintf("%#lx", tcp->u_arg[2]); + else { + tprintf("["); + for (i = 0; i < len; i++) { + if (abbrev(tcp) && i >= max_strlen) { + tprintf("..."); + break; + } + tprintf((vec[i] & 1) ? "1" : "0"); + } + tprintf("]"); + } + if (vec) + free(vec); + } + return 0; +} + +int +sys_getpagesize(tcp) +struct tcb *tcp; +{ + if (exiting(tcp)) + return RVAL_HEX; + return 0; +} + +#if defined(LINUX) && defined(__i386__) +int +sys_modify_ldt(tcp) +struct tcb *tcp; +{ + if (entering(tcp)) { + struct modify_ldt_ldt_s copy; + tprintf("%ld", tcp->u_arg[0]); + if (tcp->u_arg[1] == 0 + || tcp->u_arg[2] != sizeof (struct modify_ldt_ldt_s) + || umove(tcp, tcp->u_arg[1], ©) == -1) + tprintf(", %lx", tcp->u_arg[1]); + else { + tprintf(", {entry_number:%d, ", copy.entry_number); + if (!verbose(tcp)) + tprintf("...}"); + else { + tprintf("base_addr:%#08lx, " + "limit:%d, " + "seg_32bit:%d, " + "contents:%d, " + "read_exec_only:%d, " + "limit_in_pages:%d, " + "seg_not_present:%d, " + "useable:%d}", + copy.base_addr, + copy.limit, + copy.seg_32bit, + copy.contents, + copy.read_exec_only, + copy.limit_in_pages, + copy.seg_not_present, + copy.useable); + } + } + tprintf(", %lu", tcp->u_arg[2]); + } + return 0; +} +#endif /* LINUX && __i386__ */ + |