162306a36Sopenharmony_ci// SPDX-License-Identifier: LGPL-2.1
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * trace/beauty/cone.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "trace/beauty/beauty.h"
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci#include <sys/types.h>
1162306a36Sopenharmony_ci#include <uapi/linux/sched.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistatic size_t clone__scnprintf_flags(unsigned long flags, char *bf, size_t size, bool show_prefix)
1462306a36Sopenharmony_ci{
1562306a36Sopenharmony_ci	const char *prefix = "CLONE_";
1662306a36Sopenharmony_ci	int printed = 0;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define	P_FLAG(n) \
1962306a36Sopenharmony_ci	if (flags & CLONE_##n) { \
2062306a36Sopenharmony_ci		printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \
2162306a36Sopenharmony_ci		flags &= ~CLONE_##n; \
2262306a36Sopenharmony_ci	}
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	P_FLAG(VM);
2562306a36Sopenharmony_ci	P_FLAG(FS);
2662306a36Sopenharmony_ci	P_FLAG(FILES);
2762306a36Sopenharmony_ci	P_FLAG(SIGHAND);
2862306a36Sopenharmony_ci	P_FLAG(PIDFD);
2962306a36Sopenharmony_ci	P_FLAG(PTRACE);
3062306a36Sopenharmony_ci	P_FLAG(VFORK);
3162306a36Sopenharmony_ci	P_FLAG(PARENT);
3262306a36Sopenharmony_ci	P_FLAG(THREAD);
3362306a36Sopenharmony_ci	P_FLAG(NEWNS);
3462306a36Sopenharmony_ci	P_FLAG(SYSVSEM);
3562306a36Sopenharmony_ci	P_FLAG(SETTLS);
3662306a36Sopenharmony_ci	P_FLAG(PARENT_SETTID);
3762306a36Sopenharmony_ci	P_FLAG(CHILD_CLEARTID);
3862306a36Sopenharmony_ci	P_FLAG(DETACHED);
3962306a36Sopenharmony_ci	P_FLAG(UNTRACED);
4062306a36Sopenharmony_ci	P_FLAG(CHILD_SETTID);
4162306a36Sopenharmony_ci	P_FLAG(NEWCGROUP);
4262306a36Sopenharmony_ci	P_FLAG(NEWUTS);
4362306a36Sopenharmony_ci	P_FLAG(NEWIPC);
4462306a36Sopenharmony_ci	P_FLAG(NEWUSER);
4562306a36Sopenharmony_ci	P_FLAG(NEWPID);
4662306a36Sopenharmony_ci	P_FLAG(NEWNET);
4762306a36Sopenharmony_ci	P_FLAG(IO);
4862306a36Sopenharmony_ci	P_FLAG(CLEAR_SIGHAND);
4962306a36Sopenharmony_ci	P_FLAG(INTO_CGROUP);
5062306a36Sopenharmony_ci#undef P_FLAG
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	if (flags)
5362306a36Sopenharmony_ci		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	return printed;
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cisize_t syscall_arg__scnprintf_clone_flags(char *bf, size_t size, struct syscall_arg *arg)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	unsigned long flags = arg->val;
6162306a36Sopenharmony_ci	enum syscall_clone_args {
6262306a36Sopenharmony_ci		SCC_FLAGS	  = (1 << 0),
6362306a36Sopenharmony_ci		SCC_CHILD_STACK	  = (1 << 1),
6462306a36Sopenharmony_ci		SCC_PARENT_TIDPTR = (1 << 2),
6562306a36Sopenharmony_ci		SCC_CHILD_TIDPTR  = (1 << 3),
6662306a36Sopenharmony_ci		SCC_TLS		  = (1 << 4),
6762306a36Sopenharmony_ci	};
6862306a36Sopenharmony_ci	if (!(flags & CLONE_PARENT_SETTID))
6962306a36Sopenharmony_ci		arg->mask |= SCC_PARENT_TIDPTR;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	if (!(flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)))
7262306a36Sopenharmony_ci		arg->mask |= SCC_CHILD_TIDPTR;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	if (!(flags & CLONE_SETTLS))
7562306a36Sopenharmony_ci		arg->mask |= SCC_TLS;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	return clone__scnprintf_flags(flags, bf, size, arg->show_string_prefix);
7862306a36Sopenharmony_ci}
79