1 /*
2 * Copyright (c) 2015 Dmitry V. Levin <ldv@strace.io>
3 * Copyright (c) 2015-2022 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #include "defs.h"
10 #include <linux/memfd.h>
11 #include "xlat/memfd_create_flags.h"
12
13 #ifndef MFD_NAME_MAX_LEN
14 # define MFD_NAME_MAX_LEN (255 - (sizeof("memfd:") - 1))
15 #endif
16
17 SYS_FUNC(memfd_create)
18 {
19 /* name */
20 printstr_ex(tcp, tcp->u_arg[0], MFD_NAME_MAX_LEN + 1,
21 QUOTE_0_TERMINATED);
22 tprint_arg_next();
23
24 unsigned int flags = tcp->u_arg[1];
25
26 if (!flags || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
27 PRINT_VAL_X(flags);
28
29 if (!flags || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
30 return RVAL_DECODED | RVAL_FD;
31
32 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
33 tprint_comment_begin();
34
35 const unsigned int mask = MFD_HUGE_MASK << MFD_HUGE_SHIFT;
36 const unsigned int hugetlb_value = flags & mask;
37 flags &= ~mask;
38
39 tprint_flags_begin();
40
41 if (flags || !hugetlb_value)
42 printflags_ex(flags, "MFD_???", XLAT_STYLE_ABBREV,
43 memfd_create_flags, NULL);
44
45 if (hugetlb_value) {
46 if (flags)
47 tprint_flags_or();
48 tprint_shift_begin();
49 PRINT_VAL_U(hugetlb_value >> MFD_HUGE_SHIFT);
50 tprint_shift();
51 /*
52 * print_xlat_u is not used here because the whole thing
53 * is potentially inside a comment already.
54 */
55 tprints_string("MFD_HUGE_SHIFT");
56 tprint_shift_end();
57 }
58
59 tprint_flags_end();
60
61 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
62 tprint_comment_end();
63
64 return RVAL_DECODED | RVAL_FD;
65 }