Commit 0337cf74 authored by Hendrik Brueckner's avatar Hendrik Brueckner Committed by Arnaldo Carvalho de Melo
Browse files

perf util: Introduce architecture specific errno/name mapping



Introduce a script that generates a mapping of errno numbers to their
names for each architecture that is supported by perf (i.e.  has a
subdirectory in tools/perf/arch/).

The errno mapping is generated as part of the trace beautifiers and can
be used by including the trace/beauty/arch_errno_names.c file.  Then,
use arch_syscalls__strerrno() to look up an errno value to obtain the
errno name (e.g. ENOENT) for a particular architecture.

Signed-off-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: default avatarThomas Richter <tmricht@linux.vnet.ibm.com>
Suggested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: linux-s390@vger.kernel.org
LPU-Reference: 1516352177-11106-4-git-send-email-brueckner@linux.vnet.ibm.com
Link: https://lkml.kernel.org/n/tip-8zlsjnuoep2ww39aq5z41fno@git.kernel.org


[ Make x86 be the first arch, most common, add newline to last line, fixing build on centos:5 ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 28b8f954
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -462,6 +462,13 @@ prctl_option_tbl := $(srctree)/tools/perf/trace/beauty/prctl_option.sh
$(prctl_option_array): $(prctl_hdr_dir)/prctl.h $(prctl_option_tbl)
	$(Q)$(SHELL) '$(prctl_option_tbl)' $(prctl_hdr_dir) > $@

arch_errno_name_array := $(beauty_outdir)/arch_errno_name_array.c
arch_errno_hdr_dir := $(srctree)/tools
arch_errno_tbl := $(srctree)/tools/perf/trace/beauty/arch_errno_names.sh

$(arch_errno_name_array): $(arch_errno_tbl)
	$(Q)$(SHELL) '$(arch_errno_tbl)' $(CC) $(arch_errno_hdr_dir) > $@

all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)

$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST)
@@ -565,7 +572,8 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc
	$(vhost_virtio_ioctl_array) \
	$(madvise_behavior_array) \
	$(perf_ioctl_array) \
	$(prctl_option_array)
	$(prctl_option_array) \
	$(arch_errno_name_array)

$(OUTPUT)%.o: %.c prepare FORCE
	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -847,7 +855,8 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
		$(OUTPUT)$(kcmp_type_array) \
		$(OUTPUT)$(vhost_virtio_ioctl_array) \
		$(OUTPUT)$(perf_ioctl_array) \
		$(OUTPUT)$(prctl_option_array)
		$(OUTPUT)$(prctl_option_array) \
		$(OUTPUT)$(arch_errno_name_array)
	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean

#
+1 −0
Original line number Diff line number Diff line
#include "trace/beauty/generated/arch_errno_name_array.c"
+100 −0
Original line number Diff line number Diff line
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Generate C file mapping errno codes to errno names.
#
# Copyright IBM Corp. 2018
# Author(s):  Hendrik Brueckner <brueckner@linux.vnet.ibm.com>

gcc="$1"
toolsdir="$2"
include_path="-I$toolsdir/include/uapi"

arch_string()
{
	echo "$1" |sed -e 'y/- /__/' |tr '[[:upper:]]' '[[:lower:]]'
}

asm_errno_file()
{
	local arch="$1"
	local header

	header="$toolsdir/arch/$arch/include/uapi/asm/errno.h"
	if test -r "$header"; then
		echo "$header"
	else
		echo "$toolsdir/include/uapi/asm-generic/errno.h"
	fi
}

create_errno_lookup_func()
{
	local arch=$(arch_string "$1")
	local nr name

	cat <<EoFuncBegin
static const char *errno_to_name__$arch(int err)
{
	switch (err) {
EoFuncBegin

	while read name nr; do
		printf '\tcase %d: return "%s";\n' $nr $name
	done

	cat <<EoFuncEnd
	default:
		return "(unknown)";
	}
}

EoFuncEnd
}

process_arch()
{
	local arch="$1"
	local asm_errno=$(asm_errno_file "$arch")

	$gcc $include_path -E -dM -x c $asm_errno \
		|grep -hE '^#define[[:blank:]]+(E[^[:blank:]]+)[[:blank:]]+([[:digit:]]+).*' \
		|awk '{ print $2","$3; }' \
		|sort -t, -k2 -nu \
		|IFS=, create_errno_lookup_func "$arch"
}

create_arch_errno_table_func()
{
	local archlist="$1"
	local default="$2"
	local arch

	printf 'const char *arch_syscalls__strerrno(const char *arch, int err)\n'
	printf '{\n'
	for arch in $archlist; do
		printf '\tif (!strcmp(arch, "%s"))\n' $(arch_string "$arch")
		printf '\t\treturn errno_to_name__%s(err);\n' $(arch_string "$arch")
	done
	printf '\treturn errno_to_name__%s(err);\n' $(arch_string "$default")
	printf '}\n'
}

cat <<EoHEADER
/* SPDX-License-Identifier: GPL-2.0 */

#include <string.h>

EoHEADER

# Create list of architectures and ignore those that do not appear
# in tools/perf/arch
archlist=""
for arch in $(find $toolsdir/arch -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | grep -v x86 | sort); do
	test -d arch/$arch && archlist="$archlist $arch"
done

for arch in x86 $archlist generic; do
	process_arch "$arch"
done
create_arch_errno_table_func "x86 $archlist" "generic"
+2 −0
Original line number Diff line number Diff line
@@ -114,4 +114,6 @@ size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size);
void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg,
				    size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg));

const char *arch_syscalls__strerrno(const char *arch, int err);

#endif /* _PERF_TRACE_BEAUTY_H */