| /* | 
 |  * 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> | 
 |  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> | 
 |  * Copyright (c) 2000 PocketPenguins Inc.  Linux for Hitachi SuperH | 
 |  *                    port by Greg Banks <gbanks@pocketpenguins.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 LINUX | 
 | #include <linux/mman.h> | 
 | #endif | 
 | #include <sys/mman.h> | 
 |  | 
 | #if defined(LINUX) && defined(I386) | 
 | #include <asm/ldt.h> | 
 | #endif | 
 | #if defined(LINUX) && defined(SH64) | 
 | #include <asm/page.h>	    /* for PAGE_SHIFT */ | 
 | #endif | 
 |  | 
 | #ifdef HAVE_LONG_LONG_OFF_T | 
 | /* | 
 |  * Ugly hacks for systems that have a long long off_t | 
 |  */ | 
 | #define sys_mmap64	sys_mmap | 
 | #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"	}, | 
 | #ifdef PROT_SEM | 
 | 	{ PROT_SEM,	"PROT_SEM"	}, | 
 | #endif | 
 | #ifdef PROT_GROWSDOWN | 
 | 	{ PROT_GROWSDOWN,"PROT_GROWSDOWN"}, | 
 | #endif | 
 | #ifdef PROT_GROWSUP | 
 | 	{ PROT_GROWSUP, "PROT_GROWSUP"	}, | 
 | #endif | 
 | 	{ 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_POPULATE | 
 | 	{ MAP_POPULATE, "MAP_POPULATE" }, | 
 | #endif | 
 | #ifdef MAP_NONBLOCK | 
 | 	{ MAP_NONBLOCK, "MAP_NONBLOCK" }, | 
 | #endif | 
 | 	/* | 
 | 	 * XXX - this was introduced in SunOS 4.x to distinguish between | 
 | 	 * the old pre-4.x "mmap()", which: | 
 | 	 * | 
 | 	 *	only let you map devices with an "mmap" routine (e.g., | 
 | 	 *	frame buffers) in; | 
 | 	 * | 
 | 	 *	required you to specify the mapping address; | 
 | 	 * | 
 | 	 *	returned 0 on success and -1 on failure; | 
 | 	 * | 
 | 	 * memory and which, and the 4.x "mmap()" which: | 
 | 	 * | 
 | 	 *	can map plain files; | 
 | 	 * | 
 | 	 *	can be asked to pick where to map the file; | 
 | 	 * | 
 | 	 *	returns the address where it mapped the file on success | 
 | 	 *	and -1 on failure. | 
 | 	 * | 
 | 	 * It's not actually used in source code that calls "mmap()"; the | 
 | 	 * "mmap()" routine adds it for you. | 
 | 	 * | 
 | 	 * It'd be nice to come up with some way of eliminating it from | 
 | 	 * the flags, e.g. reporting calls *without* it as "old_mmap()" | 
 | 	 * and calls with it as "mmap()". | 
 | 	 */ | 
 | #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_INHERIT | 
 | 	{ MAP_INHERIT,"MAP_INHERIT"	}, | 
 | #endif | 
 | #ifdef MAP_FILE | 
 | 	{ MAP_FILE,"MAP_FILE"}, | 
 | #endif | 
 | #ifdef MAP_LOCKED | 
 | 	{ MAP_LOCKED,"MAP_LOCKED"}, | 
 | #endif | 
 | 	/* FreeBSD ones */ | 
 | #ifdef MAP_ANON | 
 | 	{ MAP_ANON,		"MAP_ANON"	}, | 
 | #endif | 
 | #ifdef MAP_HASSEMAPHORE | 
 | 	{ MAP_HASSEMAPHORE,	"MAP_HASSEMAPHORE"	}, | 
 | #endif | 
 | #ifdef MAP_STACK | 
 | 	{ MAP_STACK,		"MAP_STACK"	}, | 
 | #endif | 
 | #ifdef MAP_NOSYNC | 
 | 	{ MAP_NOSYNC,		"MAP_NOSYNC"	}, | 
 | #endif | 
 | #ifdef MAP_NOCORE | 
 | 	{ MAP_NOCORE,		"MAP_NOCORE"	}, | 
 | #endif | 
 | 	{ 0,		NULL		}, | 
 | }; | 
 |  | 
 | #if !HAVE_LONG_LONG_OFF_T | 
 | static | 
 | int | 
 | print_mmap(tcp,u_arg) | 
 | struct tcb *tcp; | 
 | long *u_arg; | 
 | { | 
 | 	if (entering(tcp)) { | 
 | 		/* addr */ | 
 | 		if (!u_arg[0]) | 
 | 			tprintf("NULL, "); | 
 | 		else | 
 | 			tprintf("%#lx, ", u_arg[0]); | 
 | 		/* len */ | 
 | 		tprintf("%lu, ", u_arg[1]); | 
 | 		/* prot */ | 
 | 		printflags(mmap_prot, u_arg[2]); | 
 | 		tprintf(", "); | 
 | 		/* flags */ | 
 | #ifdef MAP_TYPE | 
 | 		printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???"); | 
 | 		addflags(mmap_flags, u_arg[3] & ~MAP_TYPE); | 
 | #else | 
 | 		printflags(mmap_flags, u_arg[3]); | 
 | #endif | 
 | 		/* fd (is always int, not long) */ | 
 | 		tprintf(", %d, ", (int)u_arg[4]); | 
 | 		/* offset */ | 
 | 		tprintf("%#lx", u_arg[5]); | 
 | 	} | 
 | 	return RVAL_HEX; | 
 | } | 
 |  | 
 | #ifdef LINUX | 
 | int sys_old_mmap(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 |     long u_arg[6]; | 
 |  | 
 | #if	defined(IA64) | 
 |     int i, v; | 
 |     /* | 
 |      *  IA64 processes never call this routine, they only use the | 
 |      *  new `sys_mmap' interface.  This code converts the integer | 
 |      *  arguments that the IA32 process pushed onto the stack into | 
 |      *  longs. | 
 |      * | 
 |      *  Note that addresses with bit 31 set will be sign extended. | 
 |      *  Fortunately, those addresses are not currently being generated | 
 |      *  for IA32 processes so it's not a problem. | 
 |      */ | 
 |     for (i = 0; i < 6; i++) | 
 | 	if (umove(tcp, tcp->u_arg[0] + (i * sizeof(int)), &v) == -1) | 
 | 		return 0; | 
 | 	else | 
 | 		u_arg[i] = v; | 
 | #elif defined(SH) || defined(SH64) | 
 |     /* SH has always passed the args in registers */ | 
 |     int i; | 
 |     for (i=0; i<6; i++) | 
 |         u_arg[i] = tcp->u_arg[i]; | 
 | #else | 
 |     if (umoven(tcp, tcp->u_arg[0], sizeof u_arg, (char *) u_arg) == -1) | 
 | 	    return 0; | 
 | #endif	// defined(IA64) | 
 |     return print_mmap(tcp, u_arg); | 
 |  | 
 | } | 
 | #endif | 
 |  | 
 | int | 
 | sys_mmap(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | #if defined(LINUX) && defined(SH64) | 
 |     /* | 
 |      * Old mmap differs from new mmap in specifying the | 
 |      * offset in units of bytes rather than pages.  We | 
 |      * pretend it's in byte units so the user only ever | 
 |      * sees bytes in the printout. | 
 |      */ | 
 |     tcp->u_arg[5] <<= PAGE_SHIFT; | 
 | #endif | 
 |     return print_mmap(tcp, tcp->u_arg); | 
 | } | 
 | #endif /* !HAVE_LONG_LONG_OFF_T */ | 
 |  | 
 | #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T | 
 | int | 
 | sys_mmap64(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | #ifdef linux | 
 | #ifdef ALPHA | 
 | 	long *u_arg = tcp->u_arg; | 
 | #else /* !ALPHA */ | 
 | 	long u_arg[7]; | 
 | #endif /* !ALPHA */ | 
 | #else /* !linux */ | 
 | 	long *u_arg = tcp->u_arg; | 
 | #endif /* !linux */ | 
 |  | 
 | 	if (entering(tcp)) { | 
 | #ifdef linux | 
 | #ifndef ALPHA | 
 | 		if (umoven(tcp, tcp->u_arg[0], sizeof u_arg, | 
 | 				(char *) u_arg) == -1) | 
 | 			return 0; | 
 | #endif /* ALPHA */ | 
 | #endif /* linux */ | 
 | 		ALIGN64 (tcp, 5);	/* FreeBSD wierdies */ | 
 |  | 
 | 		/* addr */ | 
 | 		tprintf("%#lx, ", u_arg[0]); | 
 | 		/* len */ | 
 | 		tprintf("%lu, ", u_arg[1]); | 
 | 		/* prot */ | 
 | 		printflags(mmap_prot, u_arg[2]); | 
 | 		tprintf(", "); | 
 | 		/* flags */ | 
 | #ifdef MAP_TYPE | 
 | 		printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???"); | 
 | 		addflags(mmap_flags, u_arg[3] & ~MAP_TYPE); | 
 | #else | 
 | 		printflags(mmap_flags, u_arg[3]); | 
 | #endif | 
 | 		/* fd */ | 
 | 		tprintf(", %ld, ", u_arg[4]); | 
 | 		/* offset */ | 
 | 		tprintf("%#llx", LONG_LONG(u_arg[5], u_arg[6])); | 
 | 	} | 
 | 	return RVAL_HEX; | 
 | } | 
 | #endif | 
 |  | 
 |  | 
 | 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 LINUX | 
 |  | 
 | static struct xlat mremap_flags[] = { | 
 | 	{ MREMAP_MAYMOVE,	"MREMAP_MAYMOVE"	}, | 
 | 	{ 0,			NULL			} | 
 | }; | 
 |  | 
 | int | 
 | sys_mremap(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | 	if (entering(tcp)) { | 
 | 		tprintf("%#lx, %lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1], | 
 | 			tcp->u_arg[2]); | 
 | 		printflags(mremap_flags, tcp->u_arg[3]); | 
 | 	} | 
 | 	return RVAL_HEX; | 
 | } | 
 |  | 
 | static struct xlat madvise_flags[] = { | 
 | #ifdef MADV_NORMAL | 
 | 	{ MADV_NORMAL,		"MADV_NORMAL" }, | 
 | #endif | 
 | #ifdef MADZV_RANDOM | 
 | 	{ MADV_RANDOM,		"MADV_RANDOM" }, | 
 | #endif | 
 | #ifdef MADV_SEQUENTIAL | 
 | 	{ MADV_SEQUENTIAL,	"MADV_SEQUENTIAL" }, | 
 | #endif | 
 | #ifdef MADV_WILLNEED | 
 | 	{ MADV_WILLNEED,	"MADV_WILLNEED" }, | 
 | #endif | 
 | #ifdef MADV_DONTNED | 
 | 	{ MADV_DONTNEED,	"MADV_DONTNEED" }, | 
 | #endif | 
 | 	{ 0,			NULL }, | 
 | }; | 
 |  | 
 |  | 
 | int | 
 | sys_madvise(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | 	if (entering(tcp)) { | 
 | 		tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); | 
 | 		printflags(madvise_flags, tcp->u_arg[2]); | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 |  | 
 | static struct xlat mlockall_flags[] = { | 
 | #ifdef MCL_CURRENT | 
 | 	{ MCL_CURRENT,	"MCL_CURRENT" }, | 
 | #endif | 
 | #ifdef MCL_FUTURE | 
 | 	{ MCL_FUTURE,	"MCL_FUTURE" }, | 
 | #endif | 
 | 	{ 0,		NULL} | 
 | }; | 
 |  | 
 | int | 
 | sys_mlockall(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | 	if (entering(tcp)) { | 
 | 		printflags(mlockall_flags, tcp->u_arg[0]); | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 |  | 
 | #endif /* LINUX */ | 
 |  | 
 | #ifdef MS_ASYNC | 
 |  | 
 | static struct xlat mctl_sync[] = { | 
 | #ifdef MS_SYNC | 
 | 	{ MS_SYNC,	"MS_SYNC"	}, | 
 | #endif | 
 | 	{ MS_ASYNC,	"MS_ASYNC"	}, | 
 | 	{ MS_INVALIDATE,"MS_INVALIDATE"	}, | 
 | 	{ 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__) | 
 | void | 
 | print_ldt_entry (ldt_entry) | 
 | struct modify_ldt_ldt_s *ldt_entry; | 
 | { | 
 | 	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}", | 
 | 		ldt_entry->base_addr, | 
 | 		ldt_entry->limit, | 
 | 		ldt_entry->seg_32bit, | 
 | 		ldt_entry->contents, | 
 | 		ldt_entry->read_exec_only, | 
 | 		ldt_entry->limit_in_pages, | 
 | 		ldt_entry->seg_not_present, | 
 | 		ldt_entry->useable); | 
 | } | 
 |  | 
 | 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 { | 
 | 				print_ldt_entry(©); | 
 | 			} | 
 | 		} | 
 | 		tprintf(", %lu", tcp->u_arg[2]); | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 | int | 
 | sys_set_thread_area(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | 	struct modify_ldt_ldt_s copy; | 
 | 	if (entering(tcp)) { | 
 | 		if (umove(tcp, tcp->u_arg[0], ©) != -1) { | 
 | 			if (copy.entry_number == -1) | 
 | 				tprintf("{entry_number:%d -> ", | 
 | 					copy.entry_number); | 
 | 			else | 
 | 				tprintf("{entry_number:"); | 
 | 		} | 
 | 	} else { | 
 | 		if (umove(tcp, tcp->u_arg[0], ©) != -1) { | 
 | 			tprintf("%d, ", copy.entry_number); | 
 | 			if (!verbose(tcp)) | 
 | 				tprintf("...}"); | 
 | 			else { | 
 | 				print_ldt_entry(©); | 
 | 			} | 
 | 		} else { | 
 | 			tprintf("%lx", tcp->u_arg[0]); | 
 | 		} | 
 | 	} | 
 | 	return 0; | 
 |  | 
 | } | 
 |  | 
 | int | 
 | sys_get_thread_area(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | 	struct modify_ldt_ldt_s copy; | 
 | 	if (exiting(tcp)) { | 
 | 		if (umove(tcp, tcp->u_arg[0], ©) != -1) { | 
 | 			tprintf("{entry_number:%d, ", copy.entry_number); | 
 | 			if (!verbose(tcp)) | 
 | 				tprintf("...}"); | 
 | 			else { | 
 | 				print_ldt_entry(©); | 
 | 			} | 
 | 		} else { | 
 | 			tprintf("%lx", tcp->u_arg[0]); | 
 | 		} | 
 | 	} | 
 | 	return 0; | 
 |  | 
 | } | 
 | #endif /* LINUX && __i386__ */ | 
 |  | 
 | #if defined(LINUX) | 
 | int | 
 | sys_remap_file_pages(tcp) | 
 | struct tcb *tcp; | 
 | { | 
 | 	if (entering(tcp)) { | 
 | 		tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); | 
 | 		printflags(mmap_prot, tcp->u_arg[2]); | 
 | 		tprintf(", %lu, ", tcp->u_arg[3]); | 
 | #ifdef MAP_TYPE | 
 | 		printxval(mmap_flags, tcp->u_arg[4] & MAP_TYPE, "MAP_???"); | 
 | 		addflags(mmap_flags, tcp->u_arg[4] & ~MAP_TYPE); | 
 | #else | 
 | 		printflags(mmap_flags, tcp->u_arg[4]); | 
 | #endif | 
 | 	} | 
 | 	return 0; | 
 | } | 
 | #endif |