Hi Arnaldo, On Thu, Dec 07, 2017 at 02:52:56PM -0300, Arnaldo Carvalho de Melo wrote: > Em Thu, Dec 07, 2017 at 04:00:10PM +0100, Hendrik Brueckner escreveu: > > Introduce an errno_to_name() function to return the name of a > > give errno number as string. > > Humm, we cannot use asm-generic for all, as there are differences in the > errno numbers from arch to arch, for instance: > > In arch/alpha/include/uapi/asm/errno.h we use errno-base.h but even in > that part one of its entries gets a different number on the Alpha arch, > EAGAIN: > ------------------- > #include <asm-generic/errno-base.h> > > #undef EAGAIN /* 11 in errno-base.h */ > > #define EDEADLK 11 /* Resource deadlock would occur */ > > #define EAGAIN 35 /* Try again */ > #define EWOULDBLOCK EAGAIN /* Operation would block */ > ------------------- With that in the mind, I have changed the generation in a way similar I did for s390 syscall table generation. The util/generate-errno-names.sh script can simply process the arch specific errno.h with cpp/gcc. This approach will work fine if the arch errno.h does only include the asm-generic/errno*.h files and does not have any differences between 32/64 bit. Otherwise it becomes more difficult. > So you can try to copy all arch/*/include/uapi/asm/errno.h files and > use the arch to key that, i.e. its almost what you did, but needs to > take the arch into consideration. util/generate-errno-names.sh is also extended to process architectures for which there is a resp. directory below the tools/arch/ directory. Generation of the errno name mappings is still the same but one ALL_ define for each architecture. > > Later we'll generate a two dimensional table of sorts, having the first > dimension be the arch name, so that we can translate errnos in a > perf.data file collected on, say, mips (one of these routers) in a tool > running on x86_64 (or S/390 :)). Yep... for this I need your help: How to obtain the arch string/ID whatever in builtin-trace to use the correct errno map? Below you can find an update on the patch (excluding the patch(es) to grab the header files, one can do that simply with cp --parents -v $(find arch/ -name errno.h) tools/ in the linux source tree.) ---->8--------- Introduce an errno_to_name() function to return the name of a give errno number as string. With this change, the dependency to libaudit can be removed for architectures that support syscall tables. Hence, remove the audit_errno_to_name() call in builtin-trace.c and just link util/syscalltbl.c against libaudit. A follow-up commit could then clean-up this dependency with respect to the syscall table. The errno name strings are generated by util/generate-errno-names.sh script and saved as util/errno-names.h. Errno mappings are created for the architectures that are available in the tool/arch/ directory in the Linux source tree. Signed-off-by: Hendrik Brueckner <brueckner@xxxxxxxxxxxxxxxxxx> --- tools/perf/.gitignore | 1 + tools/perf/Makefile.config | 2 +- tools/perf/Makefile.perf | 9 ++++- tools/perf/builtin-trace.c | 26 +++++++++++-- tools/perf/util/generate-errno-names.sh | 67 +++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 6 deletions(-) create mode 100755 tools/perf/util/generate-errno-names.sh diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 643cc4ba..4e022f9 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -14,6 +14,7 @@ perf*.1 perf*.xml perf*.html common-cmds.h +errno-names.h perf.data perf.data.old output.svg diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index ab16aab..d8447b1 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -251,7 +251,7 @@ INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/ INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/ -# $(obj-perf) for generated common-cmds.h +# $(obj-perf) for generated common-cmds.h and errno-names.h # $(obj-perf)/util for generated bison/flex headers ifneq ($(OUTPUT),) INC_FLAGS += -I$(obj-perf)/util diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 68cf136..73a2616 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -518,6 +518,9 @@ $(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt) $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ +$(OUTPUT)util/errno-names.h: util/generate-errno-names.sh + $(QUIET_GEN). util/generate-errno-names.sh "$(CC)" "$(srctree)/tools" > $@+ && mv $@+ $@ + $(SCRIPTS) : % : %.sh $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@' @@ -565,7 +568,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) \ + $(OUTPUT)util/errno-names.h $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ @@ -847,7 +851,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)util/errno-names.h $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean # diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 84debdb..4c7805d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -42,17 +42,16 @@ #include "string2.h" #include "syscalltbl.h" #include "rb_resort.h" +#include "util/errno-names.h" #include <errno.h> #include <inttypes.h> -#include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */ #include <poll.h> #include <signal.h> #include <stdlib.h> #include <string.h> #include <linux/err.h> #include <linux/filter.h> -#include <linux/audit.h> #include <linux/kernel.h> #include <linux/random.h> #include <linux/stringify.h> @@ -1659,6 +1658,27 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output); } +static const char *__generic_errno_to_name(int err) +{ +#define ERRNO_NAME_MAP(_err, _num) case _num: return #_err; +#define ERRNO_NAME_MAP(_err, _num) case _num: return #_err; + switch (err) { + ALL_ERRNO_NAME_MAPPINGS__GENERIC +#undef ERRNO_NAME_MAP + default: + return "(unknown)"; + break; + } +} + +static const char *errno_to_name(const int arch, int err) +{ + switch (arch) { + default: + return __generic_errno_to_name(err); + } +} + static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) @@ -1729,7 +1749,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, errno_print: { char bf[STRERR_BUFSIZE]; const char *emsg = str_error_r(-ret, bf, sizeof(bf)), - *e = audit_errno_to_name(-ret); + *e = errno_to_name(0, -ret); fprintf(trace->output, ") = -1 %s %s", e, emsg); } diff --git a/tools/perf/util/generate-errno-names.sh b/tools/perf/util/generate-errno-names.sh new file mode 100755 index 0000000..57f74d4 --- /dev/null +++ b/tools/perf/util/generate-errno-names.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Generate errno names header file +# +# Copyright IBM Corp. 2017 +# Author(s): Hendrik Brueckner <brueckner@xxxxxxxxxxxxxxxxxx> + +gcc="$1" +toolsdir="$2" +include_path="-I$toolsdir/include/uapi" + +arch_string() +{ + echo "$1" |sed -e 'y/- /__/' |tr '[[:lower:]]' '[[:upper:]]' +} + +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 +} + +process_arch() +{ + local arch="$1" + local tmpfile=$(mktemp -t generate-errno-names.XXXXXXXXX) + 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 \ + |sed -e 's/^/\tERRNO_NAME_MAP(/' -e 's/$/)/' \ + > $tmpfile + + printf '#define ALL_ERRNO_NAME_MAPPINGS__%s \\\n' $(arch_string "$arch") + head -n -1 $tmpfile |sed -e 's/$/ \\/' + tail -1 $tmpfile + printf "\n" + rm $tmpfile +} + +cat <<EoHeader +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _UTIL_ERRNO_NAMES_H +#define _UTIL_ERRNO_NAMES_H + +EoHeader + +for arch in $(find $toolsdir/arch -maxdepth 1 -mindepth 1 -type d -printf "%f\n" |sort); do + process_arch "$arch" +done + +# Generic fallback +process_arch "generic" + +cat <<EoFooter +#endif /* _UTIL_ERRNO_NAMES_H */ +EoFooter -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-s390" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html