1/*
2 * Copyright (c) 2002-2003 Roland McGrath  <roland@redhat.com>
3 * Copyright (c) 2007-2008 Ulrich Drepper <drepper@redhat.com>
4 * Copyright (c) 2009 Andreas Schwab <schwab@redhat.com>
5 * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
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#ifndef FUTEX_PRIVATE_FLAG
34# define FUTEX_PRIVATE_FLAG 128
35#endif
36#ifndef FUTEX_CLOCK_REALTIME
37# define FUTEX_CLOCK_REALTIME 256
38#endif
39
40#include "xlat/futexops.h"
41#include "xlat/futexwakeops.h"
42#include "xlat/futexwakecmps.h"
43
44SYS_FUNC(futex)
45{
46	const kernel_ulong_t uaddr = tcp->u_arg[0];
47	const int op = tcp->u_arg[1];
48	const int cmd = op & 127;
49	const kernel_ulong_t timeout = tcp->u_arg[3];
50	const kernel_ulong_t uaddr2 = tcp->u_arg[4];
51	const unsigned int val = tcp->u_arg[2];
52	const unsigned int val2 = tcp->u_arg[3];
53	const unsigned int val3 = tcp->u_arg[5];
54
55	printaddr(uaddr);
56	tprints(", ");
57	printxval(futexops, op, "FUTEX_???");
58	switch (cmd) {
59	case FUTEX_WAIT:
60		tprintf(", %u", val);
61		tprints(", ");
62		print_timespec(tcp, timeout);
63		break;
64	case FUTEX_LOCK_PI:
65		tprints(", ");
66		print_timespec(tcp, timeout);
67		break;
68	case FUTEX_WAIT_BITSET:
69		tprintf(", %u", val);
70		tprints(", ");
71		print_timespec(tcp, timeout);
72		tprintf(", %#x", val3);
73		break;
74	case FUTEX_WAKE_BITSET:
75		tprintf(", %u", val);
76		tprintf(", %#x", val3);
77		break;
78	case FUTEX_REQUEUE:
79		tprintf(", %u", val);
80		tprintf(", %u, ", val2);
81		printaddr(uaddr2);
82		break;
83	case FUTEX_CMP_REQUEUE:
84	case FUTEX_CMP_REQUEUE_PI:
85		tprintf(", %u", val);
86		tprintf(", %u, ", val2);
87		printaddr(uaddr2);
88		tprintf(", %u", val3);
89		break;
90	case FUTEX_WAKE_OP:
91		tprintf(", %u", val);
92		tprintf(", %u, ", val2);
93		printaddr(uaddr2);
94		tprints(", ");
95		if ((val3 >> 28) & 8)
96			tprints("FUTEX_OP_OPARG_SHIFT<<28|");
97		if (printxval(futexwakeops, (val3 >> 28) & 0x7, NULL))
98			tprints("<<28");
99		else
100			tprints("<<28 /* FUTEX_OP_??? */");
101		tprintf("|%#x<<12|", (val3 >> 12) & 0xfff);
102		if (printxval(futexwakecmps, (val3 >> 24) & 0xf, NULL))
103			tprints("<<24");
104		else
105			tprints("<<24 /* FUTEX_OP_CMP_??? */");
106		tprintf("|%#x", val3 & 0xfff);
107		break;
108	case FUTEX_WAIT_REQUEUE_PI:
109		tprintf(", %u", val);
110		tprints(", ");
111		print_timespec(tcp, timeout);
112		tprints(", ");
113		printaddr(uaddr2);
114		break;
115	case FUTEX_FD:
116	case FUTEX_WAKE:
117		tprintf(", %u", val);
118		break;
119	case FUTEX_UNLOCK_PI:
120	case FUTEX_TRYLOCK_PI:
121		break;
122	default:
123		tprintf(", %u", val);
124		tprints(", ");
125		printaddr(timeout);
126		tprints(", ");
127		printaddr(uaddr2);
128		tprintf(", %#x", val3);
129		break;
130	}
131
132	return RVAL_DECODED;
133}
134