Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Set build-id using build-id header on new mmap records

MMAP records that occur after the build-id header is parsed do not have
their build-id set even if the filename matches an entry from the
header. Set the build-id on these dsos as long as the MMAP record
doesn't have its own build-id set.

This fixes an issue with off target analysis where the local version of
a dso is loaded rather than one from ~/.debug via a build-id.

Reported-by: Denis Nikitin <denik@chromium.org>
Signed-off-by: James Clark <james.clark@arm.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: coresight@lists.linaro.org
Link: https://lore.kernel.org/r/20220304090956.2048712-2-james.clark@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

James Clark and committed by
Arnaldo Carvalho de Melo
f693dac4 7177a479

+19 -3
+1
tools/perf/util/dso.h
··· 167 167 enum dso_load_errno load_errno; 168 168 u8 adjust_symbols:1; 169 169 u8 has_build_id:1; 170 + u8 header_build_id:1; 170 171 u8 has_srcline:1; 171 172 u8 hit:1; 172 173 u8 annotate_warned:1;
+1
tools/perf/util/header.c
··· 2200 2200 2201 2201 build_id__init(&bid, bev->data, size); 2202 2202 dso__set_build_id(dso, &bid); 2203 + dso->header_build_id = 1; 2203 2204 2204 2205 if (dso_space != DSO_SPACE__USER) { 2205 2206 struct kmod_path m = { .name = NULL, };
+17 -3
tools/perf/util/map.c
··· 127 127 128 128 if (map != NULL) { 129 129 char newfilename[PATH_MAX]; 130 - struct dso *dso; 130 + struct dso *dso, *header_bid_dso; 131 131 int anon, no_dso, vdso, android; 132 132 133 133 android = is_android_lib(filename); ··· 183 183 } 184 184 dso->nsinfo = nsi; 185 185 186 - if (build_id__is_defined(bid)) 186 + if (build_id__is_defined(bid)) { 187 187 dso__set_build_id(dso, bid); 188 - 188 + } else { 189 + /* 190 + * If the mmap event had no build ID, search for an existing dso from the 191 + * build ID header by name. Otherwise only the dso loaded at the time of 192 + * reading the header will have the build ID set and all future mmaps will 193 + * have it missing. 194 + */ 195 + down_read(&machine->dsos.lock); 196 + header_bid_dso = __dsos__find(&machine->dsos, filename, false); 197 + up_read(&machine->dsos.lock); 198 + if (header_bid_dso && header_bid_dso->header_build_id) { 199 + dso__set_build_id(dso, &header_bid_dso->bid); 200 + dso->header_build_id = 1; 201 + } 202 + } 189 203 dso__put(dso); 190 204 } 191 205 return map;