Skip to content

Commit bb83c99

Browse files
committed
Merge tag 'perf-tools-fixes-for-v5.19-2022-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
Pull perf tools fixes from Arnaldo Carvalho de Melo: - Fix addresses for bss symbols, describing variables used in resolving data access in tools such as 'perf c2c' and 'perf mem'. - Skip symbols if SHF_ALLOC flag is not set, a technique used for listing deprecated symbols, its addresses are zeros, so not useful. - Remove undefined behavior from bpf_perf_object__next() when dealing with an empty bpf_objects_list list. - Make a ARM CoreSight disasm script work with both python2 and python3. - Sync x86's cpufeatures header with with the kernel sources. * tag 'perf-tools-fixes-for-v5.19-2022-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: perf bpf: Remove undefined behavior from bpf_perf_object__next() perf symbol: Skip symbols if SHF_ALLOC flag is not set perf symbol: Correct address for bss symbols perf scripts python: Let script to be python2 compliant tools headers cpufeatures: Sync with the kernel sources
2 parents 4b20426 + 9a24180 commit bb83c99

File tree

4 files changed

+78
-31
lines changed

4 files changed

+78
-31
lines changed

tools/arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@
302302
#define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */
303303
#define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */
304304
#define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */
305+
#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */
305306

306307
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
307308
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */

tools/perf/scripts/python/arm-cs-trace-disasm.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def get_optional(perf_dict, field):
6161

6262
def get_offset(perf_dict, field):
6363
if field in perf_dict:
64-
return f"+0x{perf_dict[field]:x}"
64+
return "+%#x" % perf_dict[field]
6565
return ""
6666

6767
def get_dso_file_path(dso_name, dso_build_id):
@@ -76,7 +76,7 @@ def get_dso_file_path(dso_name, dso_build_id):
7676
else:
7777
append = "/elf"
7878

79-
dso_path = f"{os.environ['PERF_BUILDID_DIR']}/{dso_name}/{dso_build_id}{append}"
79+
dso_path = os.environ['PERF_BUILDID_DIR'] + "/" + dso_name + "/" + dso_build_id + append;
8080
# Replace duplicate slash chars to single slash char
8181
dso_path = dso_path.replace('//', '/', 1)
8282
return dso_path
@@ -94,8 +94,8 @@ def read_disam(dso_fname, dso_start, start_addr, stop_addr):
9494
start_addr = start_addr - dso_start;
9595
stop_addr = stop_addr - dso_start;
9696
disasm = [ options.objdump_name, "-d", "-z",
97-
f"--start-address=0x{start_addr:x}",
98-
f"--stop-address=0x{stop_addr:x}" ]
97+
"--start-address="+format(start_addr,"#x"),
98+
"--stop-address="+format(stop_addr,"#x") ]
9999
disasm += [ dso_fname ]
100100
disasm_output = check_output(disasm).decode('utf-8').split('\n')
101101
disasm_cache[addr_range] = disasm_output
@@ -109,12 +109,14 @@ def print_disam(dso_fname, dso_start, start_addr, stop_addr):
109109
m = disasm_re.search(line)
110110
if m is None:
111111
continue
112-
print(f"\t{line}")
112+
print("\t" + line)
113113

114114
def print_sample(sample):
115-
print(f"Sample = {{ cpu: {sample['cpu']:04} addr: 0x{sample['addr']:016x} " \
116-
f"phys_addr: 0x{sample['phys_addr']:016x} ip: 0x{sample['ip']:016x} " \
117-
f"pid: {sample['pid']} tid: {sample['tid']} period: {sample['period']} time: {sample['time']} }}")
115+
print("Sample = { cpu: %04d addr: 0x%016x phys_addr: 0x%016x ip: 0x%016x " \
116+
"pid: %d tid: %d period: %d time: %d }" % \
117+
(sample['cpu'], sample['addr'], sample['phys_addr'], \
118+
sample['ip'], sample['pid'], sample['tid'], \
119+
sample['period'], sample['time']))
118120

119121
def trace_begin():
120122
print('ARM CoreSight Trace Data Assembler Dump')
@@ -131,7 +133,7 @@ def common_start_str(comm, sample):
131133
cpu = sample["cpu"]
132134
pid = sample["pid"]
133135
tid = sample["tid"]
134-
return f"{comm:>16} {pid:>5}/{tid:<5} [{cpu:04}] {sec:9}.{ns:09} "
136+
return "%16s %5u/%-5u [%04u] %9u.%09u " % (comm, pid, tid, cpu, sec, ns)
135137

136138
# This code is copied from intel-pt-events.py for printing source code
137139
# line and symbols.
@@ -171,7 +173,7 @@ def print_srccode(comm, param_dict, sample, symbol, dso):
171173
glb_line_number = line_number
172174
glb_source_file_name = source_file_name
173175

174-
print(f"{start_str}{src_str}")
176+
print(start_str, src_str)
175177

176178
def process_event(param_dict):
177179
global cache_size
@@ -188,7 +190,7 @@ def process_event(param_dict):
188190
symbol = get_optional(param_dict, "symbol")
189191

190192
if (options.verbose == True):
191-
print(f"Event type: {name}")
193+
print("Event type: %s" % name)
192194
print_sample(sample)
193195

194196
# If cannot find dso so cannot dump assembler, bail out
@@ -197,7 +199,7 @@ def process_event(param_dict):
197199

198200
# Validate dso start and end addresses
199201
if ((dso_start == '[unknown]') or (dso_end == '[unknown]')):
200-
print(f"Failed to find valid dso map for dso {dso}")
202+
print("Failed to find valid dso map for dso %s" % dso)
201203
return
202204

203205
if (name[0:12] == "instructions"):
@@ -244,15 +246,15 @@ def process_event(param_dict):
244246

245247
# Handle CS_ETM_TRACE_ON packet if start_addr=0 and stop_addr=4
246248
if (start_addr == 0 and stop_addr == 4):
247-
print(f"CPU{cpu}: CS_ETM_TRACE_ON packet is inserted")
249+
print("CPU%d: CS_ETM_TRACE_ON packet is inserted" % cpu)
248250
return
249251

250252
if (start_addr < int(dso_start) or start_addr > int(dso_end)):
251-
print(f"Start address 0x{start_addr:x} is out of range [ 0x{dso_start:x} .. 0x{dso_end:x} ] for dso {dso}")
253+
print("Start address 0x%x is out of range [ 0x%x .. 0x%x ] for dso %s" % (start_addr, int(dso_start), int(dso_end), dso))
252254
return
253255

254256
if (stop_addr < int(dso_start) or stop_addr > int(dso_end)):
255-
print(f"Stop address 0x{stop_addr:x} is out of range [ 0x{dso_start:x} .. 0x{dso_end:x} ] for dso {dso}")
257+
print("Stop address 0x%x is out of range [ 0x%x .. 0x%x ] for dso %s" % (stop_addr, int(dso_start), int(dso_end), dso))
256258
return
257259

258260
if (options.objdump_name != None):
@@ -267,6 +269,6 @@ def process_event(param_dict):
267269
if path.exists(dso_fname):
268270
print_disam(dso_fname, dso_vm_start, start_addr, stop_addr)
269271
else:
270-
print(f"Failed to find dso {dso} for address range [ 0x{start_addr:x} .. 0x{stop_addr:x} ]")
272+
print("Failed to find dso %s for address range [ 0x%x .. 0x%x ]" % (dso, start_addr, stop_addr))
271273

272274
print_srccode(comm, param_dict, sample, symbol, dso)

tools/perf/util/bpf-loader.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,16 @@ static struct hashmap *bpf_map_hash;
6363
static struct bpf_perf_object *
6464
bpf_perf_object__next(struct bpf_perf_object *prev)
6565
{
66-
struct bpf_perf_object *next;
67-
68-
if (!prev)
69-
next = list_first_entry(&bpf_objects_list,
70-
struct bpf_perf_object,
71-
list);
72-
else
73-
next = list_next_entry(prev, list);
66+
if (!prev) {
67+
if (list_empty(&bpf_objects_list))
68+
return NULL;
7469

75-
/* Empty list is noticed here so don't need checking on entry. */
76-
if (&next->list == &bpf_objects_list)
70+
return list_first_entry(&bpf_objects_list, struct bpf_perf_object, list);
71+
}
72+
if (list_is_last(&prev->list, &bpf_objects_list))
7773
return NULL;
7874

79-
return next;
75+
return list_next_entry(prev, list);
8076
}
8177

8278
#define bpf_perf_object__for_each(perf_obj, tmp) \

tools/perf/util/symbol-elf.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,33 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
233233
return NULL;
234234
}
235235

236+
static int elf_read_program_header(Elf *elf, u64 vaddr, GElf_Phdr *phdr)
237+
{
238+
size_t i, phdrnum;
239+
u64 sz;
240+
241+
if (elf_getphdrnum(elf, &phdrnum))
242+
return -1;
243+
244+
for (i = 0; i < phdrnum; i++) {
245+
if (gelf_getphdr(elf, i, phdr) == NULL)
246+
return -1;
247+
248+
if (phdr->p_type != PT_LOAD)
249+
continue;
250+
251+
sz = max(phdr->p_memsz, phdr->p_filesz);
252+
if (!sz)
253+
continue;
254+
255+
if (vaddr >= phdr->p_vaddr && (vaddr < phdr->p_vaddr + sz))
256+
return 0;
257+
}
258+
259+
/* Not found any valid program header */
260+
return -1;
261+
}
262+
236263
static bool want_demangle(bool is_kernel_sym)
237264
{
238265
return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
@@ -1209,6 +1236,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
12091236
sym.st_value);
12101237
used_opd = true;
12111238
}
1239+
12121240
/*
12131241
* When loading symbols in a data mapping, ABS symbols (which
12141242
* has a value of SHN_ABS in its st_shndx) failed at
@@ -1227,6 +1255,17 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
12271255

12281256
gelf_getshdr(sec, &shdr);
12291257

1258+
/*
1259+
* If the attribute bit SHF_ALLOC is not set, the section
1260+
* doesn't occupy memory during process execution.
1261+
* E.g. ".gnu.warning.*" section is used by linker to generate
1262+
* warnings when calling deprecated functions, the symbols in
1263+
* the section aren't loaded to memory during process execution,
1264+
* so skip them.
1265+
*/
1266+
if (!(shdr.sh_flags & SHF_ALLOC))
1267+
continue;
1268+
12301269
secstrs = secstrs_sym;
12311270

12321271
/*
@@ -1262,11 +1301,20 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
12621301
goto out_elf_end;
12631302
} else if ((used_opd && runtime_ss->adjust_symbols) ||
12641303
(!used_opd && syms_ss->adjust_symbols)) {
1304+
GElf_Phdr phdr;
1305+
1306+
if (elf_read_program_header(syms_ss->elf,
1307+
(u64)sym.st_value, &phdr)) {
1308+
pr_warning("%s: failed to find program header for "
1309+
"symbol: %s st_value: %#" PRIx64 "\n",
1310+
__func__, elf_name, (u64)sym.st_value);
1311+
continue;
1312+
}
12651313
pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1266-
"sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1267-
(u64)sym.st_value, (u64)shdr.sh_addr,
1268-
(u64)shdr.sh_offset);
1269-
sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1314+
"p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n",
1315+
__func__, (u64)sym.st_value, (u64)phdr.p_vaddr,
1316+
(u64)phdr.p_offset);
1317+
sym.st_value -= phdr.p_vaddr - phdr.p_offset;
12701318
}
12711319

12721320
demangled = demangle_sym(dso, kmodule, elf_name);

0 commit comments

Comments
 (0)