diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-04-13 02:57:50 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-04-13 02:57:50 -0400 |
commit | aeaae7d612ff2ad647ba422099da56eb3aa89237 (patch) | |
tree | bad2e6634e57c9d0d24a67086620ffca86dc5313 | |
parent | 889fac6d67d46a5e781c08fb26fec9016db1c307 (diff) | |
parent | 99e87f7bb7268cf644add87130590966fd5d0d17 (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>
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 | |||
30 | FEATURE_TESTS_BASIC := \ | 30 | FEATURE_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 | ||
79 | FEATURE_DISPLAY ?= \ | 80 | FEATURE_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 | |||
4 | int 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: | |||
93 | You should refer to the processor specific documentation for getting these | 93 | You should refer to the processor specific documentation for getting these |
94 | details. Some of them are referenced in the SEE ALSO section below. | 94 | details. Some of them are referenced in the SEE ALSO section below. |
95 | 95 | ||
96 | ARBITRARY PMUS | ||
97 | -------------- | ||
98 | |||
99 | perf also supports an extended syntax for specifying raw parameters | ||
100 | to PMUs. Using this typically requires looking up the specific event | ||
101 | in the CPU vendor specific documentation. | ||
102 | |||
103 | The available PMUs and their raw parameters can be listed with | ||
104 | |||
105 | ls /sys/devices/*/format | ||
106 | |||
107 | For example the raw event "LSD.UOPS" core pmu event above could | ||
108 | be specified as | ||
109 | |||
110 | perf stat -e cpu/event=0xa8,umask=0x1,name=LSD.UOPS_CYCLES,cmask=1/ ... | ||
111 | |||
112 | PER SOCKET PMUS | ||
113 | --------------- | ||
114 | |||
115 | Some PMUs are not associated with a core, but with a whole CPU socket. | ||
116 | Events on these PMUs generally cannot be sampled, but only counted globally | ||
117 | with perf stat -a. They can be bound to one logical CPU, but will measure | ||
118 | all the CPUs in the same socket. | ||
119 | |||
120 | This example measures memory bandwidth every second | ||
121 | on 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 | |||
125 | Each memory controller has its own PMU. Measuring the complete system | ||
126 | bandwidth would require specifying all imc PMUs (see perf list output), | ||
127 | and adding the values together. | ||
128 | |||
129 | This example measures the combined core power every second | ||
130 | |||
131 | perf stat -I 1000 -e power/energy-cores/ -a | ||
132 | |||
133 | ACCESS RESTRICTIONS | ||
134 | ------------------- | ||
135 | |||
136 | For non root users generally only context switched PMU events are available. | ||
137 | This is normally only the events in the cpu PMU, the predefined events | ||
138 | like cycles and instructions and some software events. | ||
139 | |||
140 | Other PMUs and global measurements are normally root only. | ||
141 | Some event qualifiers, such as "any", are also root only. | ||
142 | |||
143 | This can be overriden by setting the kernel.perf_event_paranoid | ||
144 | sysctl to -1, which allows non root to use these events. | ||
145 | |||
146 | For 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 | ||
148 | setting. | ||
149 | |||
150 | TRACING | ||
151 | ------- | ||
152 | |||
153 | Some PMUs control advanced hardware tracing capabilities, such as Intel PT, | ||
154 | that allows low overhead execution tracing. These are described in a separate | ||
155 | intel-pt.txt document. | ||
156 | |||
96 | PARAMETERIZED EVENTS | 157 | PARAMETERIZED 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 | ||
170 | EVENT GROUPS | ||
171 | ------------ | ||
172 | |||
173 | Perf supports time based multiplexing of events, when the number of events | ||
174 | active exceeds the number of hardware performance counters. Multiplexing | ||
175 | can cause measurement errors when the workload changes its execution | ||
176 | profile. | ||
177 | |||
178 | When metrics are computed using formulas from event counts, it is useful to | ||
179 | ensure some events are always measured together as a group to minimize multiplexing | ||
180 | errors. Event groups can be specified using { }. | ||
181 | |||
182 | perf stat -e '{instructions,cycles}' ... | ||
183 | |||
184 | The number of available performance counters depend on the CPU. A group | ||
185 | cannot contain more events than available counters. | ||
186 | For example Intel Core CPUs typically have four generic performance counters | ||
187 | for the core, plus three fixed counters for instructions, cycles and | ||
188 | ref-cycles. Some special events have restrictions on which counter they | ||
189 | can schedule, and may not support multiple instances in a single group. | ||
190 | When too many events are specified in the group none of them will not | ||
191 | be measured. | ||
192 | |||
193 | Globally pinned events can limit the number of counters available for | ||
194 | other groups. On x86 systems, the NMI watchdog pins a counter by default. | ||
195 | The nmi watchdog can be disabled as root with | ||
196 | |||
197 | echo 0 > /proc/sys/kernel/nmi_watchdog | ||
198 | |||
199 | Events from multiple different PMUs cannot be mixed in a group, with | ||
200 | some exceptions for software events. | ||
201 | |||
202 | LEADER SAMPLING | ||
203 | --------------- | ||
204 | |||
205 | perf also supports group leader sampling using the :S specifier. | ||
206 | |||
207 | perf record -e '{cycles,instructions}:S' ... | ||
208 | perf report --group | ||
209 | |||
210 | Normally all events in a event group sample, but with :S only | ||
211 | the first event (the leader) samples, and it only reads the values of the | ||
212 | other events in the group. | ||
213 | |||
109 | OPTIONS | 214 | OPTIONS |
110 | ------- | 215 | ------- |
111 | 216 | ||
@@ -143,5 +248,5 @@ SEE ALSO | |||
143 | -------- | 248 | -------- |
144 | linkperf:perf-stat[1], linkperf:perf-top[1], | 249 | linkperf:perf-stat[1], linkperf:perf-top[1], |
145 | linkperf:perf-record[1], | 250 | linkperf:perf-record[1], |
146 | http://www.intel.com/Assets/PDF/manual/253669.pdf[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide], | 251 | http://www.intel.com/sdm/[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide], |
147 | http://support.amd.com/us/Processor_TechDocs/24593_APM_v2.pdf[AMD64 Architecture Programmer’s Manual Volume 2: System Programming] | 252 | http://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 | |||
183 | include config/Makefile | 183 | include config/Makefile |
184 | endif | 184 | endif |
185 | 185 | ||
186 | ifeq ($(config),0) | ||
187 | include $(srctree)/tools/scripts/Makefile.arch | ||
188 | -include arch/$(ARCH)/Makefile | ||
189 | endif | ||
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 | |||
302 | ifneq ($(OUTPUT),) | 305 | ifneq ($(OUTPUT),) |
303 | CFLAGS += -I$(OUTPUT) | 306 | CFLAGS += -I$(OUTPUT) |
304 | endif | 307 | endif |
@@ -390,7 +393,7 @@ endif | |||
390 | __build-dir = $(subst $(OUTPUT),,$(dir $@)) | 393 | __build-dir = $(subst $(OUTPUT),,$(dir $@)) |
391 | build-dir = $(if $(__build-dir),$(__build-dir),.) | 394 | build-dir = $(if $(__build-dir),$(__build-dir),.) |
392 | 395 | ||
393 | prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep | 396 | prepare: $(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 | ||
431 | LIBPERF_IN := $(OUTPUT)libperf-in.o | 434 | LIBPERF_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 | ||
628 | clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean | 631 | clean:: $(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 | |||
4 | HAVE_KVM_STAT_SUPPORT := 1 | 4 | HAVE_KVM_STAT_SUPPORT := 1 |
5 | PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 | 5 | PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 |
6 | PERF_HAVE_JITDUMP := 1 | 6 | PERF_HAVE_JITDUMP := 1 |
7 | |||
8 | ### | ||
9 | # Syscall table generation | ||
10 | # | ||
11 | |||
12 | out := $(OUTPUT)arch/x86/include/generated/asm | ||
13 | header := $(out)/syscalls_64.c | ||
14 | sys := $(srctree)/tools/perf/arch/x86/entry/syscalls | ||
15 | systbl := $(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 | |||
26 | clean:: | ||
27 | rm -f $(header) | ||
28 | |||
29 | archheaders: $(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 | # | ||
9 | 0 common read sys_read | ||
10 | 1 common write sys_write | ||
11 | 2 common open sys_open | ||
12 | 3 common close sys_close | ||
13 | 4 common stat sys_newstat | ||
14 | 5 common fstat sys_newfstat | ||
15 | 6 common lstat sys_newlstat | ||
16 | 7 common poll sys_poll | ||
17 | 8 common lseek sys_lseek | ||
18 | 9 common mmap sys_mmap | ||
19 | 10 common mprotect sys_mprotect | ||
20 | 11 common munmap sys_munmap | ||
21 | 12 common brk sys_brk | ||
22 | 13 64 rt_sigaction sys_rt_sigaction | ||
23 | 14 common rt_sigprocmask sys_rt_sigprocmask | ||
24 | 15 64 rt_sigreturn sys_rt_sigreturn/ptregs | ||
25 | 16 64 ioctl sys_ioctl | ||
26 | 17 common pread64 sys_pread64 | ||
27 | 18 common pwrite64 sys_pwrite64 | ||
28 | 19 64 readv sys_readv | ||
29 | 20 64 writev sys_writev | ||
30 | 21 common access sys_access | ||
31 | 22 common pipe sys_pipe | ||
32 | 23 common select sys_select | ||
33 | 24 common sched_yield sys_sched_yield | ||
34 | 25 common mremap sys_mremap | ||
35 | 26 common msync sys_msync | ||
36 | 27 common mincore sys_mincore | ||
37 | 28 common madvise sys_madvise | ||
38 | 29 common shmget sys_shmget | ||
39 | 30 common shmat sys_shmat | ||
40 | 31 common shmctl sys_shmctl | ||
41 | 32 common dup sys_dup | ||
42 | 33 common dup2 sys_dup2 | ||
43 | 34 common pause sys_pause | ||
44 | 35 common nanosleep sys_nanosleep | ||
45 | 36 common getitimer sys_getitimer | ||
46 | 37 common alarm sys_alarm | ||
47 | 38 common setitimer sys_setitimer | ||
48 | 39 common getpid sys_getpid | ||
49 | 40 common sendfile sys_sendfile64 | ||
50 | 41 common socket sys_socket | ||
51 | 42 common connect sys_connect | ||
52 | 43 common accept sys_accept | ||
53 | 44 common sendto sys_sendto | ||
54 | 45 64 recvfrom sys_recvfrom | ||
55 | 46 64 sendmsg sys_sendmsg | ||
56 | 47 64 recvmsg sys_recvmsg | ||
57 | 48 common shutdown sys_shutdown | ||
58 | 49 common bind sys_bind | ||
59 | 50 common listen sys_listen | ||
60 | 51 common getsockname sys_getsockname | ||
61 | 52 common getpeername sys_getpeername | ||
62 | 53 common socketpair sys_socketpair | ||
63 | 54 64 setsockopt sys_setsockopt | ||
64 | 55 64 getsockopt sys_getsockopt | ||
65 | 56 common clone sys_clone/ptregs | ||
66 | 57 common fork sys_fork/ptregs | ||
67 | 58 common vfork sys_vfork/ptregs | ||
68 | 59 64 execve sys_execve/ptregs | ||
69 | 60 common exit sys_exit | ||
70 | 61 common wait4 sys_wait4 | ||
71 | 62 common kill sys_kill | ||
72 | 63 common uname sys_newuname | ||
73 | 64 common semget sys_semget | ||
74 | 65 common semop sys_semop | ||
75 | 66 common semctl sys_semctl | ||
76 | 67 common shmdt sys_shmdt | ||
77 | 68 common msgget sys_msgget | ||
78 | 69 common msgsnd sys_msgsnd | ||
79 | 70 common msgrcv sys_msgrcv | ||
80 | 71 common msgctl sys_msgctl | ||
81 | 72 common fcntl sys_fcntl | ||
82 | 73 common flock sys_flock | ||
83 | 74 common fsync sys_fsync | ||
84 | 75 common fdatasync sys_fdatasync | ||
85 | 76 common truncate sys_truncate | ||
86 | 77 common ftruncate sys_ftruncate | ||
87 | 78 common getdents sys_getdents | ||
88 | 79 common getcwd sys_getcwd | ||
89 | 80 common chdir sys_chdir | ||
90 | 81 common fchdir sys_fchdir | ||
91 | 82 common rename sys_rename | ||
92 | 83 common mkdir sys_mkdir | ||
93 | 84 common rmdir sys_rmdir | ||
94 | 85 common creat sys_creat | ||
95 | 86 common link sys_link | ||
96 | 87 common unlink sys_unlink | ||
97 | 88 common symlink sys_symlink | ||
98 | 89 common readlink sys_readlink | ||
99 | 90 common chmod sys_chmod | ||
100 | 91 common fchmod sys_fchmod | ||
101 | 92 common chown sys_chown | ||
102 | 93 common fchown sys_fchown | ||
103 | 94 common lchown sys_lchown | ||
104 | 95 common umask sys_umask | ||
105 | 96 common gettimeofday sys_gettimeofday | ||
106 | 97 common getrlimit sys_getrlimit | ||
107 | 98 common getrusage sys_getrusage | ||
108 | 99 common sysinfo sys_sysinfo | ||
109 | 100 common times sys_times | ||
110 | 101 64 ptrace sys_ptrace | ||
111 | 102 common getuid sys_getuid | ||
112 | 103 common syslog sys_syslog | ||
113 | 104 common getgid sys_getgid | ||
114 | 105 common setuid sys_setuid | ||
115 | 106 common setgid sys_setgid | ||
116 | 107 common geteuid sys_geteuid | ||
117 | 108 common getegid sys_getegid | ||
118 | 109 common setpgid sys_setpgid | ||
119 | 110 common getppid sys_getppid | ||
120 | 111 common getpgrp sys_getpgrp | ||
121 | 112 common setsid sys_setsid | ||
122 | 113 common setreuid sys_setreuid | ||
123 | 114 common setregid sys_setregid | ||
124 | 115 common getgroups sys_getgroups | ||
125 | 116 common setgroups sys_setgroups | ||
126 | 117 common setresuid sys_setresuid | ||
127 | 118 common getresuid sys_getresuid | ||
128 | 119 common setresgid sys_setresgid | ||
129 | 120 common getresgid sys_getresgid | ||
130 | 121 common getpgid sys_getpgid | ||
131 | 122 common setfsuid sys_setfsuid | ||
132 | 123 common setfsgid sys_setfsgid | ||
133 | 124 common getsid sys_getsid | ||
134 | 125 common capget sys_capget | ||
135 | 126 common capset sys_capset | ||
136 | 127 64 rt_sigpending sys_rt_sigpending | ||
137 | 128 64 rt_sigtimedwait sys_rt_sigtimedwait | ||
138 | 129 64 rt_sigqueueinfo sys_rt_sigqueueinfo | ||
139 | 130 common rt_sigsuspend sys_rt_sigsuspend | ||
140 | 131 64 sigaltstack sys_sigaltstack | ||
141 | 132 common utime sys_utime | ||
142 | 133 common mknod sys_mknod | ||
143 | 134 64 uselib | ||
144 | 135 common personality sys_personality | ||
145 | 136 common ustat sys_ustat | ||
146 | 137 common statfs sys_statfs | ||
147 | 138 common fstatfs sys_fstatfs | ||
148 | 139 common sysfs sys_sysfs | ||
149 | 140 common getpriority sys_getpriority | ||
150 | 141 common setpriority sys_setpriority | ||
151 | 142 common sched_setparam sys_sched_setparam | ||
152 | 143 common sched_getparam sys_sched_getparam | ||
153 | 144 common sched_setscheduler sys_sched_setscheduler | ||
154 | 145 common sched_getscheduler sys_sched_getscheduler | ||
155 | 146 common sched_get_priority_max sys_sched_get_priority_max | ||
156 | 147 common sched_get_priority_min sys_sched_get_priority_min | ||
157 | 148 common sched_rr_get_interval sys_sched_rr_get_interval | ||
158 | 149 common mlock sys_mlock | ||
159 | 150 common munlock sys_munlock | ||
160 | 151 common mlockall sys_mlockall | ||
161 | 152 common munlockall sys_munlockall | ||
162 | 153 common vhangup sys_vhangup | ||
163 | 154 common modify_ldt sys_modify_ldt | ||
164 | 155 common pivot_root sys_pivot_root | ||
165 | 156 64 _sysctl sys_sysctl | ||
166 | 157 common prctl sys_prctl | ||
167 | 158 common arch_prctl sys_arch_prctl | ||
168 | 159 common adjtimex sys_adjtimex | ||
169 | 160 common setrlimit sys_setrlimit | ||
170 | 161 common chroot sys_chroot | ||
171 | 162 common sync sys_sync | ||
172 | 163 common acct sys_acct | ||
173 | 164 common settimeofday sys_settimeofday | ||
174 | 165 common mount sys_mount | ||
175 | 166 common umount2 sys_umount | ||
176 | 167 common swapon sys_swapon | ||
177 | 168 common swapoff sys_swapoff | ||
178 | 169 common reboot sys_reboot | ||
179 | 170 common sethostname sys_sethostname | ||
180 | 171 common setdomainname sys_setdomainname | ||
181 | 172 common iopl sys_iopl/ptregs | ||
182 | 173 common ioperm sys_ioperm | ||
183 | 174 64 create_module | ||
184 | 175 common init_module sys_init_module | ||
185 | 176 common delete_module sys_delete_module | ||
186 | 177 64 get_kernel_syms | ||
187 | 178 64 query_module | ||
188 | 179 common quotactl sys_quotactl | ||
189 | 180 64 nfsservctl | ||
190 | 181 common getpmsg | ||
191 | 182 common putpmsg | ||
192 | 183 common afs_syscall | ||
193 | 184 common tuxcall | ||
194 | 185 common security | ||
195 | 186 common gettid sys_gettid | ||
196 | 187 common readahead sys_readahead | ||
197 | 188 common setxattr sys_setxattr | ||
198 | 189 common lsetxattr sys_lsetxattr | ||
199 | 190 common fsetxattr sys_fsetxattr | ||
200 | 191 common getxattr sys_getxattr | ||
201 | 192 common lgetxattr sys_lgetxattr | ||
202 | 193 common fgetxattr sys_fgetxattr | ||
203 | 194 common listxattr sys_listxattr | ||
204 | 195 common llistxattr sys_llistxattr | ||
205 | 196 common flistxattr sys_flistxattr | ||
206 | 197 common removexattr sys_removexattr | ||
207 | 198 common lremovexattr sys_lremovexattr | ||
208 | 199 common fremovexattr sys_fremovexattr | ||
209 | 200 common tkill sys_tkill | ||
210 | 201 common time sys_time | ||
211 | 202 common futex sys_futex | ||
212 | 203 common sched_setaffinity sys_sched_setaffinity | ||
213 | 204 common sched_getaffinity sys_sched_getaffinity | ||
214 | 205 64 set_thread_area | ||
215 | 206 64 io_setup sys_io_setup | ||
216 | 207 common io_destroy sys_io_destroy | ||
217 | 208 common io_getevents sys_io_getevents | ||
218 | 209 64 io_submit sys_io_submit | ||
219 | 210 common io_cancel sys_io_cancel | ||
220 | 211 64 get_thread_area | ||
221 | 212 common lookup_dcookie sys_lookup_dcookie | ||
222 | 213 common epoll_create sys_epoll_create | ||
223 | 214 64 epoll_ctl_old | ||
224 | 215 64 epoll_wait_old | ||
225 | 216 common remap_file_pages sys_remap_file_pages | ||
226 | 217 common getdents64 sys_getdents64 | ||
227 | 218 common set_tid_address sys_set_tid_address | ||
228 | 219 common restart_syscall sys_restart_syscall | ||
229 | 220 common semtimedop sys_semtimedop | ||
230 | 221 common fadvise64 sys_fadvise64 | ||
231 | 222 64 timer_create sys_timer_create | ||
232 | 223 common timer_settime sys_timer_settime | ||
233 | 224 common timer_gettime sys_timer_gettime | ||
234 | 225 common timer_getoverrun sys_timer_getoverrun | ||
235 | 226 common timer_delete sys_timer_delete | ||
236 | 227 common clock_settime sys_clock_settime | ||
237 | 228 common clock_gettime sys_clock_gettime | ||
238 | 229 common clock_getres sys_clock_getres | ||
239 | 230 common clock_nanosleep sys_clock_nanosleep | ||
240 | 231 common exit_group sys_exit_group | ||
241 | 232 common epoll_wait sys_epoll_wait | ||
242 | 233 common epoll_ctl sys_epoll_ctl | ||
243 | 234 common tgkill sys_tgkill | ||
244 | 235 common utimes sys_utimes | ||
245 | 236 64 vserver | ||
246 | 237 common mbind sys_mbind | ||
247 | 238 common set_mempolicy sys_set_mempolicy | ||
248 | 239 common get_mempolicy sys_get_mempolicy | ||
249 | 240 common mq_open sys_mq_open | ||
250 | 241 common mq_unlink sys_mq_unlink | ||
251 | 242 common mq_timedsend sys_mq_timedsend | ||
252 | 243 common mq_timedreceive sys_mq_timedreceive | ||
253 | 244 64 mq_notify sys_mq_notify | ||
254 | 245 common mq_getsetattr sys_mq_getsetattr | ||
255 | 246 64 kexec_load sys_kexec_load | ||
256 | 247 64 waitid sys_waitid | ||
257 | 248 common add_key sys_add_key | ||
258 | 249 common request_key sys_request_key | ||
259 | 250 common keyctl sys_keyctl | ||
260 | 251 common ioprio_set sys_ioprio_set | ||
261 | 252 common ioprio_get sys_ioprio_get | ||
262 | 253 common inotify_init sys_inotify_init | ||
263 | 254 common inotify_add_watch sys_inotify_add_watch | ||
264 | 255 common inotify_rm_watch sys_inotify_rm_watch | ||
265 | 256 common migrate_pages sys_migrate_pages | ||
266 | 257 common openat sys_openat | ||
267 | 258 common mkdirat sys_mkdirat | ||
268 | 259 common mknodat sys_mknodat | ||
269 | 260 common fchownat sys_fchownat | ||
270 | 261 common futimesat sys_futimesat | ||
271 | 262 common newfstatat sys_newfstatat | ||
272 | 263 common unlinkat sys_unlinkat | ||
273 | 264 common renameat sys_renameat | ||
274 | 265 common linkat sys_linkat | ||
275 | 266 common symlinkat sys_symlinkat | ||
276 | 267 common readlinkat sys_readlinkat | ||
277 | 268 common fchmodat sys_fchmodat | ||
278 | 269 common faccessat sys_faccessat | ||
279 | 270 common pselect6 sys_pselect6 | ||
280 | 271 common ppoll sys_ppoll | ||
281 | 272 common unshare sys_unshare | ||
282 | 273 64 set_robust_list sys_set_robust_list | ||
283 | 274 64 get_robust_list sys_get_robust_list | ||
284 | 275 common splice sys_splice | ||
285 | 276 common tee sys_tee | ||
286 | 277 common sync_file_range sys_sync_file_range | ||
287 | 278 64 vmsplice sys_vmsplice | ||
288 | 279 64 move_pages sys_move_pages | ||
289 | 280 common utimensat sys_utimensat | ||
290 | 281 common epoll_pwait sys_epoll_pwait | ||
291 | 282 common signalfd sys_signalfd | ||
292 | 283 common timerfd_create sys_timerfd_create | ||
293 | 284 common eventfd sys_eventfd | ||
294 | 285 common fallocate sys_fallocate | ||
295 | 286 common timerfd_settime sys_timerfd_settime | ||
296 | 287 common timerfd_gettime sys_timerfd_gettime | ||
297 | 288 common accept4 sys_accept4 | ||
298 | 289 common signalfd4 sys_signalfd4 | ||
299 | 290 common eventfd2 sys_eventfd2 | ||
300 | 291 common epoll_create1 sys_epoll_create1 | ||
301 | 292 common dup3 sys_dup3 | ||
302 | 293 common pipe2 sys_pipe2 | ||
303 | 294 common inotify_init1 sys_inotify_init1 | ||
304 | 295 64 preadv sys_preadv | ||
305 | 296 64 pwritev sys_pwritev | ||
306 | 297 64 rt_tgsigqueueinfo sys_rt_tgsigqueueinfo | ||
307 | 298 common perf_event_open sys_perf_event_open | ||
308 | 299 64 recvmmsg sys_recvmmsg | ||
309 | 300 common fanotify_init sys_fanotify_init | ||
310 | 301 common fanotify_mark sys_fanotify_mark | ||
311 | 302 common prlimit64 sys_prlimit64 | ||
312 | 303 common name_to_handle_at sys_name_to_handle_at | ||
313 | 304 common open_by_handle_at sys_open_by_handle_at | ||
314 | 305 common clock_adjtime sys_clock_adjtime | ||
315 | 306 common syncfs sys_syncfs | ||
316 | 307 64 sendmmsg sys_sendmmsg | ||
317 | 308 common setns sys_setns | ||
318 | 309 common getcpu sys_getcpu | ||
319 | 310 64 process_vm_readv sys_process_vm_readv | ||
320 | 311 64 process_vm_writev sys_process_vm_writev | ||
321 | 312 common kcmp sys_kcmp | ||
322 | 313 common finit_module sys_finit_module | ||
323 | 314 common sched_setattr sys_sched_setattr | ||
324 | 315 common sched_getattr sys_sched_getattr | ||
325 | 316 common renameat2 sys_renameat2 | ||
326 | 317 common seccomp sys_seccomp | ||
327 | 318 common getrandom sys_getrandom | ||
328 | 319 common memfd_create sys_memfd_create | ||
329 | 320 common kexec_file_load sys_kexec_file_load | ||
330 | 321 common bpf sys_bpf | ||
331 | 322 64 execveat sys_execveat/ptregs | ||
332 | 323 common userfaultfd sys_userfaultfd | ||
333 | 324 common membarrier sys_membarrier | ||
334 | 325 common mlock2 sys_mlock2 | ||
335 | 326 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 | # | ||
341 | 512 x32 rt_sigaction compat_sys_rt_sigaction | ||
342 | 513 x32 rt_sigreturn sys32_x32_rt_sigreturn | ||
343 | 514 x32 ioctl compat_sys_ioctl | ||
344 | 515 x32 readv compat_sys_readv | ||
345 | 516 x32 writev compat_sys_writev | ||
346 | 517 x32 recvfrom compat_sys_recvfrom | ||
347 | 518 x32 sendmsg compat_sys_sendmsg | ||
348 | 519 x32 recvmsg compat_sys_recvmsg | ||
349 | 520 x32 execve compat_sys_execve/ptregs | ||
350 | 521 x32 ptrace compat_sys_ptrace | ||
351 | 522 x32 rt_sigpending compat_sys_rt_sigpending | ||
352 | 523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait | ||
353 | 524 x32 rt_sigqueueinfo compat_sys_rt_sigqueueinfo | ||
354 | 525 x32 sigaltstack compat_sys_sigaltstack | ||
355 | 526 x32 timer_create compat_sys_timer_create | ||
356 | 527 x32 mq_notify compat_sys_mq_notify | ||
357 | 528 x32 kexec_load compat_sys_kexec_load | ||
358 | 529 x32 waitid compat_sys_waitid | ||
359 | 530 x32 set_robust_list compat_sys_set_robust_list | ||
360 | 531 x32 get_robust_list compat_sys_get_robust_list | ||
361 | 532 x32 vmsplice compat_sys_vmsplice | ||
362 | 533 x32 move_pages compat_sys_move_pages | ||
363 | 534 x32 preadv compat_sys_preadv64 | ||
364 | 535 x32 pwritev compat_sys_pwritev64 | ||
365 | 536 x32 rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo | ||
366 | 537 x32 recvmmsg compat_sys_recvmmsg | ||
367 | 538 x32 sendmmsg compat_sys_sendmmsg | ||
368 | 539 x32 process_vm_readv compat_sys_process_vm_readv | ||
369 | 540 x32 process_vm_writev compat_sys_process_vm_writev | ||
370 | 541 x32 setsockopt compat_sys_setsockopt | ||
371 | 542 x32 getsockopt compat_sys_getsockopt | ||
372 | 543 x32 io_setup compat_sys_io_setup | ||
373 | 544 x32 io_submit compat_sys_io_submit | ||
374 | 545 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 | |||
3 | in="$1" | ||
4 | arch="$2" | ||
5 | |||
6 | syscall_macro() { | ||
7 | nr="$1" | ||
8 | name="$2" | ||
9 | |||
10 | echo " [$nr] = \"$name\"," | ||
11 | } | ||
12 | |||
13 | emit() { | ||
14 | nr="$1" | ||
15 | entry="$2" | ||
16 | |||
17 | syscall_macro "$nr" "$entry" | ||
18 | } | ||
19 | |||
20 | echo "static const char *syscalltbl_${arch}[] = {" | ||
21 | |||
22 | sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX) | ||
23 | grep '^[0-9]' "$in" | sort -n > $sorted_table | ||
24 | |||
25 | max_nr=0 | ||
26 | while 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 | ||
33 | done < $sorted_table | ||
34 | |||
35 | rm -f $sorted_table | ||
36 | |||
37 | echo "};" | ||
38 | |||
39 | echo "#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 | ||
116 | struct 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 | ||
116 | struct tp_field { | 167 | struct 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 | |||
1076 | static struct syscall_fmt { | 1132 | static 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 | ||
1472 | static const size_t trace__entry_str_size = 2048; | 1541 | static const size_t trace__entry_str_size = 2048; |
1473 | 1542 | ||
1474 | struct 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 | |||
1527 | static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) | 1543 | static 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) { |
2148 | signed_print: | 2168 | signed_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 | |||
27 | ifeq ($(ARCH),x86) | 27 | ifeq ($(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 |
273 | endif # NO_LIBELF | 279 | endif # 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 | |||
22 | static 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 @@ | |||
1 | static 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 | |||
13 | static 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 | |||
4 | static 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 | |||
38 | libperf-y += map.o | 38 | libperf-y += map.o |
39 | libperf-y += pstack.o | 39 | libperf-y += pstack.o |
40 | libperf-y += session.o | 40 | libperf-y += session.o |
41 | libperf-$(CONFIG_AUDIT) += syscalltbl.o | ||
41 | libperf-y += ordered-events.o | 42 | libperf-y += ordered-events.o |
42 | libperf-y += comm.o | 43 | libperf-y += comm.o |
43 | libperf-y += thread.o | 44 | libperf-y += thread.o |
@@ -147,6 +148,10 @@ CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ET | |||
147 | CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" | 148 | CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" |
148 | CFLAGS_parse-events.o += -Wno-redundant-decls | 149 | CFLAGS_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 | ||
1085 | int 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> | ||
26 | const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID; | ||
27 | static const char **syscalltbl_native = syscalltbl_x86_64; | ||
28 | #endif | ||
29 | |||
30 | struct syscall { | ||
31 | int id; | ||
32 | const char *name; | ||
33 | }; | ||
34 | |||
35 | static 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 | |||
43 | static 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 | |||
50 | static 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 | |||
76 | struct 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 | |||
88 | void syscalltbl__delete(struct syscalltbl *tbl) | ||
89 | { | ||
90 | zfree(&tbl->syscalls.entries); | ||
91 | free(tbl); | ||
92 | } | ||
93 | |||
94 | const 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 | |||
99 | int 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 | |||
112 | struct 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 | |||
120 | void syscalltbl__delete(struct syscalltbl *tbl) | ||
121 | { | ||
122 | free(tbl); | ||
123 | } | ||
124 | |||
125 | const char *syscalltbl__name(const struct syscalltbl *tbl, int id) | ||
126 | { | ||
127 | return audit_syscall_to_name(id, tbl->audit_machine); | ||
128 | } | ||
129 | |||
130 | int 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 | |||
4 | struct syscalltbl { | ||
5 | union { | ||
6 | int audit_machine; | ||
7 | struct { | ||
8 | int nr_entries; | ||
9 | void *entries; | ||
10 | } syscalls; | ||
11 | }; | ||
12 | }; | ||
13 | |||
14 | struct syscalltbl *syscalltbl__new(void); | ||
15 | void syscalltbl__delete(struct syscalltbl *tbl); | ||
16 | |||
17 | const char *syscalltbl__name(const struct syscalltbl *tbl, int id); | ||
18 | int 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 | ||
13 | struct thread_stack; | 16 | struct 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 | ||
37 | struct machine; | 43 | struct 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 | ||
36 | extern int | 37 | extern int |
37 | UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, | 38 | UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, |
@@ -580,43 +581,33 @@ static unw_accessors_t accessors = { | |||
580 | 581 | ||
581 | int unwind__prepare_access(struct thread *thread) | 582 | int 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 | ||
600 | void unwind__flush_access(struct thread *thread) | 597 | void 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 | ||
611 | void unwind__finish_access(struct thread *thread) | 605 | void 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 | ||
622 | static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | 613 | static 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); | |||
254 | char *ltrim(char *s); | 254 | char *ltrim(char *s); |
255 | char *rtrim(char *s); | 255 | char *rtrim(char *s); |
256 | 256 | ||
257 | static inline char *trim(char *s) | ||
258 | { | ||
259 | return ltrim(rtrim(s)); | ||
260 | } | ||
261 | |||
257 | void dump_stack(void); | 262 | void dump_stack(void); |
258 | void sighandler_dump_stack(int sig); | 263 | void sighandler_dump_stack(int sig); |
259 | 264 | ||