Skip to content

Commit 76c30e1

Browse files
author
Jakub Brnak
committed
perf disasm: Introduce symbol__disassemble_objdump()
JIRA: https://issues.redhat.com/browse/RHEL-83785 upstream ======== commit 4c1d8f0 Author: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Mon Nov 11 12:17:32 2024 -0300 description =========== With the first disassemble method in perf, the parsing of objdump output, just like we have for llvm and capstone. This paves the way to allow the user to specify what disassemblers are preferred and to also to at some point allow building without the objdump method. Acked-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Steinar H. Gunderson <sesse@google.com> Link: https://lore.kernel.org/r/20241111151734.1018476-2-acme@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Jakub Brnak <jbrnak@redhat.com>
1 parent 818e414 commit 76c30e1

File tree

1 file changed

+88
-80
lines changed

1 file changed

+88
-80
lines changed

tools/perf/util/disasm.c

Lines changed: 88 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,17 +2053,14 @@ static char *expand_tabs(char *line, char **storage, size_t *storage_len)
20532053
return new_line;
20542054
}
20552055

2056-
int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
2056+
static int symbol__disassemble_objdump(const char *filename, struct symbol *sym,
2057+
struct annotate_args *args)
20572058
{
20582059
struct annotation_options *opts = &annotate_opts;
20592060
struct map *map = args->ms.map;
20602061
struct dso *dso = map__dso(map);
20612062
char *command;
20622063
FILE *file;
2063-
char symfs_filename[PATH_MAX];
2064-
struct kcore_extract kce;
2065-
bool delete_extract = false;
2066-
bool decomp = false;
20672064
int lineno = 0;
20682065
char *fileloc = NULL;
20692066
int nline;
@@ -2078,77 +2075,7 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
20782075
NULL,
20792076
};
20802077
struct child_process objdump_process;
2081-
int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename));
2082-
2083-
if (err)
2084-
return err;
2085-
2086-
pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
2087-
symfs_filename, sym->name, map__unmap_ip(map, sym->start),
2088-
map__unmap_ip(map, sym->end));
2089-
2090-
pr_debug("annotating [%p] %30s : [%p] %30s\n",
2091-
dso, dso__long_name(dso), sym, sym->name);
2092-
2093-
if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) {
2094-
return symbol__disassemble_bpf(sym, args);
2095-
} else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) {
2096-
return symbol__disassemble_bpf_image(sym, args);
2097-
} else if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) {
2098-
return -1;
2099-
} else if (dso__is_kcore(dso)) {
2100-
kce.kcore_filename = symfs_filename;
2101-
kce.addr = map__rip_2objdump(map, sym->start);
2102-
kce.offs = sym->start;
2103-
kce.len = sym->end - sym->start;
2104-
if (!kcore_extract__create(&kce)) {
2105-
delete_extract = true;
2106-
strlcpy(symfs_filename, kce.extract_filename,
2107-
sizeof(symfs_filename));
2108-
}
2109-
} else if (dso__needs_decompress(dso)) {
2110-
char tmp[KMOD_DECOMP_LEN];
2111-
2112-
if (dso__decompress_kmodule_path(dso, symfs_filename,
2113-
tmp, sizeof(tmp)) < 0)
2114-
return -1;
2115-
2116-
decomp = true;
2117-
strcpy(symfs_filename, tmp);
2118-
}
2119-
2120-
/*
2121-
* For powerpc data type profiling, use the dso__data_read_offset
2122-
* to read raw instruction directly and interpret the binary code
2123-
* to understand instructions and register fields. For sort keys as
2124-
* type and typeoff, disassemble to mnemonic notation is
2125-
* not required in case of powerpc.
2126-
*/
2127-
if (arch__is(args->arch, "powerpc")) {
2128-
extern const char *sort_order;
2129-
2130-
if (sort_order && !strstr(sort_order, "sym")) {
2131-
err = symbol__disassemble_raw(symfs_filename, sym, args);
2132-
if (err == 0)
2133-
goto out_remove_tmp;
2134-
#ifdef HAVE_LIBCAPSTONE_SUPPORT
2135-
err = symbol__disassemble_capstone_powerpc(symfs_filename, sym, args);
2136-
if (err == 0)
2137-
goto out_remove_tmp;
2138-
#endif
2139-
}
2140-
}
2141-
2142-
#ifdef HAVE_LIBLLVM_SUPPORT
2143-
err = symbol__disassemble_llvm(symfs_filename, sym, args);
2144-
if (err == 0)
2145-
goto out_remove_tmp;
2146-
#endif
2147-
#ifdef HAVE_LIBCAPSTONE_SUPPORT
2148-
err = symbol__disassemble_capstone(symfs_filename, sym, args);
2149-
if (err == 0)
2150-
goto out_remove_tmp;
2151-
#endif
2078+
int err;
21522079

21532080
err = asprintf(&command,
21542081
"%s %s%s --start-address=0x%016" PRIx64
@@ -2171,13 +2098,13 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
21712098

21722099
if (err < 0) {
21732100
pr_err("Failure allocating memory for the command to run\n");
2174-
goto out_remove_tmp;
2101+
return err;
21752102
}
21762103

21772104
pr_debug("Executing: %s\n", command);
21782105

21792106
objdump_argv[2] = command;
2180-
objdump_argv[4] = symfs_filename;
2107+
objdump_argv[4] = filename;
21812108

21822109
/* Create a pipe to read from for stdout */
21832110
memset(&objdump_process, 0, sizeof(objdump_process));
@@ -2215,8 +2142,8 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
22152142
break;
22162143

22172144
/* Skip lines containing "filename:" */
2218-
match = strstr(line, symfs_filename);
2219-
if (match && match[strlen(symfs_filename)] == ':')
2145+
match = strstr(line, filename);
2146+
if (match && match[strlen(filename)] == ':')
22202147
continue;
22212148

22222149
expanded_line = strim(line);
@@ -2261,6 +2188,87 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
22612188

22622189
out_free_command:
22632190
free(command);
2191+
return err;
2192+
}
2193+
2194+
int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
2195+
{
2196+
struct map *map = args->ms.map;
2197+
struct dso *dso = map__dso(map);
2198+
char symfs_filename[PATH_MAX];
2199+
bool delete_extract = false;
2200+
struct kcore_extract kce;
2201+
bool decomp = false;
2202+
int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename));
2203+
2204+
if (err)
2205+
return err;
2206+
2207+
pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
2208+
symfs_filename, sym->name, map__unmap_ip(map, sym->start),
2209+
map__unmap_ip(map, sym->end));
2210+
2211+
pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso__long_name(dso), sym, sym->name);
2212+
2213+
if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) {
2214+
return symbol__disassemble_bpf(sym, args);
2215+
} else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) {
2216+
return symbol__disassemble_bpf_image(sym, args);
2217+
} else if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) {
2218+
return -1;
2219+
} else if (dso__is_kcore(dso)) {
2220+
kce.addr = map__rip_2objdump(map, sym->start);
2221+
kce.kcore_filename = symfs_filename;
2222+
kce.len = sym->end - sym->start;
2223+
kce.offs = sym->start;
2224+
2225+
if (!kcore_extract__create(&kce)) {
2226+
delete_extract = true;
2227+
strlcpy(symfs_filename, kce.extract_filename, sizeof(symfs_filename));
2228+
}
2229+
} else if (dso__needs_decompress(dso)) {
2230+
char tmp[KMOD_DECOMP_LEN];
2231+
2232+
if (dso__decompress_kmodule_path(dso, symfs_filename, tmp, sizeof(tmp)) < 0)
2233+
return -1;
2234+
2235+
decomp = true;
2236+
strcpy(symfs_filename, tmp);
2237+
}
2238+
2239+
/*
2240+
* For powerpc data type profiling, use the dso__data_read_offset to
2241+
* read raw instruction directly and interpret the binary code to
2242+
* understand instructions and register fields. For sort keys as type
2243+
* and typeoff, disassemble to mnemonic notation is not required in
2244+
* case of powerpc.
2245+
*/
2246+
if (arch__is(args->arch, "powerpc")) {
2247+
extern const char *sort_order;
2248+
2249+
if (sort_order && !strstr(sort_order, "sym")) {
2250+
err = symbol__disassemble_raw(symfs_filename, sym, args);
2251+
if (err == 0)
2252+
goto out_remove_tmp;
2253+
#ifdef HAVE_LIBCAPSTONE_SUPPORT
2254+
err = symbol__disassemble_capstone_powerpc(symfs_filename, sym, args);
2255+
if (err == 0)
2256+
goto out_remove_tmp;
2257+
#endif
2258+
}
2259+
}
2260+
2261+
#ifdef HAVE_LIBLLVM_SUPPORT
2262+
err = symbol__disassemble_llvm(symfs_filename, sym, args);
2263+
if (err == 0)
2264+
goto out_remove_tmp;
2265+
#endif
2266+
#ifdef HAVE_LIBCAPSTONE_SUPPORT
2267+
err = symbol__disassemble_capstone(symfs_filename, sym, args);
2268+
if (err == 0)
2269+
goto out_remove_tmp;
2270+
#endif
2271+
err = symbol__disassemble_objdump(symfs_filename, sym, args);
22642272

22652273
out_remove_tmp:
22662274
if (decomp)

0 commit comments

Comments
 (0)