aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-04-13 02:57:50 -0400
committerIngo Molnar <mingo@kernel.org>2016-04-13 02:57:50 -0400
commitaeaae7d612ff2ad647ba422099da56eb3aa89237 (patch)
treebad2e6634e57c9d0d24a67086620ffca86dc5313
parent889fac6d67d46a5e781c08fb26fec9016db1c307 (diff)
parent99e87f7bb7268cf644add87130590966fd5d0d17 (diff)
Merge tag 'perf-core-for-mingo-20160408' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Beautify more syscall arguments in 'perf trace', using the type column in tracepoint /format fields to attach, for instance, a pid_t resolver to the thread COMM, also attach a mode_t beautifier in the same fashion (Arnaldo Carvalho de Melo) - Build the syscall table id <-> name resolver using the same .tbl file used in the kernel to generate headers, to avoid the delay in getting new syscalls supported in the audit-libs external dependency, done so far only for x86_64 (Arnaldo Carvalho de Melo) - Improve the documentation of event specifications (Andi Kleen) - Process update events in 'perf script', fixing up this use case: # perf stat -a -I 1000 -e cycles record | perf script -s script.py - Shared object symbol adjustment fixes, fixing symbol resolution in Android (Wang Nan) Infrastructure changes: - Add dedicated unwind addr_space member into thread struct, to allow tools to use thread->priv, noticed while working on having callchains in 'perf trace' (Jiri Olsa) Build fixes: - Fix the build in Ubuntu 12.04 (Arnaldo Carvalho de Melo, Vinson Lee) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/build/Makefile.feature2
-rw-r--r--tools/build/feature/Makefile4
-rw-r--r--tools/build/feature/test-all.c5
-rw-r--r--tools/build/feature/test-dwarf_getlocations.c12
-rw-r--r--tools/perf/Documentation/perf-list.txt107
-rw-r--r--tools/perf/Makefile.perf15
-rw-r--r--tools/perf/arch/x86/Makefile23
-rw-r--r--tools/perf/arch/x86/entry/syscalls/syscall_64.tbl374
-rwxr-xr-xtools/perf/arch/x86/entry/syscalls/syscalltbl.sh39
-rw-r--r--tools/perf/builtin-script.c1
-rw-r--r--tools/perf/builtin-trace.c156
-rw-r--r--tools/perf/config/Makefile11
-rw-r--r--tools/perf/trace/beauty/mode_t.c68
-rw-r--r--tools/perf/trace/beauty/pid.c18
-rw-r--r--tools/perf/trace/beauty/sched_policy.c44
-rw-r--r--tools/perf/trace/beauty/waitid_options.c26
-rw-r--r--tools/perf/ui/browsers/hists.c3
-rw-r--r--tools/perf/ui/stdio/hist.c3
-rw-r--r--tools/perf/util/Build5
-rw-r--r--tools/perf/util/config.c6
-rw-r--r--tools/perf/util/dwarf-aux.c9
-rw-r--r--tools/perf/util/map.c14
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c30
-rw-r--r--tools/perf/util/symbol-elf.c13
-rw-r--r--tools/perf/util/syscalltbl.c134
-rw-r--r--tools/perf/util/syscalltbl.h20
-rw-r--r--tools/perf/util/thread.h6
-rw-r--r--tools/perf/util/unwind-libunwind.c25
-rw-r--r--tools/perf/util/util.h5
29 files changed, 1061 insertions, 117 deletions
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 6b7707270aa3..9f878619077a 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -30,6 +30,7 @@ endef
30FEATURE_TESTS_BASIC := \ 30FEATURE_TESTS_BASIC := \
31 backtrace \ 31 backtrace \
32 dwarf \ 32 dwarf \
33 dwarf_getlocations \
33 fortify-source \ 34 fortify-source \
34 sync-compare-and-swap \ 35 sync-compare-and-swap \
35 glibc \ 36 glibc \
@@ -78,6 +79,7 @@ endif
78 79
79FEATURE_DISPLAY ?= \ 80FEATURE_DISPLAY ?= \
80 dwarf \ 81 dwarf \
82 dwarf_getlocations \
81 glibc \ 83 glibc \
82 gtk2 \ 84 gtk2 \
83 libaudit \ 85 libaudit \
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index c5f4c417428d..4ae94dbfdab9 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -3,6 +3,7 @@ FILES= \
3 test-backtrace.bin \ 3 test-backtrace.bin \
4 test-bionic.bin \ 4 test-bionic.bin \
5 test-dwarf.bin \ 5 test-dwarf.bin \
6 test-dwarf_getlocations.bin \
6 test-fortify-source.bin \ 7 test-fortify-source.bin \
7 test-sync-compare-and-swap.bin \ 8 test-sync-compare-and-swap.bin \
8 test-glibc.bin \ 9 test-glibc.bin \
@@ -82,6 +83,9 @@ endif
82$(OUTPUT)test-dwarf.bin: 83$(OUTPUT)test-dwarf.bin:
83 $(BUILD) $(DWARFLIBS) 84 $(BUILD) $(DWARFLIBS)
84 85
86$(OUTPUT)test-dwarf_getlocations.bin:
87 $(BUILD) $(DWARFLIBS)
88
85$(OUTPUT)test-libelf-mmap.bin: 89$(OUTPUT)test-libelf-mmap.bin:
86 $(BUILD) -lelf 90 $(BUILD) -lelf
87 91
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index e499a36c1e4a..a282e8cb84f3 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -41,6 +41,10 @@
41# include "test-dwarf.c" 41# include "test-dwarf.c"
42#undef main 42#undef main
43 43
44#define main main_test_dwarf_getlocations
45# include "test-dwarf_getlocations.c"
46#undef main
47
44#define main main_test_libelf_getphdrnum 48#define main main_test_libelf_getphdrnum
45# include "test-libelf-getphdrnum.c" 49# include "test-libelf-getphdrnum.c"
46#undef main 50#undef main
@@ -143,6 +147,7 @@ int main(int argc, char *argv[])
143 main_test_libelf_mmap(); 147 main_test_libelf_mmap();
144 main_test_glibc(); 148 main_test_glibc();
145 main_test_dwarf(); 149 main_test_dwarf();
150 main_test_dwarf_getlocations();
146 main_test_libelf_getphdrnum(); 151 main_test_libelf_getphdrnum();
147 main_test_libunwind(); 152 main_test_libunwind();
148 main_test_libaudit(); 153 main_test_libaudit();
diff --git a/tools/build/feature/test-dwarf_getlocations.c b/tools/build/feature/test-dwarf_getlocations.c
new file mode 100644
index 000000000000..70162699dd43
--- /dev/null
+++ b/tools/build/feature/test-dwarf_getlocations.c
@@ -0,0 +1,12 @@
1#include <stdlib.h>
2#include <elfutils/libdw.h>
3
4int main(void)
5{
6 Dwarf_Addr base, start, end;
7 Dwarf_Attribute attr;
8 Dwarf_Op *op;
9 size_t nops;
10 ptrdiff_t offset = 0;
11 return (int)dwarf_getlocations(&attr, offset, &base, &start, &end, &op, &nops);
12}
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index ec723d0a5bb3..a126e97a8114 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -93,6 +93,67 @@ raw encoding of 0x1A8 can be used:
93You should refer to the processor specific documentation for getting these 93You should refer to the processor specific documentation for getting these
94details. Some of them are referenced in the SEE ALSO section below. 94details. Some of them are referenced in the SEE ALSO section below.
95 95
96ARBITRARY PMUS
97--------------
98
99perf also supports an extended syntax for specifying raw parameters
100to PMUs. Using this typically requires looking up the specific event
101in the CPU vendor specific documentation.
102
103The available PMUs and their raw parameters can be listed with
104
105 ls /sys/devices/*/format
106
107For example the raw event "LSD.UOPS" core pmu event above could
108be specified as
109
110 perf stat -e cpu/event=0xa8,umask=0x1,name=LSD.UOPS_CYCLES,cmask=1/ ...
111
112PER SOCKET PMUS
113---------------
114
115Some PMUs are not associated with a core, but with a whole CPU socket.
116Events on these PMUs generally cannot be sampled, but only counted globally
117with perf stat -a. They can be bound to one logical CPU, but will measure
118all the CPUs in the same socket.
119
120This example measures memory bandwidth every second
121on the first memory controller on socket 0 of a Intel Xeon system
122
123 perf stat -C 0 -a uncore_imc_0/cas_count_read/,uncore_imc_0/cas_count_write/ -I 1000 ...
124
125Each memory controller has its own PMU. Measuring the complete system
126bandwidth would require specifying all imc PMUs (see perf list output),
127and adding the values together.
128
129This example measures the combined core power every second
130
131 perf stat -I 1000 -e power/energy-cores/ -a
132
133ACCESS RESTRICTIONS
134-------------------
135
136For non root users generally only context switched PMU events are available.
137This is normally only the events in the cpu PMU, the predefined events
138like cycles and instructions and some software events.
139
140Other PMUs and global measurements are normally root only.
141Some event qualifiers, such as "any", are also root only.
142
143This can be overriden by setting the kernel.perf_event_paranoid
144sysctl to -1, which allows non root to use these events.
145
146For accessing trace point events perf needs to have read access to
147/sys/kernel/debug/tracing, even when perf_event_paranoid is in a relaxed
148setting.
149
150TRACING
151-------
152
153Some PMUs control advanced hardware tracing capabilities, such as Intel PT,
154that allows low overhead execution tracing. These are described in a separate
155intel-pt.txt document.
156
96PARAMETERIZED EVENTS 157PARAMETERIZED EVENTS
97-------------------- 158--------------------
98 159
@@ -106,6 +167,50 @@ also be supplied. For example:
106 167
107 perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ... 168 perf stat -C 0 -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ...
108 169
170EVENT GROUPS
171------------
172
173Perf supports time based multiplexing of events, when the number of events
174active exceeds the number of hardware performance counters. Multiplexing
175can cause measurement errors when the workload changes its execution
176profile.
177
178When metrics are computed using formulas from event counts, it is useful to
179ensure some events are always measured together as a group to minimize multiplexing
180errors. Event groups can be specified using { }.
181
182 perf stat -e '{instructions,cycles}' ...
183
184The number of available performance counters depend on the CPU. A group
185cannot contain more events than available counters.
186For example Intel Core CPUs typically have four generic performance counters
187for the core, plus three fixed counters for instructions, cycles and
188ref-cycles. Some special events have restrictions on which counter they
189can schedule, and may not support multiple instances in a single group.
190When too many events are specified in the group none of them will not
191be measured.
192
193Globally pinned events can limit the number of counters available for
194other groups. On x86 systems, the NMI watchdog pins a counter by default.
195The nmi watchdog can be disabled as root with
196
197 echo 0 > /proc/sys/kernel/nmi_watchdog
198
199Events from multiple different PMUs cannot be mixed in a group, with
200some exceptions for software events.
201
202LEADER SAMPLING
203---------------
204
205perf also supports group leader sampling using the :S specifier.
206
207 perf record -e '{cycles,instructions}:S' ...
208 perf report --group
209
210Normally all events in a event group sample, but with :S only
211the first event (the leader) samples, and it only reads the values of the
212other events in the group.
213
109OPTIONS 214OPTIONS
110------- 215-------
111 216
@@ -143,5 +248,5 @@ SEE ALSO
143-------- 248--------
144linkperf:perf-stat[1], linkperf:perf-top[1], 249linkperf:perf-stat[1], linkperf:perf-top[1],
145linkperf:perf-record[1], 250linkperf:perf-record[1],
146http://www.intel.com/Assets/PDF/manual/253669.pdf[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide], 251http://www.intel.com/sdm/[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide],
147http://support.amd.com/us/Processor_TechDocs/24593_APM_v2.pdf[AMD64 Architecture Programmer’s Manual Volume 2: System Programming] 252http://support.amd.com/us/Processor_TechDocs/24593_APM_v2.pdf[AMD64 Architecture Programmer’s Manual Volume 2: System Programming]
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 000ea210389d..bde8cbae7dd9 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -183,6 +183,11 @@ endif
183include config/Makefile 183include config/Makefile
184endif 184endif
185 185
186ifeq ($(config),0)
187include $(srctree)/tools/scripts/Makefile.arch
188-include arch/$(ARCH)/Makefile
189endif
190
186# The FEATURE_DUMP_EXPORT holds location of the actual 191# The FEATURE_DUMP_EXPORT holds location of the actual
187# FEATURE_DUMP file to be used to bypass feature detection 192# FEATURE_DUMP file to be used to bypass feature detection
188# (for bpf or any other subproject) 193# (for bpf or any other subproject)
@@ -297,8 +302,6 @@ endif
297# because maintaining the nesting to match is a pain. If 302# because maintaining the nesting to match is a pain. If
298# we had "elif" things would have been much nicer... 303# we had "elif" things would have been much nicer...
299 304
300-include arch/$(ARCH)/Makefile
301
302ifneq ($(OUTPUT),) 305ifneq ($(OUTPUT),)
303 CFLAGS += -I$(OUTPUT) 306 CFLAGS += -I$(OUTPUT)
304endif 307endif
@@ -390,7 +393,7 @@ endif
390__build-dir = $(subst $(OUTPUT),,$(dir $@)) 393__build-dir = $(subst $(OUTPUT),,$(dir $@))
391build-dir = $(if $(__build-dir),$(__build-dir),.) 394build-dir = $(if $(__build-dir),$(__build-dir),.)
392 395
393prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep 396prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep archheaders
394 397
395$(OUTPUT)%.o: %.c prepare FORCE 398$(OUTPUT)%.o: %.c prepare FORCE
396 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 399 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -430,7 +433,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
430 433
431LIBPERF_IN := $(OUTPUT)libperf-in.o 434LIBPERF_IN := $(OUTPUT)libperf-in.o
432 435
433$(LIBPERF_IN): fixdep FORCE 436$(LIBPERF_IN): prepare fixdep FORCE
434 $(Q)$(MAKE) $(build)=libperf 437 $(Q)$(MAKE) $(build)=libperf
435 438
436$(LIB_FILE): $(LIBPERF_IN) 439$(LIB_FILE): $(LIBPERF_IN)
@@ -625,7 +628,7 @@ config-clean:
625 $(call QUIET_CLEAN, config) 628 $(call QUIET_CLEAN, config)
626 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null 629 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null
627 630
628clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean 631clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean
629 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) 632 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
630 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete 633 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
631 $(Q)$(RM) $(OUTPUT).config-detected 634 $(Q)$(RM) $(OUTPUT).config-detected
@@ -662,5 +665,5 @@ FORCE:
662.PHONY: all install clean config-clean strip install-gtk 665.PHONY: all install clean config-clean strip install-gtk
663.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 666.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
664.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare 667.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
665.PHONY: libtraceevent_plugins 668.PHONY: libtraceevent_plugins archheaders
666 669
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 269af2143735..a33729173b13 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -4,3 +4,26 @@ endif
4HAVE_KVM_STAT_SUPPORT := 1 4HAVE_KVM_STAT_SUPPORT := 1
5PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 5PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
6PERF_HAVE_JITDUMP := 1 6PERF_HAVE_JITDUMP := 1
7
8###
9# Syscall table generation
10#
11
12out := $(OUTPUT)arch/x86/include/generated/asm
13header := $(out)/syscalls_64.c
14sys := $(srctree)/tools/perf/arch/x86/entry/syscalls
15systbl := $(sys)/syscalltbl.sh
16
17# Create output directory if not already present
18_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
19
20$(header): $(sys)/syscall_64.tbl $(systbl)
21 @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \
22 (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \
23 || echo "Warning: x86_64's syscall_64.tbl differs from kernel" >&2 )) || true
24 $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
25
26clean::
27 rm -f $(header)
28
29archheaders: $(header)
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
new file mode 100644
index 000000000000..2e5b565adacc
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
@@ -0,0 +1,374 @@
1#
2# 64-bit system call numbers and entry vectors
3#
4# The format is:
5# <number> <abi> <name> <entry point>
6#
7# The abi is "common", "64" or "x32" for this file.
8#
90 common read sys_read
101 common write sys_write
112 common open sys_open
123 common close sys_close
134 common stat sys_newstat
145 common fstat sys_newfstat
156 common lstat sys_newlstat
167 common poll sys_poll
178 common lseek sys_lseek
189 common mmap sys_mmap
1910 common mprotect sys_mprotect
2011 common munmap sys_munmap
2112 common brk sys_brk
2213 64 rt_sigaction sys_rt_sigaction
2314 common rt_sigprocmask sys_rt_sigprocmask
2415 64 rt_sigreturn sys_rt_sigreturn/ptregs
2516 64 ioctl sys_ioctl
2617 common pread64 sys_pread64
2718 common pwrite64 sys_pwrite64
2819 64 readv sys_readv
2920 64 writev sys_writev
3021 common access sys_access
3122 common pipe sys_pipe
3223 common select sys_select
3324 common sched_yield sys_sched_yield
3425 common mremap sys_mremap
3526 common msync sys_msync
3627 common mincore sys_mincore
3728 common madvise sys_madvise
3829 common shmget sys_shmget
3930 common shmat sys_shmat
4031 common shmctl sys_shmctl
4132 common dup sys_dup
4233 common dup2 sys_dup2
4334 common pause sys_pause
4435 common nanosleep sys_nanosleep
4536 common getitimer sys_getitimer
4637 common alarm sys_alarm
4738 common setitimer sys_setitimer
4839 common getpid sys_getpid
4940 common sendfile sys_sendfile64
5041 common socket sys_socket
5142 common connect sys_connect
5243 common accept sys_accept
5344 common sendto sys_sendto
5445 64 recvfrom sys_recvfrom
5546 64 sendmsg sys_sendmsg
5647 64 recvmsg sys_recvmsg
5748 common shutdown sys_shutdown
5849 common bind sys_bind
5950 common listen sys_listen
6051 common getsockname sys_getsockname
6152 common getpeername sys_getpeername
6253 common socketpair sys_socketpair
6354 64 setsockopt sys_setsockopt
6455 64 getsockopt sys_getsockopt
6556 common clone sys_clone/ptregs
6657 common fork sys_fork/ptregs
6758 common vfork sys_vfork/ptregs
6859 64 execve sys_execve/ptregs
6960 common exit sys_exit
7061 common wait4 sys_wait4
7162 common kill sys_kill
7263 common uname sys_newuname
7364 common semget sys_semget
7465 common semop sys_semop
7566 common semctl sys_semctl
7667 common shmdt sys_shmdt
7768 common msgget sys_msgget
7869 common msgsnd sys_msgsnd
7970 common msgrcv sys_msgrcv
8071 common msgctl sys_msgctl
8172 common fcntl sys_fcntl
8273 common flock sys_flock
8374 common fsync sys_fsync
8475 common fdatasync sys_fdatasync
8576 common truncate sys_truncate
8677 common ftruncate sys_ftruncate
8778 common getdents sys_getdents
8879 common getcwd sys_getcwd
8980 common chdir sys_chdir
9081 common fchdir sys_fchdir
9182 common rename sys_rename
9283 common mkdir sys_mkdir
9384 common rmdir sys_rmdir
9485 common creat sys_creat
9586 common link sys_link
9687 common unlink sys_unlink
9788 common symlink sys_symlink
9889 common readlink sys_readlink
9990 common chmod sys_chmod
10091 common fchmod sys_fchmod
10192 common chown sys_chown
10293 common fchown sys_fchown
10394 common lchown sys_lchown
10495 common umask sys_umask
10596 common gettimeofday sys_gettimeofday
10697 common getrlimit sys_getrlimit
10798 common getrusage sys_getrusage
10899 common sysinfo sys_sysinfo
109100 common times sys_times
110101 64 ptrace sys_ptrace
111102 common getuid sys_getuid
112103 common syslog sys_syslog
113104 common getgid sys_getgid
114105 common setuid sys_setuid
115106 common setgid sys_setgid
116107 common geteuid sys_geteuid
117108 common getegid sys_getegid
118109 common setpgid sys_setpgid
119110 common getppid sys_getppid
120111 common getpgrp sys_getpgrp
121112 common setsid sys_setsid
122113 common setreuid sys_setreuid
123114 common setregid sys_setregid
124115 common getgroups sys_getgroups
125116 common setgroups sys_setgroups
126117 common setresuid sys_setresuid
127118 common getresuid sys_getresuid
128119 common setresgid sys_setresgid
129120 common getresgid sys_getresgid
130121 common getpgid sys_getpgid
131122 common setfsuid sys_setfsuid
132123 common setfsgid sys_setfsgid
133124 common getsid sys_getsid
134125 common capget sys_capget
135126 common capset sys_capset
136127 64 rt_sigpending sys_rt_sigpending
137128 64 rt_sigtimedwait sys_rt_sigtimedwait
138129 64 rt_sigqueueinfo sys_rt_sigqueueinfo
139130 common rt_sigsuspend sys_rt_sigsuspend
140131 64 sigaltstack sys_sigaltstack
141132 common utime sys_utime
142133 common mknod sys_mknod
143134 64 uselib
144135 common personality sys_personality
145136 common ustat sys_ustat
146137 common statfs sys_statfs
147138 common fstatfs sys_fstatfs
148139 common sysfs sys_sysfs
149140 common getpriority sys_getpriority
150141 common setpriority sys_setpriority
151142 common sched_setparam sys_sched_setparam
152143 common sched_getparam sys_sched_getparam
153144 common sched_setscheduler sys_sched_setscheduler
154145 common sched_getscheduler sys_sched_getscheduler
155146 common sched_get_priority_max sys_sched_get_priority_max
156147 common sched_get_priority_min sys_sched_get_priority_min
157148 common sched_rr_get_interval sys_sched_rr_get_interval
158149 common mlock sys_mlock
159150 common munlock sys_munlock
160151 common mlockall sys_mlockall
161152 common munlockall sys_munlockall
162153 common vhangup sys_vhangup
163154 common modify_ldt sys_modify_ldt
164155 common pivot_root sys_pivot_root
165156 64 _sysctl sys_sysctl
166157 common prctl sys_prctl
167158 common arch_prctl sys_arch_prctl
168159 common adjtimex sys_adjtimex
169160 common setrlimit sys_setrlimit
170161 common chroot sys_chroot
171162 common sync sys_sync
172163 common acct sys_acct
173164 common settimeofday sys_settimeofday
174165 common mount sys_mount
175166 common umount2 sys_umount
176167 common swapon sys_swapon
177168 common swapoff sys_swapoff
178169 common reboot sys_reboot
179170 common sethostname sys_sethostname
180171 common setdomainname sys_setdomainname
181172 common iopl sys_iopl/ptregs
182173 common ioperm sys_ioperm
183174 64 create_module
184175 common init_module sys_init_module
185176 common delete_module sys_delete_module
186177 64 get_kernel_syms
187178 64 query_module
188179 common quotactl sys_quotactl
189180 64 nfsservctl
190181 common getpmsg
191182 common putpmsg
192183 common afs_syscall
193184 common tuxcall
194185 common security
195186 common gettid sys_gettid
196187 common readahead sys_readahead
197188 common setxattr sys_setxattr
198189 common lsetxattr sys_lsetxattr
199190 common fsetxattr sys_fsetxattr
200191 common getxattr sys_getxattr
201192 common lgetxattr sys_lgetxattr
202193 common fgetxattr sys_fgetxattr
203194 common listxattr sys_listxattr
204195 common llistxattr sys_llistxattr
205196 common flistxattr sys_flistxattr
206197 common removexattr sys_removexattr
207198 common lremovexattr sys_lremovexattr
208199 common fremovexattr sys_fremovexattr
209200 common tkill sys_tkill
210201 common time sys_time
211202 common futex sys_futex
212203 common sched_setaffinity sys_sched_setaffinity
213204 common sched_getaffinity sys_sched_getaffinity
214205 64 set_thread_area
215206 64 io_setup sys_io_setup
216207 common io_destroy sys_io_destroy
217208 common io_getevents sys_io_getevents
218209 64 io_submit sys_io_submit
219210 common io_cancel sys_io_cancel
220211 64 get_thread_area
221212 common lookup_dcookie sys_lookup_dcookie
222213 common epoll_create sys_epoll_create
223214 64 epoll_ctl_old
224215 64 epoll_wait_old
225216 common remap_file_pages sys_remap_file_pages
226217 common getdents64 sys_getdents64
227218 common set_tid_address sys_set_tid_address
228219 common restart_syscall sys_restart_syscall
229220 common semtimedop sys_semtimedop
230221 common fadvise64 sys_fadvise64
231222 64 timer_create sys_timer_create
232223 common timer_settime sys_timer_settime
233224 common timer_gettime sys_timer_gettime
234225 common timer_getoverrun sys_timer_getoverrun
235226 common timer_delete sys_timer_delete
236227 common clock_settime sys_clock_settime
237228 common clock_gettime sys_clock_gettime
238229 common clock_getres sys_clock_getres
239230 common clock_nanosleep sys_clock_nanosleep
240231 common exit_group sys_exit_group
241232 common epoll_wait sys_epoll_wait
242233 common epoll_ctl sys_epoll_ctl
243234 common tgkill sys_tgkill
244235 common utimes sys_utimes
245236 64 vserver
246237 common mbind sys_mbind
247238 common set_mempolicy sys_set_mempolicy
248239 common get_mempolicy sys_get_mempolicy
249240 common mq_open sys_mq_open
250241 common mq_unlink sys_mq_unlink
251242 common mq_timedsend sys_mq_timedsend
252243 common mq_timedreceive sys_mq_timedreceive
253244 64 mq_notify sys_mq_notify
254245 common mq_getsetattr sys_mq_getsetattr
255246 64 kexec_load sys_kexec_load
256247 64 waitid sys_waitid
257248 common add_key sys_add_key
258249 common request_key sys_request_key
259250 common keyctl sys_keyctl
260251 common ioprio_set sys_ioprio_set
261252 common ioprio_get sys_ioprio_get
262253 common inotify_init sys_inotify_init
263254 common inotify_add_watch sys_inotify_add_watch
264255 common inotify_rm_watch sys_inotify_rm_watch
265256 common migrate_pages sys_migrate_pages
266257 common openat sys_openat
267258 common mkdirat sys_mkdirat
268259 common mknodat sys_mknodat
269260 common fchownat sys_fchownat
270261 common futimesat sys_futimesat
271262 common newfstatat sys_newfstatat
272263 common unlinkat sys_unlinkat
273264 common renameat sys_renameat
274265 common linkat sys_linkat
275266 common symlinkat sys_symlinkat
276267 common readlinkat sys_readlinkat
277268 common fchmodat sys_fchmodat
278269 common faccessat sys_faccessat
279270 common pselect6 sys_pselect6
280271 common ppoll sys_ppoll
281272 common unshare sys_unshare
282273 64 set_robust_list sys_set_robust_list
283274 64 get_robust_list sys_get_robust_list
284275 common splice sys_splice
285276 common tee sys_tee
286277 common sync_file_range sys_sync_file_range
287278 64 vmsplice sys_vmsplice
288279 64 move_pages sys_move_pages
289280 common utimensat sys_utimensat
290281 common epoll_pwait sys_epoll_pwait
291282 common signalfd sys_signalfd
292283 common timerfd_create sys_timerfd_create
293284 common eventfd sys_eventfd
294285 common fallocate sys_fallocate
295286 common timerfd_settime sys_timerfd_settime
296287 common timerfd_gettime sys_timerfd_gettime
297288 common accept4 sys_accept4
298289 common signalfd4 sys_signalfd4
299290 common eventfd2 sys_eventfd2
300291 common epoll_create1 sys_epoll_create1
301292 common dup3 sys_dup3
302293 common pipe2 sys_pipe2
303294 common inotify_init1 sys_inotify_init1
304295 64 preadv sys_preadv
305296 64 pwritev sys_pwritev
306297 64 rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
307298 common perf_event_open sys_perf_event_open
308299 64 recvmmsg sys_recvmmsg
309300 common fanotify_init sys_fanotify_init
310301 common fanotify_mark sys_fanotify_mark
311302 common prlimit64 sys_prlimit64
312303 common name_to_handle_at sys_name_to_handle_at
313304 common open_by_handle_at sys_open_by_handle_at
314305 common clock_adjtime sys_clock_adjtime
315306 common syncfs sys_syncfs
316307 64 sendmmsg sys_sendmmsg
317308 common setns sys_setns
318309 common getcpu sys_getcpu
319310 64 process_vm_readv sys_process_vm_readv
320311 64 process_vm_writev sys_process_vm_writev
321312 common kcmp sys_kcmp
322313 common finit_module sys_finit_module
323314 common sched_setattr sys_sched_setattr
324315 common sched_getattr sys_sched_getattr
325316 common renameat2 sys_renameat2
326317 common seccomp sys_seccomp
327318 common getrandom sys_getrandom
328319 common memfd_create sys_memfd_create
329320 common kexec_file_load sys_kexec_file_load
330321 common bpf sys_bpf
331322 64 execveat sys_execveat/ptregs
332323 common userfaultfd sys_userfaultfd
333324 common membarrier sys_membarrier
334325 common mlock2 sys_mlock2
335326 common copy_file_range sys_copy_file_range
336
337#
338# x32-specific system call numbers start at 512 to avoid cache impact
339# for native 64-bit operation.
340#
341512 x32 rt_sigaction compat_sys_rt_sigaction
342513 x32 rt_sigreturn sys32_x32_rt_sigreturn
343514 x32 ioctl compat_sys_ioctl
344515 x32 readv compat_sys_readv
345516 x32 writev compat_sys_writev
346517 x32 recvfrom compat_sys_recvfrom
347518 x32 sendmsg compat_sys_sendmsg
348519 x32 recvmsg compat_sys_recvmsg
349520 x32 execve compat_sys_execve/ptregs
350521 x32 ptrace compat_sys_ptrace
351522 x32 rt_sigpending compat_sys_rt_sigpending
352523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait
353524 x32 rt_sigqueueinfo compat_sys_rt_sigqueueinfo
354525 x32 sigaltstack compat_sys_sigaltstack
355526 x32 timer_create compat_sys_timer_create
356527 x32 mq_notify compat_sys_mq_notify
357528 x32 kexec_load compat_sys_kexec_load
358529 x32 waitid compat_sys_waitid
359530 x32 set_robust_list compat_sys_set_robust_list
360531 x32 get_robust_list compat_sys_get_robust_list
361532 x32 vmsplice compat_sys_vmsplice
362533 x32 move_pages compat_sys_move_pages
363534 x32 preadv compat_sys_preadv64
364535 x32 pwritev compat_sys_pwritev64
365536 x32 rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
366537 x32 recvmmsg compat_sys_recvmmsg
367538 x32 sendmmsg compat_sys_sendmmsg
368539 x32 process_vm_readv compat_sys_process_vm_readv
369540 x32 process_vm_writev compat_sys_process_vm_writev
370541 x32 setsockopt compat_sys_setsockopt
371542 x32 getsockopt compat_sys_getsockopt
372543 x32 io_setup compat_sys_io_setup
373544 x32 io_submit compat_sys_io_submit
374545 x32 execveat compat_sys_execveat/ptregs
diff --git a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
new file mode 100755
index 000000000000..49a18b9ad9cf
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
@@ -0,0 +1,39 @@
1#!/bin/sh
2
3in="$1"
4arch="$2"
5
6syscall_macro() {
7 nr="$1"
8 name="$2"
9
10 echo " [$nr] = \"$name\","
11}
12
13emit() {
14 nr="$1"
15 entry="$2"
16
17 syscall_macro "$nr" "$entry"
18}
19
20echo "static const char *syscalltbl_${arch}[] = {"
21
22sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
23grep '^[0-9]' "$in" | sort -n > $sorted_table
24
25max_nr=0
26while read nr abi name entry compat; do
27 if [ $nr -ge 512 ] ; then # discard compat sycalls
28 break
29 fi
30
31 emit "$nr" "$name"
32 max_nr=$nr
33done < $sorted_table
34
35rm -f $sorted_table
36
37echo "};"
38
39echo "#define SYSCALLTBL_${arch}_MAX_ID ${max_nr}"
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 3770c3dffe5e..59009aa7e2ca 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1961,6 +1961,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1961 .exit = perf_event__process_exit, 1961 .exit = perf_event__process_exit,
1962 .fork = perf_event__process_fork, 1962 .fork = perf_event__process_fork,
1963 .attr = process_attr, 1963 .attr = process_attr,
1964 .event_update = perf_event__process_event_update,
1964 .tracing_data = perf_event__process_tracing_data, 1965 .tracing_data = perf_event__process_tracing_data,
1965 .build_id = perf_event__process_build_id, 1966 .build_id = perf_event__process_build_id,
1966 .id_index = perf_event__process_id_index, 1967 .id_index = perf_event__process_id_index,
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d309f4535a45..11290b57ce04 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -34,8 +34,9 @@
34#include "trace-event.h" 34#include "trace-event.h"
35#include "util/parse-events.h" 35#include "util/parse-events.h"
36#include "util/bpf-loader.h" 36#include "util/bpf-loader.h"
37#include "syscalltbl.h"
37 38
38#include <libaudit.h> 39#include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */
39#include <stdlib.h> 40#include <stdlib.h>
40#include <sys/mman.h> 41#include <sys/mman.h>
41#include <linux/futex.h> 42#include <linux/futex.h>
@@ -112,6 +113,56 @@
112# define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */ 113# define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */
113#endif 114#endif
114 115
116struct trace {
117 struct perf_tool tool;
118 struct syscalltbl *sctbl;
119 struct {
120 int max;
121 struct syscall *table;
122 struct {
123 struct perf_evsel *sys_enter,
124 *sys_exit;
125 } events;
126 } syscalls;
127 struct record_opts opts;
128 struct perf_evlist *evlist;
129 struct machine *host;
130 struct thread *current;
131 u64 base_time;
132 FILE *output;
133 unsigned long nr_events;
134 struct strlist *ev_qualifier;
135 struct {
136 size_t nr;
137 int *entries;
138 } ev_qualifier_ids;
139 struct intlist *tid_list;
140 struct intlist *pid_list;
141 struct {
142 size_t nr;
143 pid_t *entries;
144 } filter_pids;
145 double duration_filter;
146 double runtime_ms;
147 struct {
148 u64 vfs_getname,
149 proc_getname;
150 } stats;
151 bool not_ev_qualifier;
152 bool live;
153 bool full_time;
154 bool sched;
155 bool multiple_threads;
156 bool summary;
157 bool summary_only;
158 bool show_comm;
159 bool show_tool_stats;
160 bool trace_syscalls;
161 bool force;
162 bool vfs_getname;
163 int trace_pgfaults;
164 int open_id;
165};
115 166
116struct tp_field { 167struct tp_field {
117 int offset; 168 int offset;
@@ -1073,12 +1124,18 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size,
1073 .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ 1124 .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \
1074 .arg_parm = { [arg] = &strarray__##array, } 1125 .arg_parm = { [arg] = &strarray__##array, }
1075 1126
1127#include "trace/beauty/pid.c"
1128#include "trace/beauty/mode_t.c"
1129#include "trace/beauty/sched_policy.c"
1130#include "trace/beauty/waitid_options.c"
1131
1076static struct syscall_fmt { 1132static struct syscall_fmt {
1077 const char *name; 1133 const char *name;
1078 const char *alias; 1134 const char *alias;
1079 size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg); 1135 size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg);
1080 void *arg_parm[6]; 1136 void *arg_parm[6];
1081 bool errmsg; 1137 bool errmsg;
1138 bool errpid;
1082 bool timeout; 1139 bool timeout;
1083 bool hexret; 1140 bool hexret;
1084} syscall_fmts[] = { 1141} syscall_fmts[] = {
@@ -1096,6 +1153,7 @@ static struct syscall_fmt {
1096 { .name = "chroot", .errmsg = true, 1153 { .name = "chroot", .errmsg = true,
1097 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, }, 1154 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1098 { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), }, 1155 { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), },
1156 { .name = "clone", .errpid = true, },
1099 { .name = "close", .errmsg = true, 1157 { .name = "close", .errmsg = true,
1100 .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, 1158 .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, },
1101 { .name = "connect", .errmsg = true, }, 1159 { .name = "connect", .errmsg = true, },
@@ -1161,6 +1219,9 @@ static struct syscall_fmt {
1161 { .name = "getdents64", .errmsg = true, 1219 { .name = "getdents64", .errmsg = true,
1162 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 1220 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1163 { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, 1221 { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), },
1222 { .name = "getpid", .errpid = true, },
1223 { .name = "getpgid", .errpid = true, },
1224 { .name = "getppid", .errpid = true, },
1164 { .name = "getrandom", .errmsg = true, 1225 { .name = "getrandom", .errmsg = true,
1165 .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, }, 1226 .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, },
1166 { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, 1227 { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
@@ -1304,6 +1365,8 @@ static struct syscall_fmt {
1304 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, 1365 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1305 { .name = "rt_tgsigqueueinfo", .errmsg = true, 1366 { .name = "rt_tgsigqueueinfo", .errmsg = true,
1306 .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, 1367 .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
1368 { .name = "sched_setscheduler", .errmsg = true,
1369 .arg_scnprintf = { [1] = SCA_SCHED_POLICY, /* policy */ }, },
1307 { .name = "seccomp", .errmsg = true, 1370 { .name = "seccomp", .errmsg = true,
1308 .arg_scnprintf = { [0] = SCA_SECCOMP_OP, /* op */ 1371 .arg_scnprintf = { [0] = SCA_SECCOMP_OP, /* op */
1309 [1] = SCA_SECCOMP_FLAGS, /* flags */ }, }, 1372 [1] = SCA_SECCOMP_FLAGS, /* flags */ }, },
@@ -1317,7 +1380,9 @@ static struct syscall_fmt {
1317 { .name = "sendto", .errmsg = true, 1380 { .name = "sendto", .errmsg = true,
1318 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 1381 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1319 [3] = SCA_MSG_FLAGS, /* flags */ }, }, 1382 [3] = SCA_MSG_FLAGS, /* flags */ }, },
1383 { .name = "set_tid_address", .errpid = true, },
1320 { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, 1384 { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), },
1385 { .name = "setpgid", .errmsg = true, },
1321 { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, 1386 { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
1322 { .name = "setxattr", .errmsg = true, 1387 { .name = "setxattr", .errmsg = true,
1323 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, }, 1388 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
@@ -1360,6 +1425,10 @@ static struct syscall_fmt {
1360 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, }, 1425 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1361 { .name = "vmsplice", .errmsg = true, 1426 { .name = "vmsplice", .errmsg = true,
1362 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 1427 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1428 { .name = "wait4", .errpid = true,
1429 .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, },
1430 { .name = "waitid", .errpid = true,
1431 .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, },
1363 { .name = "write", .errmsg = true, 1432 { .name = "write", .errmsg = true,
1364 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 1433 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1365 { .name = "writev", .errmsg = true, 1434 { .name = "writev", .errmsg = true,
@@ -1471,59 +1540,6 @@ fail:
1471 1540
1472static const size_t trace__entry_str_size = 2048; 1541static const size_t trace__entry_str_size = 2048;
1473 1542
1474struct trace {
1475 struct perf_tool tool;
1476 struct {
1477 int machine;
1478 int open_id;
1479 } audit;
1480 struct {
1481 int max;
1482 struct syscall *table;
1483 struct {
1484 struct perf_evsel *sys_enter,
1485 *sys_exit;
1486 } events;
1487 } syscalls;
1488 struct record_opts opts;
1489 struct perf_evlist *evlist;
1490 struct machine *host;
1491 struct thread *current;
1492 u64 base_time;
1493 FILE *output;
1494 unsigned long nr_events;
1495 struct strlist *ev_qualifier;
1496 struct {
1497 size_t nr;
1498 int *entries;
1499 } ev_qualifier_ids;
1500 struct intlist *tid_list;
1501 struct intlist *pid_list;
1502 struct {
1503 size_t nr;
1504 pid_t *entries;
1505 } filter_pids;
1506 double duration_filter;
1507 double runtime_ms;
1508 struct {
1509 u64 vfs_getname,
1510 proc_getname;
1511 } stats;
1512 bool not_ev_qualifier;
1513 bool live;
1514 bool full_time;
1515 bool sched;
1516 bool multiple_threads;
1517 bool summary;
1518 bool summary_only;
1519 bool show_comm;
1520 bool show_tool_stats;
1521 bool trace_syscalls;
1522 bool force;
1523 bool vfs_getname;
1524 int trace_pgfaults;
1525};
1526
1527static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) 1543static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)
1528{ 1544{
1529 struct thread_trace *ttrace = thread__priv(thread); 1545 struct thread_trace *ttrace = thread__priv(thread);
@@ -1749,6 +1765,10 @@ static int syscall__set_arg_fmts(struct syscall *sc)
1749 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; 1765 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
1750 else if (field->flags & FIELD_IS_POINTER) 1766 else if (field->flags & FIELD_IS_POINTER)
1751 sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; 1767 sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex;
1768 else if (strcmp(field->type, "pid_t") == 0)
1769 sc->arg_scnprintf[idx] = SCA_PID;
1770 else if (strcmp(field->type, "umode_t") == 0)
1771 sc->arg_scnprintf[idx] = SCA_MODE_T;
1752 ++idx; 1772 ++idx;
1753 } 1773 }
1754 1774
@@ -1759,7 +1779,7 @@ static int trace__read_syscall_info(struct trace *trace, int id)
1759{ 1779{
1760 char tp_name[128]; 1780 char tp_name[128];
1761 struct syscall *sc; 1781 struct syscall *sc;
1762 const char *name = audit_syscall_to_name(id, trace->audit.machine); 1782 const char *name = syscalltbl__name(trace->sctbl, id);
1763 1783
1764 if (name == NULL) 1784 if (name == NULL)
1765 return -1; 1785 return -1;
@@ -1834,7 +1854,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)
1834 1854
1835 strlist__for_each(pos, trace->ev_qualifier) { 1855 strlist__for_each(pos, trace->ev_qualifier) {
1836 const char *sc = pos->s; 1856 const char *sc = pos->s;
1837 int id = audit_name_to_syscall(sc, trace->audit.machine); 1857 int id = syscalltbl__id(trace->sctbl, sc);
1838 1858
1839 if (id < 0) { 1859 if (id < 0) {
1840 if (err == 0) { 1860 if (err == 0) {
@@ -2116,7 +2136,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
2116 2136
2117 ret = perf_evsel__sc_tp_uint(evsel, ret, sample); 2137 ret = perf_evsel__sc_tp_uint(evsel, ret, sample);
2118 2138
2119 if (id == trace->audit.open_id && ret >= 0 && ttrace->filename.pending_open) { 2139 if (id == trace->open_id && ret >= 0 && ttrace->filename.pending_open) {
2120 trace__set_fd_pathname(thread, ret, ttrace->filename.name); 2140 trace__set_fd_pathname(thread, ret, ttrace->filename.name);
2121 ttrace->filename.pending_open = false; 2141 ttrace->filename.pending_open = false;
2122 ++trace->stats.vfs_getname; 2142 ++trace->stats.vfs_getname;
@@ -2147,7 +2167,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
2147 if (sc->fmt == NULL) { 2167 if (sc->fmt == NULL) {
2148signed_print: 2168signed_print:
2149 fprintf(trace->output, ") = %ld", ret); 2169 fprintf(trace->output, ") = %ld", ret);
2150 } else if (ret < 0 && sc->fmt->errmsg) { 2170 } else if (ret < 0 && (sc->fmt->errmsg || sc->fmt->errpid)) {
2151 char bf[STRERR_BUFSIZE]; 2171 char bf[STRERR_BUFSIZE];
2152 const char *emsg = strerror_r(-ret, bf, sizeof(bf)), 2172 const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
2153 *e = audit_errno_to_name(-ret); 2173 *e = audit_errno_to_name(-ret);
@@ -2157,7 +2177,16 @@ signed_print:
2157 fprintf(trace->output, ") = 0 Timeout"); 2177 fprintf(trace->output, ") = 0 Timeout");
2158 else if (sc->fmt->hexret) 2178 else if (sc->fmt->hexret)
2159 fprintf(trace->output, ") = %#lx", ret); 2179 fprintf(trace->output, ") = %#lx", ret);
2160 else 2180 else if (sc->fmt->errpid) {
2181 struct thread *child = machine__find_thread(trace->host, ret, ret);
2182
2183 if (child != NULL) {
2184 fprintf(trace->output, ") = %ld", ret);
2185 if (child->comm_set)
2186 fprintf(trace->output, " (%s)", thread__comm_str(child));
2187 thread__put(child);
2188 }
2189 } else
2161 goto signed_print; 2190 goto signed_print;
2162 2191
2163 fputc('\n', trace->output); 2192 fputc('\n', trace->output);
@@ -3159,10 +3188,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
3159 NULL 3188 NULL
3160 }; 3189 };
3161 struct trace trace = { 3190 struct trace trace = {
3162 .audit = {
3163 .machine = audit_detect_machine(),
3164 .open_id = audit_name_to_syscall("open", trace.audit.machine),
3165 },
3166 .syscalls = { 3191 .syscalls = {
3167 . max = -1, 3192 . max = -1,
3168 }, 3193 },
@@ -3237,8 +3262,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
3237 signal(SIGFPE, sighandler_dump_stack); 3262 signal(SIGFPE, sighandler_dump_stack);
3238 3263
3239 trace.evlist = perf_evlist__new(); 3264 trace.evlist = perf_evlist__new();
3265 trace.sctbl = syscalltbl__new();
3240 3266
3241 if (trace.evlist == NULL) { 3267 if (trace.evlist == NULL || trace.sctbl == NULL) {
3242 pr_err("Not enough memory to run!\n"); 3268 pr_err("Not enough memory to run!\n");
3243 err = -ENOMEM; 3269 err = -ENOMEM;
3244 goto out; 3270 goto out;
@@ -3276,6 +3302,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
3276 } 3302 }
3277 } 3303 }
3278 3304
3305 trace.open_id = syscalltbl__id(trace.sctbl, "open");
3306
3279 if (ev_qualifier_str != NULL) { 3307 if (ev_qualifier_str != NULL) {
3280 const char *s = ev_qualifier_str; 3308 const char *s = ev_qualifier_str;
3281 struct strlist_config slist_config = { 3309 struct strlist_config slist_config = {
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index f7d7f5a1cad5..1e46277286c2 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -27,7 +27,7 @@ NO_PERF_REGS := 1
27ifeq ($(ARCH),x86) 27ifeq ($(ARCH),x86)
28 $(call detected,CONFIG_X86) 28 $(call detected,CONFIG_X86)
29 ifeq (${IS_64_BIT}, 1) 29 ifeq (${IS_64_BIT}, 1)
30 CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT 30 CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated
31 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S 31 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
32 LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 32 LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
33 $(call detected,CONFIG_X86_64) 33 $(call detected,CONFIG_X86_64)
@@ -268,6 +268,12 @@ else
268 ifneq ($(feature-dwarf), 1) 268 ifneq ($(feature-dwarf), 1)
269 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); 269 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
270 NO_DWARF := 1 270 NO_DWARF := 1
271 else
272 ifneq ($(feature-dwarf_getlocations), 1)
273 msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157);
274 else
275 CFLAGS += -DHAVE_DWARF_GETLOCATIONS
276 endif # dwarf_getlocations
271 endif # Dwarf support 277 endif # Dwarf support
272 endif # libelf support 278 endif # libelf support
273endif # NO_LIBELF 279endif # NO_LIBELF
@@ -289,9 +295,6 @@ ifndef NO_LIBELF
289 CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT 295 CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT
290 endif 296 endif
291 297
292 # include ARCH specific config
293 -include $(src-perf)/arch/$(ARCH)/Makefile
294
295 ifndef NO_DWARF 298 ifndef NO_DWARF
296 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) 299 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
297 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); 300 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
diff --git a/tools/perf/trace/beauty/mode_t.c b/tools/perf/trace/beauty/mode_t.c
new file mode 100644
index 000000000000..930d8fef2400
--- /dev/null
+++ b/tools/perf/trace/beauty/mode_t.c
@@ -0,0 +1,68 @@
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <unistd.h>
4
5/* From include/linux/stat.h */
6#ifndef S_IRWXUGO
7#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
8#endif
9#ifndef S_IALLUGO
10#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
11#endif
12#ifndef S_IRUGO
13#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
14#endif
15#ifndef S_IWUGO
16#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
17#endif
18#ifndef S_IXUGO
19#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
20#endif
21
22static size_t syscall_arg__scnprintf_mode_t(char *bf, size_t size, struct syscall_arg *arg)
23{
24 int printed = 0, mode = arg->val;
25
26#define P_MODE(n) \
27 if ((mode & S_##n) == S_##n) { \
28 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
29 mode &= ~S_##n; \
30 }
31
32 P_MODE(IALLUGO);
33 P_MODE(IRWXUGO);
34 P_MODE(IRUGO);
35 P_MODE(IWUGO);
36 P_MODE(IXUGO);
37 P_MODE(IFMT);
38 P_MODE(IFSOCK);
39 P_MODE(IFLNK);
40 P_MODE(IFREG);
41 P_MODE(IFBLK);
42 P_MODE(IFDIR);
43 P_MODE(IFCHR);
44 P_MODE(IFIFO);
45 P_MODE(ISUID);
46 P_MODE(ISGID);
47 P_MODE(ISVTX);
48 P_MODE(IRWXU);
49 P_MODE(IRUSR);
50 P_MODE(IWUSR);
51 P_MODE(IXUSR);
52 P_MODE(IRWXG);
53 P_MODE(IRGRP);
54 P_MODE(IWGRP);
55 P_MODE(IXGRP);
56 P_MODE(IRWXO);
57 P_MODE(IROTH);
58 P_MODE(IWOTH);
59 P_MODE(IXOTH);
60#undef P_MODE
61
62 if (mode)
63 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", mode);
64
65 return printed;
66}
67
68#define SCA_MODE_T syscall_arg__scnprintf_mode_t
diff --git a/tools/perf/trace/beauty/pid.c b/tools/perf/trace/beauty/pid.c
new file mode 100644
index 000000000000..111ae08d38f1
--- /dev/null
+++ b/tools/perf/trace/beauty/pid.c
@@ -0,0 +1,18 @@
1static size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg)
2{
3 int pid = arg->val;
4 struct trace *trace = arg->trace;
5 size_t printed = scnprintf(bf, size, "%d", pid);
6 struct thread *thread = machine__find_thread(trace->host, pid, pid);
7
8 if (thread != NULL) {
9 if (thread->comm_set)
10 printed += scnprintf(bf + printed, size - printed,
11 " (%s)", thread__comm_str(thread));
12 thread__put(thread);
13 }
14
15 return printed;
16}
17
18#define SCA_PID syscall_arg__scnprintf_pid
diff --git a/tools/perf/trace/beauty/sched_policy.c b/tools/perf/trace/beauty/sched_policy.c
new file mode 100644
index 000000000000..c205bc608b3c
--- /dev/null
+++ b/tools/perf/trace/beauty/sched_policy.c
@@ -0,0 +1,44 @@
1#include <sched.h>
2
3/*
4 * Not defined anywhere else, probably, just to make sure we
5 * catch future flags
6 */
7#define SCHED_POLICY_MASK 0xff
8
9#ifndef SCHED_DEADLINE
10#define SCHED_DEADLINE 6
11#endif
12
13static size_t syscall_arg__scnprintf_sched_policy(char *bf, size_t size,
14 struct syscall_arg *arg)
15{
16 const char *policies[] = {
17 "NORMAL", "FIFO", "RR", "BATCH", "ISO", "IDLE", "DEADLINE",
18 };
19 size_t printed;
20 int policy = arg->val,
21 flags = policy & ~SCHED_POLICY_MASK;
22
23 policy &= SCHED_POLICY_MASK;
24 if (policy <= SCHED_DEADLINE)
25 printed = scnprintf(bf, size, "%s", policies[policy]);
26 else
27 printed = scnprintf(bf, size, "%#x", policy);
28
29#define P_POLICY_FLAG(n) \
30 if (flags & SCHED_##n) { \
31 printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
32 flags &= ~SCHED_##n; \
33 }
34
35 P_POLICY_FLAG(RESET_ON_FORK);
36#undef P_POLICY_FLAG
37
38 if (flags)
39 printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
40
41 return printed;
42}
43
44#define SCA_SCHED_POLICY syscall_arg__scnprintf_sched_policy
diff --git a/tools/perf/trace/beauty/waitid_options.c b/tools/perf/trace/beauty/waitid_options.c
new file mode 100644
index 000000000000..7942724adec8
--- /dev/null
+++ b/tools/perf/trace/beauty/waitid_options.c
@@ -0,0 +1,26 @@
1#include <sys/types.h>
2#include <sys/wait.h>
3
4static size_t syscall_arg__scnprintf_waitid_options(char *bf, size_t size,
5 struct syscall_arg *arg)
6{
7 int printed = 0, options = arg->val;
8
9#define P_OPTION(n) \
10 if (options & W##n) { \
11 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
12 options &= ~W##n; \
13 }
14
15 P_OPTION(NOHANG);
16 P_OPTION(UNTRACED);
17 P_OPTION(CONTINUED);
18#undef P_OPTION
19
20 if (options)
21 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", options);
22
23 return printed;
24}
25
26#define SCA_WAITID_OPTIONS syscall_arg__scnprintf_waitid_options
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 2a83414159a6..e70df2e54d66 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1607,9 +1607,8 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows
1607 1607
1608 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); 1608 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists));
1609 dummy_hpp.buf[ret] = '\0'; 1609 dummy_hpp.buf[ret] = '\0';
1610 rtrim(dummy_hpp.buf);
1611 1610
1612 start = ltrim(dummy_hpp.buf); 1611 start = trim(dummy_hpp.buf);
1613 ret = strlen(start); 1612 ret = strlen(start);
1614 1613
1615 if (start != dummy_hpp.buf) 1614 if (start != dummy_hpp.buf)
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 7aff5acf3265..560eb47d56f9 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -569,9 +569,8 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
569 first_col = false; 569 first_col = false;
570 570
571 fmt->header(fmt, hpp, hists_to_evsel(hists)); 571 fmt->header(fmt, hpp, hists_to_evsel(hists));
572 rtrim(hpp->buf);
573 572
574 header_width += fprintf(fp, "%s", ltrim(hpp->buf)); 573 header_width += fprintf(fp, "%s", trim(hpp->buf));
575 } 574 }
576 } 575 }
577 576
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 85ceff357769..ea4ac03c1ec8 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -38,6 +38,7 @@ libperf-y += machine.o
38libperf-y += map.o 38libperf-y += map.o
39libperf-y += pstack.o 39libperf-y += pstack.o
40libperf-y += session.o 40libperf-y += session.o
41libperf-$(CONFIG_AUDIT) += syscalltbl.o
41libperf-y += ordered-events.o 42libperf-y += ordered-events.o
42libperf-y += comm.o 43libperf-y += comm.o
43libperf-y += thread.o 44libperf-y += thread.o
@@ -147,6 +148,10 @@ CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ET
147CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" 148CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
148CFLAGS_parse-events.o += -Wno-redundant-decls 149CFLAGS_parse-events.o += -Wno-redundant-decls
149 150
151$(OUTPUT)util/syscalltbl.o: util/syscalltbl.c arch/x86/entry/syscalls/syscall_64.tbl $(OUTPUT)arch/x86/include/generated/asm/syscalls_64.c FORCE
152 $(call rule_mkdir)
153 $(call if_changed_dep,cc_o_c)
154
150$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE 155$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE
151 $(call rule_mkdir) 156 $(call rule_mkdir)
152 $(call if_changed_dep,cc_o_c) 157 $(call if_changed_dep,cc_o_c)
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 5c20d783423b..664490b8b327 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -381,11 +381,11 @@ static int perf_buildid_config(const char *var, const char *value)
381{ 381{
382 /* same dir for all commands */ 382 /* same dir for all commands */
383 if (!strcmp(var, "buildid.dir")) { 383 if (!strcmp(var, "buildid.dir")) {
384 const char *dirname = perf_config_dirname(var, value); 384 const char *dir = perf_config_dirname(var, value);
385 385
386 if (!dirname) 386 if (!dir)
387 return -1; 387 return -1;
388 strncpy(buildid_dir, dirname, MAXPATHLEN-1); 388 strncpy(buildid_dir, dir, MAXPATHLEN-1);
389 buildid_dir[MAXPATHLEN-1] = '\0'; 389 buildid_dir[MAXPATHLEN-1] = '\0';
390 } 390 }
391 391
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 577e600c8eb1..aea189b41cc8 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -959,6 +959,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
959 return 0; 959 return 0;
960} 960}
961 961
962#ifdef HAVE_DWARF_GETLOCATIONS
962/** 963/**
963 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE 964 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE
964 * @sp_die: a subprogram DIE 965 * @sp_die: a subprogram DIE
@@ -1080,3 +1081,11 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
1080 1081
1081 return ret; 1082 return ret;
1082} 1083}
1084#else
1085int die_get_var_range(Dwarf_Die *sp_die __maybe_unused,
1086 Dwarf_Die *vr_die __maybe_unused,
1087 struct strbuf *buf __maybe_unused)
1088{
1089 return -ENOTSUP;
1090}
1091#endif
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 171b6d10a04b..02c31865648b 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -431,6 +431,13 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
431 if (map->dso->rel) 431 if (map->dso->rel)
432 return rip - map->pgoff; 432 return rip - map->pgoff;
433 433
434 /*
435 * kernel modules also have DSO_TYPE_USER in dso->kernel,
436 * but all kernel modules are ET_REL, so won't get here.
437 */
438 if (map->dso->kernel == DSO_TYPE_USER)
439 return rip + map->dso->text_offset;
440
434 return map->unmap_ip(map, rip) - map->reloc; 441 return map->unmap_ip(map, rip) - map->reloc;
435} 442}
436 443
@@ -454,6 +461,13 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
454 if (map->dso->rel) 461 if (map->dso->rel)
455 return map->unmap_ip(map, ip + map->pgoff); 462 return map->unmap_ip(map, ip + map->pgoff);
456 463
464 /*
465 * kernel modules also have DSO_TYPE_USER in dso->kernel,
466 * but all kernel modules are ET_REL, so won't get here.
467 */
468 if (map->dso->kernel == DSO_TYPE_USER)
469 return map->unmap_ip(map, ip - map->dso->text_offset);
470
457 return ip + map->reloc; 471 return ip + map->reloc;
458} 472}
459 473
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 1d160855cda9..35ed00a600fb 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -283,18 +283,27 @@ static SV *perl_process_callchain(struct perf_sample *sample,
283 if (!elem) 283 if (!elem)
284 goto exit; 284 goto exit;
285 285
286 hv_stores(elem, "ip", newSVuv(node->ip)); 286 if (!hv_stores(elem, "ip", newSVuv(node->ip))) {
287 hv_undef(elem);
288 goto exit;
289 }
287 290
288 if (node->sym) { 291 if (node->sym) {
289 HV *sym = newHV(); 292 HV *sym = newHV();
290 if (!sym) 293 if (!sym) {
294 hv_undef(elem);
295 goto exit;
296 }
297 if (!hv_stores(sym, "start", newSVuv(node->sym->start)) ||
298 !hv_stores(sym, "end", newSVuv(node->sym->end)) ||
299 !hv_stores(sym, "binding", newSVuv(node->sym->binding)) ||
300 !hv_stores(sym, "name", newSVpvn(node->sym->name,
301 node->sym->namelen)) ||
302 !hv_stores(elem, "sym", newRV_noinc((SV*)sym))) {
303 hv_undef(sym);
304 hv_undef(elem);
291 goto exit; 305 goto exit;
292 hv_stores(sym, "start", newSVuv(node->sym->start)); 306 }
293 hv_stores(sym, "end", newSVuv(node->sym->end));
294 hv_stores(sym, "binding", newSVuv(node->sym->binding));
295 hv_stores(sym, "name", newSVpvn(node->sym->name,
296 node->sym->namelen));
297 hv_stores(elem, "sym", newRV_noinc((SV*)sym));
298 } 307 }
299 308
300 if (node->map) { 309 if (node->map) {
@@ -306,7 +315,10 @@ static SV *perl_process_callchain(struct perf_sample *sample,
306 else if (map->dso->name) 315 else if (map->dso->name)
307 dsoname = map->dso->name; 316 dsoname = map->dso->name;
308 } 317 }
309 hv_stores(elem, "dso", newSVpv(dsoname,0)); 318 if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) {
319 hv_undef(elem);
320 goto exit;
321 }
310 } 322 }
311 323
312 callchain_cursor_advance(&callchain_cursor); 324 callchain_cursor_advance(&callchain_cursor);
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index bc229a74c6a9..3f9d6798bd18 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -709,17 +709,10 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
709 if (ss->opdshdr.sh_type != SHT_PROGBITS) 709 if (ss->opdshdr.sh_type != SHT_PROGBITS)
710 ss->opdsec = NULL; 710 ss->opdsec = NULL;
711 711
712 if (dso->kernel == DSO_TYPE_USER) { 712 if (dso->kernel == DSO_TYPE_USER)
713 GElf_Shdr shdr; 713 ss->adjust_symbols = true;
714 ss->adjust_symbols = (ehdr.e_type == ET_EXEC || 714 else
715 ehdr.e_type == ET_REL ||
716 dso__is_vdso(dso) ||
717 elf_section_by_name(elf, &ehdr, &shdr,
718 ".gnu.prelink_undo",
719 NULL) != NULL);
720 } else {
721 ss->adjust_symbols = elf__needs_adjust_symbols(ehdr); 715 ss->adjust_symbols = elf__needs_adjust_symbols(ehdr);
722 }
723 716
724 ss->name = strdup(name); 717 ss->name = strdup(name);
725 if (!ss->name) { 718 if (!ss->name) {
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
new file mode 100644
index 000000000000..bbb4c1957578
--- /dev/null
+++ b/tools/perf/util/syscalltbl.c
@@ -0,0 +1,134 @@
1/*
2 * System call table mapper
3 *
4 * (C) 2016 Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15
16#include "syscalltbl.h"
17#include <stdlib.h>
18
19#ifdef HAVE_SYSCALL_TABLE
20#include <linux/compiler.h>
21#include <string.h>
22#include "util.h"
23
24#if defined(__x86_64__)
25#include <asm/syscalls_64.c>
26const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
27static const char **syscalltbl_native = syscalltbl_x86_64;
28#endif
29
30struct syscall {
31 int id;
32 const char *name;
33};
34
35static int syscallcmpname(const void *vkey, const void *ventry)
36{
37 const char *key = vkey;
38 const struct syscall *entry = ventry;
39
40 return strcmp(key, entry->name);
41}
42
43static int syscallcmp(const void *va, const void *vb)
44{
45 const struct syscall *a = va, *b = vb;
46
47 return strcmp(a->name, b->name);
48}
49
50static int syscalltbl__init_native(struct syscalltbl *tbl)
51{
52 int nr_entries = 0, i, j;
53 struct syscall *entries;
54
55 for (i = 0; i <= syscalltbl_native_max_id; ++i)
56 if (syscalltbl_native[i])
57 ++nr_entries;
58
59 entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
60 if (tbl->syscalls.entries == NULL)
61 return -1;
62
63 for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
64 if (syscalltbl_native[i]) {
65 entries[j].name = syscalltbl_native[i];
66 entries[j].id = i;
67 ++j;
68 }
69 }
70
71 qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
72 tbl->syscalls.nr_entries = nr_entries;
73 return 0;
74}
75
76struct syscalltbl *syscalltbl__new(void)
77{
78 struct syscalltbl *tbl = malloc(sizeof(*tbl));
79 if (tbl) {
80 if (syscalltbl__init_native(tbl)) {
81 free(tbl);
82 return NULL;
83 }
84 }
85 return tbl;
86}
87
88void syscalltbl__delete(struct syscalltbl *tbl)
89{
90 zfree(&tbl->syscalls.entries);
91 free(tbl);
92}
93
94const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
95{
96 return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
97}
98
99int syscalltbl__id(struct syscalltbl *tbl, const char *name)
100{
101 struct syscall *sc = bsearch(name, tbl->syscalls.entries,
102 tbl->syscalls.nr_entries, sizeof(*sc),
103 syscallcmpname);
104
105 return sc ? sc->id : -1;
106}
107
108#else /* HAVE_SYSCALL_TABLE */
109
110#include <libaudit.h>
111
112struct syscalltbl *syscalltbl__new(void)
113{
114 struct syscalltbl *tbl = malloc(sizeof(*tbl));
115 if (tbl)
116 tbl->audit_machine = audit_detect_machine();
117 return tbl;
118}
119
120void syscalltbl__delete(struct syscalltbl *tbl)
121{
122 free(tbl);
123}
124
125const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
126{
127 return audit_syscall_to_name(id, tbl->audit_machine);
128}
129
130int syscalltbl__id(struct syscalltbl *tbl, const char *name)
131{
132 return audit_name_to_syscall(name, tbl->audit_machine);
133}
134#endif /* HAVE_SYSCALL_TABLE */
diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h
new file mode 100644
index 000000000000..e2951510484f
--- /dev/null
+++ b/tools/perf/util/syscalltbl.h
@@ -0,0 +1,20 @@
1#ifndef __PERF_SYSCALLTBL_H
2#define __PERF_SYSCALLTBL_H
3
4struct syscalltbl {
5 union {
6 int audit_machine;
7 struct {
8 int nr_entries;
9 void *entries;
10 } syscalls;
11 };
12};
13
14struct syscalltbl *syscalltbl__new(void);
15void syscalltbl__delete(struct syscalltbl *tbl);
16
17const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
18int syscalltbl__id(struct syscalltbl *tbl, const char *name);
19
20#endif /* __PERF_SYSCALLTBL_H */
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index a0ac0317affb..e214207bb13a 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -9,6 +9,9 @@
9#include "symbol.h" 9#include "symbol.h"
10#include <strlist.h> 10#include <strlist.h>
11#include <intlist.h> 11#include <intlist.h>
12#ifdef HAVE_LIBUNWIND_SUPPORT
13#include <libunwind.h>
14#endif
12 15
13struct thread_stack; 16struct thread_stack;
14 17
@@ -32,6 +35,9 @@ struct thread {
32 35
33 void *priv; 36 void *priv;
34 struct thread_stack *ts; 37 struct thread_stack *ts;
38#ifdef HAVE_LIBUNWIND_SUPPORT
39 unw_addr_space_t addr_space;
40#endif
35}; 41};
36 42
37struct machine; 43struct machine;
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index ee7e372297e5..63687d3a344e 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -32,6 +32,7 @@
32#include "symbol.h" 32#include "symbol.h"
33#include "util.h" 33#include "util.h"
34#include "debug.h" 34#include "debug.h"
35#include "asm/bug.h"
35 36
36extern int 37extern int
37UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, 38UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
@@ -580,43 +581,33 @@ static unw_accessors_t accessors = {
580 581
581int unwind__prepare_access(struct thread *thread) 582int unwind__prepare_access(struct thread *thread)
582{ 583{
583 unw_addr_space_t addr_space;
584
585 if (callchain_param.record_mode != CALLCHAIN_DWARF) 584 if (callchain_param.record_mode != CALLCHAIN_DWARF)
586 return 0; 585 return 0;
587 586
588 addr_space = unw_create_addr_space(&accessors, 0); 587 thread->addr_space = unw_create_addr_space(&accessors, 0);
589 if (!addr_space) { 588 if (!thread->addr_space) {
590 pr_err("unwind: Can't create unwind address space.\n"); 589 pr_err("unwind: Can't create unwind address space.\n");
591 return -ENOMEM; 590 return -ENOMEM;
592 } 591 }
593 592
594 unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL); 593 unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
595 thread__set_priv(thread, addr_space);
596
597 return 0; 594 return 0;
598} 595}
599 596
600void unwind__flush_access(struct thread *thread) 597void unwind__flush_access(struct thread *thread)
601{ 598{
602 unw_addr_space_t addr_space;
603
604 if (callchain_param.record_mode != CALLCHAIN_DWARF) 599 if (callchain_param.record_mode != CALLCHAIN_DWARF)
605 return; 600 return;
606 601
607 addr_space = thread__priv(thread); 602 unw_flush_cache(thread->addr_space, 0, 0);
608 unw_flush_cache(addr_space, 0, 0);
609} 603}
610 604
611void unwind__finish_access(struct thread *thread) 605void unwind__finish_access(struct thread *thread)
612{ 606{
613 unw_addr_space_t addr_space;
614
615 if (callchain_param.record_mode != CALLCHAIN_DWARF) 607 if (callchain_param.record_mode != CALLCHAIN_DWARF)
616 return; 608 return;
617 609
618 addr_space = thread__priv(thread); 610 unw_destroy_addr_space(thread->addr_space);
619 unw_destroy_addr_space(addr_space);
620} 611}
621 612
622static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, 613static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
@@ -639,7 +630,9 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
639 * unwind itself. 630 * unwind itself.
640 */ 631 */
641 if (max_stack - 1 > 0) { 632 if (max_stack - 1 > 0) {
642 addr_space = thread__priv(ui->thread); 633 WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
634 addr_space = ui->thread->addr_space;
635
643 if (addr_space == NULL) 636 if (addr_space == NULL)
644 return -1; 637 return -1;
645 638
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 8298d607c738..3bf3de86d429 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -254,6 +254,11 @@ int hex2u64(const char *ptr, u64 *val);
254char *ltrim(char *s); 254char *ltrim(char *s);
255char *rtrim(char *s); 255char *rtrim(char *s);
256 256
257static inline char *trim(char *s)
258{
259 return ltrim(rtrim(s));
260}
261
257void dump_stack(void); 262void dump_stack(void);
258void sighandler_dump_stack(int sig); 263void sighandler_dump_stack(int sig);
259 264