1 // SPDX-License-Identifier: GPL-2.0
3 #include "util/debug.h"
5 #include "util/event.h" // struct perf_sample
7 #include "util/symbol.h"
9 #include "util/evsel.h"
10 #include "util/machine.h"
11 #include "util/thread.h"
12 #include "tests/hists_common.h"
13 #include <linux/kernel.h>
14 #include <linux/perf_event.h>
20 { FAKE_PID_PERF1
, "perf" },
21 { FAKE_PID_PERF2
, "perf" },
22 { FAKE_PID_BASH
, "bash" },
29 } fake_mmap_info
[] = {
30 { FAKE_PID_PERF1
, FAKE_MAP_PERF
, "perf" },
31 { FAKE_PID_PERF1
, FAKE_MAP_LIBC
, "libc" },
32 { FAKE_PID_PERF1
, FAKE_MAP_KERNEL
, "[kernel]" },
33 { FAKE_PID_PERF2
, FAKE_MAP_PERF
, "perf" },
34 { FAKE_PID_PERF2
, FAKE_MAP_LIBC
, "libc" },
35 { FAKE_PID_PERF2
, FAKE_MAP_KERNEL
, "[kernel]" },
36 { FAKE_PID_BASH
, FAKE_MAP_BASH
, "bash" },
37 { FAKE_PID_BASH
, FAKE_MAP_LIBC
, "libc" },
38 { FAKE_PID_BASH
, FAKE_MAP_KERNEL
, "[kernel]" },
47 static struct fake_sym perf_syms
[] = {
48 { FAKE_SYM_OFFSET1
, FAKE_SYM_LENGTH
, "main" },
49 { FAKE_SYM_OFFSET2
, FAKE_SYM_LENGTH
, "run_command" },
50 { FAKE_SYM_OFFSET3
, FAKE_SYM_LENGTH
, "cmd_record" },
53 static struct fake_sym bash_syms
[] = {
54 { FAKE_SYM_OFFSET1
, FAKE_SYM_LENGTH
, "main" },
55 { FAKE_SYM_OFFSET2
, FAKE_SYM_LENGTH
, "xmalloc" },
56 { FAKE_SYM_OFFSET3
, FAKE_SYM_LENGTH
, "xfree" },
59 static struct fake_sym libc_syms
[] = {
60 { 700, 100, "malloc" },
62 { 900, 100, "realloc" },
63 { FAKE_SYM_OFFSET1
, FAKE_SYM_LENGTH
, "malloc" },
64 { FAKE_SYM_OFFSET2
, FAKE_SYM_LENGTH
, "free" },
65 { FAKE_SYM_OFFSET3
, FAKE_SYM_LENGTH
, "realloc" },
68 static struct fake_sym kernel_syms
[] = {
69 { FAKE_SYM_OFFSET1
, FAKE_SYM_LENGTH
, "schedule" },
70 { FAKE_SYM_OFFSET2
, FAKE_SYM_LENGTH
, "page_fault" },
71 { FAKE_SYM_OFFSET3
, FAKE_SYM_LENGTH
, "sys_perf_event_open" },
76 struct fake_sym
*syms
;
79 { "perf", perf_syms
, ARRAY_SIZE(perf_syms
) },
80 { "bash", bash_syms
, ARRAY_SIZE(bash_syms
) },
81 { "libc", libc_syms
, ARRAY_SIZE(libc_syms
) },
82 { "[kernel]", kernel_syms
, ARRAY_SIZE(kernel_syms
) },
85 struct machine
*setup_fake_machine(struct machines
*machines
)
87 struct machine
*machine
= machines__find(machines
, HOST_KERNEL_ID
);
90 if (machine
== NULL
) {
91 pr_debug("Not enough memory for machine setup\n");
95 for (i
= 0; i
< ARRAY_SIZE(fake_threads
); i
++) {
96 struct thread
*thread
;
98 thread
= machine__findnew_thread(machine
, fake_threads
[i
].pid
,
103 thread__set_comm(thread
, fake_threads
[i
].comm
, 0);
107 for (i
= 0; i
< ARRAY_SIZE(fake_mmap_info
); i
++) {
108 struct perf_sample sample
= {
109 .cpumode
= PERF_RECORD_MISC_USER
,
111 union perf_event fake_mmap_event
= {
113 .pid
= fake_mmap_info
[i
].pid
,
114 .tid
= fake_mmap_info
[i
].pid
,
115 .start
= fake_mmap_info
[i
].start
,
116 .len
= FAKE_MAP_LENGTH
,
121 strcpy(fake_mmap_event
.mmap
.filename
,
122 fake_mmap_info
[i
].filename
);
124 machine__process_mmap_event(machine
, &fake_mmap_event
, &sample
);
127 for (i
= 0; i
< ARRAY_SIZE(fake_symbols
); i
++) {
131 dso
= machine__findnew_dso(machine
, fake_symbols
[i
].dso_name
);
135 /* emulate dso__load() */
136 dso__set_loaded(dso
);
138 for (k
= 0; k
< fake_symbols
[i
].nr_syms
; k
++) {
140 struct fake_sym
*fsym
= &fake_symbols
[i
].syms
[k
];
142 sym
= symbol__new(fsym
->start
, fsym
->length
,
143 STB_GLOBAL
, STT_FUNC
, fsym
->name
);
149 symbols__insert(&dso
->symbols
, sym
);
158 pr_debug("Not enough memory for machine setup\n");
159 machine__delete_threads(machine
);
163 void print_hists_in(struct hists
*hists
)
166 struct rb_root_cached
*root
;
167 struct rb_node
*node
;
169 if (hists__has(hists
, need_collapse
))
170 root
= &hists
->entries_collapsed
;
172 root
= hists
->entries_in
;
174 pr_info("----- %s --------\n", __func__
);
175 node
= rb_first_cached(root
);
177 struct hist_entry
*he
;
179 he
= rb_entry(node
, struct hist_entry
, rb_node_in
);
182 pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64
"\n",
183 i
, thread__comm_str(he
->thread
),
184 he
->ms
.map
->dso
->short_name
,
185 he
->ms
.sym
->name
, he
->stat
.period
);
189 node
= rb_next(node
);
193 void print_hists_out(struct hists
*hists
)
196 struct rb_root_cached
*root
;
197 struct rb_node
*node
;
199 root
= &hists
->entries
;
201 pr_info("----- %s --------\n", __func__
);
202 node
= rb_first_cached(root
);
204 struct hist_entry
*he
;
206 he
= rb_entry(node
, struct hist_entry
, rb_node
);
209 pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64
"/%"PRIu64
"\n",
210 i
, thread__comm_str(he
->thread
), he
->thread
->tid
,
211 he
->ms
.map
->dso
->short_name
,
212 he
->ms
.sym
->name
, he
->stat
.period
,
213 he
->stat_acc
? he
->stat_acc
->period
: 0);
217 node
= rb_next(node
);