Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl>
      3  * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl>
      4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com>
      5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl>
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. The name of the author may not be used to endorse or promote products
     17  *    derived from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "defs.h"
     32 
     33 #define _LINUX_SOCKET_H
     34 #define _LINUX_FS_H
     35 
     36 #define MS_RDONLY	 1	/* Mount read-only */
     37 #define MS_NOSUID	 2	/* Ignore suid and sgid bits */
     38 #define MS_NODEV	 4	/* Disallow access to device special files */
     39 #define MS_NOEXEC	 8	/* Disallow program execution */
     40 #define MS_SYNCHRONOUS	16	/* Writes are synced at once */
     41 #define MS_REMOUNT	32	/* Alter flags of a mounted FS */
     42 #define MS_MANDLOCK	64	/* Allow mandatory locks on an FS */
     43 #define MS_DIRSYNC	128	/* Directory modifications are synchronous */
     44 #define MS_NOATIME	1024	/* Do not update access times. */
     45 #define MS_NODIRATIME	2048	/* Do not update directory access times */
     46 #define MS_BIND		4096
     47 #define MS_MOVE		8192
     48 #define MS_REC		16384
     49 #define MS_SILENT	32768
     50 #define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
     51 #define MS_UNBINDABLE	(1<<17)	/* change to unbindable */
     52 #define MS_PRIVATE	(1<<18)	/* change to private */
     53 #define MS_SLAVE	(1<<19)	/* change to slave */
     54 #define MS_SHARED	(1<<20)	/* change to shared */
     55 #define MS_RELATIME	(1<<21)
     56 #define MS_KERNMOUNT	(1<<22)
     57 #define MS_I_VERSION	(1<<23)
     58 #define MS_STRICTATIME	(1<<24)
     59 #define MS_NOSEC	(1<<28)
     60 #define MS_BORN		(1<<29)
     61 #define MS_ACTIVE	(1<<30)
     62 #define MS_NOUSER	(1<<31)
     63 #define MS_MGC_VAL	0xc0ed0000	/* Magic flag number */
     64 #define MS_MGC_MSK	0xffff0000	/* Magic flag mask */
     65 
     66 #include <sys/socket.h>
     67 #include <netinet/in.h>
     68 #include <arpa/inet.h>
     69 #ifdef HAVE_LINUX_CAPABILITY_H
     70 # include <linux/capability.h>
     71 #endif
     72 #ifdef HAVE_ASM_CACHECTL_H
     73 # include <asm/cachectl.h>
     74 #endif
     75 #ifdef HAVE_LINUX_USTNAME_H
     76 # include <linux/utsname.h>
     77 #endif
     78 #ifdef HAVE_ASM_SYSMIPS_H
     79 # include <asm/sysmips.h>
     80 #endif
     81 #include <linux/sysctl.h>
     82 #include <linux/personality.h>
     83 
     84 #include "xlat/mount_flags.h"
     85 
     86 int
     87 sys_mount(struct tcb *tcp)
     88 {
     89 	if (entering(tcp)) {
     90 		int ignore_type = 0, ignore_data = 0;
     91 		unsigned long flags = tcp->u_arg[3];
     92 
     93 		/* Discard magic */
     94 		if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
     95 			flags &= ~MS_MGC_MSK;
     96 
     97 		if (flags & MS_REMOUNT)
     98 			ignore_type = 1;
     99 		else if (flags & (MS_BIND | MS_MOVE))
    100 			ignore_type = ignore_data = 1;
    101 
    102 		printpath(tcp, tcp->u_arg[0]);
    103 		tprints(", ");
    104 
    105 		printpath(tcp, tcp->u_arg[1]);
    106 		tprints(", ");
    107 
    108 		if (ignore_type && tcp->u_arg[2])
    109 			tprintf("%#lx", tcp->u_arg[2]);
    110 		else
    111 			printstr(tcp, tcp->u_arg[2], -1);
    112 		tprints(", ");
    113 
    114 		printflags(mount_flags, tcp->u_arg[3], "MS_???");
    115 		tprints(", ");
    116 
    117 		if (ignore_data && tcp->u_arg[4])
    118 			tprintf("%#lx", tcp->u_arg[4]);
    119 		else
    120 			printstr(tcp, tcp->u_arg[4], -1);
    121 	}
    122 	return 0;
    123 }
    124 
    125 #define MNT_FORCE	0x00000001	/* Attempt to forcibily umount */
    126 #define MNT_DETACH	0x00000002	/* Just detach from the tree */
    127 #define MNT_EXPIRE	0x00000004	/* Mark for expiry */
    128 
    129 #include "xlat/umount_flags.h"
    130 
    131 int
    132 sys_umount2(struct tcb *tcp)
    133 {
    134 	if (entering(tcp)) {
    135 		printstr(tcp, tcp->u_arg[0], -1);
    136 		tprints(", ");
    137 		printflags(umount_flags, tcp->u_arg[1], "MNT_???");
    138 	}
    139 	return 0;
    140 }
    141 
    142 /* These are not macros, but enums.  We just copy the values by hand
    143    from Linux 2.6.9 here.  */
    144 #include "xlat/personality_options.h"
    145 
    146 int
    147 sys_personality(struct tcb *tcp)
    148 {
    149 	if (entering(tcp))
    150 		printxval(personality_options, tcp->u_arg[0], "PER_???");
    151 	return 0;
    152 }
    153 
    154 enum {
    155 	SYSLOG_ACTION_CLOSE = 0,
    156 	SYSLOG_ACTION_OPEN,
    157 	SYSLOG_ACTION_READ,
    158 	SYSLOG_ACTION_READ_ALL,
    159 	SYSLOG_ACTION_READ_CLEAR,
    160 	SYSLOG_ACTION_CLEAR,
    161 	SYSLOG_ACTION_CONSOLE_OFF,
    162 	SYSLOG_ACTION_CONSOLE_ON,
    163 	SYSLOG_ACTION_CONSOLE_LEVEL,
    164 	SYSLOG_ACTION_SIZE_UNREAD,
    165 	SYSLOG_ACTION_SIZE_BUFFER
    166 };
    167 
    168 #include "xlat/syslog_action_type.h"
    169 
    170 int
    171 sys_syslog(struct tcb *tcp)
    172 {
    173 	int type = tcp->u_arg[0];
    174 
    175 	if (entering(tcp)) {
    176 		/* type */
    177 		printxval(syslog_action_type, type, "SYSLOG_ACTION_???");
    178 		tprints(", ");
    179 	}
    180 
    181 	switch (type) {
    182 		case SYSLOG_ACTION_READ:
    183 		case SYSLOG_ACTION_READ_ALL:
    184 		case SYSLOG_ACTION_READ_CLEAR:
    185 			if (entering(tcp))
    186 				return 0;
    187 			break;
    188 		default:
    189 			if (entering(tcp)) {
    190 				tprintf("%#lx, %lu",
    191 					tcp->u_arg[1], tcp->u_arg[2]);
    192 			}
    193 			return 0;
    194 	}
    195 
    196 	/* bufp */
    197 	if (syserror(tcp))
    198 		tprintf("%#lx", tcp->u_arg[1]);
    199 	else
    200 		printstr(tcp, tcp->u_arg[1], tcp->u_rval);
    201 	/* len */
    202 	tprintf(", %d", (int) tcp->u_arg[2]);
    203 
    204 	return 0;
    205 }
    206 
    207 #ifdef M68K
    208 #include "xlat/cacheflush_scope.h"
    209 
    210 static const struct xlat cacheflush_flags[] = {
    211 #ifdef FLUSH_CACHE_BOTH
    212 	XLAT(FLUSH_CACHE_BOTH),
    213 #endif
    214 #ifdef FLUSH_CACHE_DATA
    215 	XLAT(FLUSH_CACHE_DATA),
    216 #endif
    217 #ifdef FLUSH_CACHE_INSN
    218 	XLAT(FLUSH_CACHE_INSN),
    219 #endif
    220 	XLAT_END
    221 };
    222 
    223 int
    224 sys_cacheflush(struct tcb *tcp)
    225 {
    226 	if (entering(tcp)) {
    227 		/* addr */
    228 		tprintf("%#lx, ", tcp->u_arg[0]);
    229 		/* scope */
    230 		printxval(cacheflush_scope, tcp->u_arg[1], "FLUSH_SCOPE_???");
    231 		tprints(", ");
    232 		/* flags */
    233 		printflags(cacheflush_flags, tcp->u_arg[2], "FLUSH_CACHE_???");
    234 		/* len */
    235 		tprintf(", %lu", tcp->u_arg[3]);
    236 	}
    237 	return 0;
    238 }
    239 #endif /* M68K */
    240 
    241 #ifdef BFIN
    242 
    243 #include <bfin_sram.h>
    244 
    245 #include "xlat/sram_alloc_flags.h"
    246 
    247 int
    248 sys_sram_alloc(struct tcb *tcp)
    249 {
    250 	if (entering(tcp)) {
    251 		/* size */
    252 		tprintf("%lu, ", tcp->u_arg[0]);
    253 		/* flags */
    254 		printflags(sram_alloc_flags, tcp->u_arg[1], "???_SRAM");
    255 	}
    256 	return 1;
    257 }
    258 
    259 #include <asm/cachectl.h>
    260 
    261 static const struct xlat cacheflush_flags[] = {
    262 	XLAT(ICACHE),
    263 	XLAT(DCACHE),
    264 	XLAT(BCACHE),
    265 	XLAT_END
    266 };
    267 
    268 int
    269 sys_cacheflush(struct tcb *tcp)
    270 {
    271 	if (entering(tcp)) {
    272 		/* start addr */
    273 		tprintf("%#lx, ", tcp->u_arg[0]);
    274 		/* length */
    275 		tprintf("%ld, ", tcp->u_arg[1]);
    276 		/* flags */
    277 		printxval(cacheflush_flags, tcp->u_arg[1], "?CACHE");
    278 	}
    279 	return 0;
    280 }
    281 
    282 #endif
    283 
    284 #ifdef SH
    285 static const struct xlat cacheflush_flags[] = {
    286 #ifdef CACHEFLUSH_D_INVAL
    287 	XLAT(CACHEFLUSH_D_INVAL),
    288 #endif
    289 #ifdef CACHEFLUSH_D_WB
    290 	XLAT(CACHEFLUSH_D_WB),
    291 #endif
    292 #ifdef CACHEFLUSH_D_PURGE
    293 	XLAT(CACHEFLUSH_D_PURGE),
    294 #endif
    295 #ifdef CACHEFLUSH_I
    296 	XLAT(CACHEFLUSH_I),
    297 #endif
    298 	XLAT_END
    299 };
    300 
    301 int
    302 sys_cacheflush(struct tcb *tcp)
    303 {
    304 	if (entering(tcp)) {
    305 		/* addr */
    306 		tprintf("%#lx, ", tcp->u_arg[0]);
    307 		/* len */
    308 		tprintf("%lu, ", tcp->u_arg[1]);
    309 		/* flags */
    310 		printflags(cacheflush_flags, tcp->u_arg[2], "CACHEFLUSH_???");
    311 	}
    312 	return 0;
    313 }
    314 #endif /* SH */
    315 
    316 #ifdef SYS_capget
    317 
    318 #include "xlat/capabilities.h"
    319 
    320 #ifndef _LINUX_CAPABILITY_VERSION_1
    321 # define _LINUX_CAPABILITY_VERSION_1 0x19980330
    322 #endif
    323 #ifndef _LINUX_CAPABILITY_VERSION_2
    324 # define _LINUX_CAPABILITY_VERSION_2 0x20071026
    325 #endif
    326 #ifndef _LINUX_CAPABILITY_VERSION_3
    327 # define _LINUX_CAPABILITY_VERSION_3 0x20080522
    328 #endif
    329 
    330 #include "xlat/cap_version.h"
    331 
    332 static void
    333 print_cap_header(struct tcb *tcp, unsigned long addr)
    334 {
    335 	union { cap_user_header_t p; long *a; char *c; } arg;
    336 	long a[sizeof(*arg.p) / sizeof(long) + 1];
    337 	arg.a = a;
    338 
    339 	if (!addr)
    340 		tprints("NULL");
    341 	else if (!verbose(tcp) ||
    342 		 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
    343 		tprintf("%#lx", addr);
    344 	else {
    345 		tprints("{");
    346 		printxval(cap_version, arg.p->version,
    347 			  "_LINUX_CAPABILITY_VERSION_???");
    348 		tprintf(", %d}", arg.p->pid);
    349 	}
    350 }
    351 
    352 static void
    353 print_cap_data(struct tcb *tcp, unsigned long addr)
    354 {
    355 	union { cap_user_data_t p; long *a; char *c; } arg;
    356 	long a[sizeof(*arg.p) / sizeof(long) + 1];
    357 	arg.a = a;
    358 
    359 	if (!addr)
    360 		tprints("NULL");
    361 	else if (!verbose(tcp) ||
    362 		 (exiting(tcp) && syserror(tcp)) ||
    363 		 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
    364 		tprintf("%#lx", addr);
    365 	else {
    366 		tprints("{");
    367 		printflags(capabilities, arg.p->effective, "CAP_???");
    368 		tprints(", ");
    369 		printflags(capabilities, arg.p->permitted, "CAP_???");
    370 		tprints(", ");
    371 		printflags(capabilities, arg.p->inheritable, "CAP_???");
    372 		tprints("}");
    373 	}
    374 }
    375 
    376 int
    377 sys_capget(struct tcb *tcp)
    378 {
    379 	if (entering(tcp)) {
    380 		print_cap_header(tcp, tcp->u_arg[0]);
    381 		tprints(", ");
    382 	} else {
    383 		print_cap_data(tcp, tcp->u_arg[1]);
    384 	}
    385 	return 0;
    386 }
    387 
    388 int
    389 sys_capset(struct tcb *tcp)
    390 {
    391 	if (entering(tcp)) {
    392 		print_cap_header(tcp, tcp->u_arg[0]);
    393 		tprints(", ");
    394 		print_cap_data(tcp, tcp->u_arg[1]);
    395 	}
    396 	return 0;
    397 }
    398 
    399 #else
    400 
    401 int sys_capget(struct tcb *tcp)
    402 {
    403 	return printargs(tcp);
    404 }
    405 
    406 int sys_capset(struct tcb *tcp)
    407 {
    408 	return printargs(tcp);
    409 }
    410 
    411 #endif
    412 
    413 #include "xlat/sysctl_root.h"
    414 #include "xlat/sysctl_kern.h"
    415 #include "xlat/sysctl_vm.h"
    416 #include "xlat/sysctl_net.h"
    417 #include "xlat/sysctl_net_core.h"
    418 #include "xlat/sysctl_net_unix.h"
    419 #include "xlat/sysctl_net_ipv4.h"
    420 #include "xlat/sysctl_net_ipv4_route.h"
    421 #include "xlat/sysctl_net_ipv4_conf.h"
    422 #include "xlat/sysctl_net_ipv6.h"
    423 #include "xlat/sysctl_net_ipv6_route.h"
    424 
    425 int
    426 sys_sysctl(struct tcb *tcp)
    427 {
    428 	struct __sysctl_args info;
    429 	int *name;
    430 	unsigned long size;
    431 
    432 	if (umove(tcp, tcp->u_arg[0], &info) < 0)
    433 		return printargs(tcp);
    434 
    435 	size = sizeof(int) * (unsigned long) info.nlen;
    436 	name = (size / sizeof(int) != info.nlen) ? NULL : malloc(size);
    437 	if (name == NULL ||
    438 	    umoven(tcp, (unsigned long) info.name, size, (char *) name) < 0) {
    439 		free(name);
    440 		if (entering(tcp))
    441 			tprintf("{%p, %d, %p, %p, %p, %lu}",
    442 				info.name, info.nlen, info.oldval,
    443 				info.oldlenp, info.newval, (unsigned long)info.newlen);
    444 		return 0;
    445 	}
    446 
    447 	if (entering(tcp)) {
    448 		int cnt = 0, max_cnt;
    449 
    450 		tprints("{{");
    451 
    452 		if (info.nlen == 0)
    453 			goto out;
    454 		printxval(sysctl_root, name[0], "CTL_???");
    455 		++cnt;
    456 
    457 		if (info.nlen == 1)
    458 			goto out;
    459 		switch (name[0]) {
    460 		case CTL_KERN:
    461 			tprints(", ");
    462 			printxval(sysctl_kern, name[1], "KERN_???");
    463 			++cnt;
    464 			break;
    465 		case CTL_VM:
    466 			tprints(", ");
    467 			printxval(sysctl_vm, name[1], "VM_???");
    468 			++cnt;
    469 			break;
    470 		case CTL_NET:
    471 			tprints(", ");
    472 			printxval(sysctl_net, name[1], "NET_???");
    473 			++cnt;
    474 
    475 			if (info.nlen == 2)
    476 				goto out;
    477 			switch (name[1]) {
    478 			case NET_CORE:
    479 				tprints(", ");
    480 				printxval(sysctl_net_core, name[2],
    481 					  "NET_CORE_???");
    482 				break;
    483 			case NET_UNIX:
    484 				tprints(", ");
    485 				printxval(sysctl_net_unix, name[2],
    486 					  "NET_UNIX_???");
    487 				break;
    488 			case NET_IPV4:
    489 				tprints(", ");
    490 				printxval(sysctl_net_ipv4, name[2],
    491 					  "NET_IPV4_???");
    492 
    493 				if (info.nlen == 3)
    494 					goto out;
    495 				switch (name[2]) {
    496 				case NET_IPV4_ROUTE:
    497 					tprints(", ");
    498 					printxval(sysctl_net_ipv4_route,
    499 						  name[3],
    500 						  "NET_IPV4_ROUTE_???");
    501 					break;
    502 				case NET_IPV4_CONF:
    503 					tprints(", ");
    504 					printxval(sysctl_net_ipv4_conf,
    505 						  name[3],
    506 						  "NET_IPV4_CONF_???");
    507 					break;
    508 				default:
    509 					goto out;
    510 				}
    511 				break;
    512 			case NET_IPV6:
    513 				tprints(", ");
    514 				printxval(sysctl_net_ipv6, name[2],
    515 					  "NET_IPV6_???");
    516 
    517 				if (info.nlen == 3)
    518 					goto out;
    519 				switch (name[2]) {
    520 				case NET_IPV6_ROUTE:
    521 					tprints(", ");
    522 					printxval(sysctl_net_ipv6_route,
    523 						  name[3],
    524 						  "NET_IPV6_ROUTE_???");
    525 					break;
    526 				default:
    527 					goto out;
    528 				}
    529 				break;
    530 			default:
    531 				goto out;
    532 			}
    533 			break;
    534 		default:
    535 			goto out;
    536 		}
    537 	out:
    538 		max_cnt = info.nlen;
    539 		if (abbrev(tcp) && max_cnt > max_strlen)
    540 			max_cnt = max_strlen;
    541 		while (cnt < max_cnt)
    542 			tprintf(", %x", name[cnt++]);
    543 		if (cnt < info.nlen)
    544 			tprints(", ...");
    545 		tprintf("}, %d, ", info.nlen);
    546 	} else {
    547 		size_t oldlen = 0;
    548 		if (info.oldval == NULL) {
    549 			tprints("NULL");
    550 		} else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0
    551 			   && info.nlen >= 2
    552 			   && ((name[0] == CTL_KERN
    553 				&& (name[1] == KERN_OSRELEASE
    554 				    || name[1] == KERN_OSTYPE
    555 #ifdef KERN_JAVA_INTERPRETER
    556 				    || name[1] == KERN_JAVA_INTERPRETER
    557 #endif
    558 #ifdef KERN_JAVA_APPLETVIEWER
    559 				    || name[1] == KERN_JAVA_APPLETVIEWER
    560 #endif
    561 					)))) {
    562 			printpath(tcp, (size_t)info.oldval);
    563 		} else {
    564 			tprintf("%p", info.oldval);
    565 		}
    566 		tprintf(", %lu, ", (unsigned long)oldlen);
    567 		if (info.newval == NULL)
    568 			tprints("NULL");
    569 		else if (syserror(tcp))
    570 			tprintf("%p", info.newval);
    571 		else
    572 			printpath(tcp, (size_t)info.newval);
    573 		tprintf(", %lu", (unsigned long)info.newlen);
    574 	}
    575 
    576 	free(name);
    577 	return 0;
    578 }
    579 
    580 #ifdef MIPS
    581 
    582 #ifndef __NEW_UTS_LEN
    583 #define __NEW_UTS_LEN 64
    584 #endif
    585 
    586 #include "xlat/sysmips_operations.h"
    587 
    588 int sys_sysmips(struct tcb *tcp)
    589 {
    590 	if (entering(tcp)) {
    591 		printxval(sysmips_operations, tcp->u_arg[0], "???");
    592 		if (!verbose(tcp)) {
    593 			tprintf("%ld, %ld, %ld", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
    594 		} else if (tcp->u_arg[0] == SETNAME) {
    595 			char nodename[__NEW_UTS_LEN + 1];
    596 			if (umovestr(tcp, tcp->u_arg[1], (__NEW_UTS_LEN + 1), nodename) < 0)
    597 				tprintf(", %#lx", tcp->u_arg[1]);
    598 			else
    599 				tprintf(", \"%.*s\"", (int)(__NEW_UTS_LEN + 1), nodename);
    600 		} else if (tcp->u_arg[0] == MIPS_ATOMIC_SET) {
    601 			tprintf(", %#lx, 0x%lx", tcp->u_arg[1], tcp->u_arg[2]);
    602 		} else if (tcp->u_arg[0] == MIPS_FIXADE) {
    603 			tprintf(", 0x%lx", tcp->u_arg[1]);
    604 		} else {
    605 			tprintf("%ld, %ld, %ld", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
    606 		}
    607 	}
    608 
    609 	return 0;
    610 }
    611 
    612 #endif /* MIPS */
    613 
    614 #ifdef OR1K
    615 #define OR1K_ATOMIC_SWAP        1
    616 #define OR1K_ATOMIC_CMPXCHG     2
    617 #define OR1K_ATOMIC_XCHG        3
    618 #define OR1K_ATOMIC_ADD         4
    619 #define OR1K_ATOMIC_DECPOS      5
    620 #define OR1K_ATOMIC_AND         6
    621 #define OR1K_ATOMIC_OR          7
    622 #define OR1K_ATOMIC_UMAX        8
    623 #define OR1K_ATOMIC_UMIN        9
    624 
    625 #include "xlat/atomic_ops.h"
    626 
    627 int sys_or1k_atomic(struct tcb *tcp)
    628 {
    629 	if (entering(tcp)) {
    630 		printxval(atomic_ops, tcp->u_arg[0], "???");
    631 		switch(tcp->u_arg[0]) {
    632 		case OR1K_ATOMIC_SWAP:
    633 			tprintf(", 0x%lx, 0x%lx", tcp->u_arg[1], tcp->u_arg[2]);
    634 			break;
    635 		case OR1K_ATOMIC_CMPXCHG:
    636 			tprintf(", 0x%lx, %#lx, %#lx", tcp->u_arg[1], tcp->u_arg[2],
    637 				tcp->u_arg[3]);
    638 			break;
    639 
    640 		case OR1K_ATOMIC_XCHG:
    641 		case OR1K_ATOMIC_ADD:
    642 		case OR1K_ATOMIC_AND:
    643 		case OR1K_ATOMIC_OR:
    644 		case OR1K_ATOMIC_UMAX:
    645 		case OR1K_ATOMIC_UMIN:
    646 			tprintf(", 0x%lx, %#lx", tcp->u_arg[1], tcp->u_arg[2]);
    647 			break;
    648 
    649 		case OR1K_ATOMIC_DECPOS:
    650 			tprintf(", 0x%lx", tcp->u_arg[1]);
    651 			break;
    652 
    653 		default:
    654 			break;
    655 		}
    656 	}
    657 
    658 	return RVAL_HEX;
    659 }
    660 
    661 #endif /* OR1K */
    662