aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c80
1 files changed, 47 insertions, 33 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 242d2b216f46..b812ace91c60 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -26,6 +26,8 @@
26#define NT_GNU_BUILD_ID 3 26#define NT_GNU_BUILD_ID 3
27#endif 27#endif
28 28
29static bool dso__build_id_equal(const struct dso *self, u8 *build_id);
30static int elf_read_build_id(Elf *elf, void *bf, size_t size);
29static void dsos__add(struct list_head *head, struct dso *dso); 31static void dsos__add(struct list_head *head, struct dso *dso);
30static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 32static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
31static int dso__load_kernel_sym(struct dso *self, struct map *map, 33static int dso__load_kernel_sym(struct dso *self, struct map *map,
@@ -993,6 +995,17 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
993 goto out_elf_end; 995 goto out_elf_end;
994 } 996 }
995 997
998 if (self->has_build_id) {
999 u8 build_id[BUILD_ID_SIZE];
1000
1001 if (elf_read_build_id(elf, build_id,
1002 BUILD_ID_SIZE) != BUILD_ID_SIZE)
1003 goto out_elf_end;
1004
1005 if (!dso__build_id_equal(self, build_id))
1006 goto out_elf_end;
1007 }
1008
996 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL); 1009 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
997 if (sec == NULL) { 1010 if (sec == NULL) {
998 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL); 1011 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
@@ -1193,37 +1206,26 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1193 */ 1206 */
1194#define NOTE_ALIGN(n) (((n) + 3) & -4U) 1207#define NOTE_ALIGN(n) (((n) + 3) & -4U)
1195 1208
1196int filename__read_build_id(const char *filename, void *bf, size_t size) 1209static int elf_read_build_id(Elf *elf, void *bf, size_t size)
1197{ 1210{
1198 int fd, err = -1; 1211 int err = -1;
1199 GElf_Ehdr ehdr; 1212 GElf_Ehdr ehdr;
1200 GElf_Shdr shdr; 1213 GElf_Shdr shdr;
1201 Elf_Data *data; 1214 Elf_Data *data;
1202 Elf_Scn *sec; 1215 Elf_Scn *sec;
1203 Elf_Kind ek; 1216 Elf_Kind ek;
1204 void *ptr; 1217 void *ptr;
1205 Elf *elf;
1206 1218
1207 if (size < BUILD_ID_SIZE) 1219 if (size < BUILD_ID_SIZE)
1208 goto out; 1220 goto out;
1209 1221
1210 fd = open(filename, O_RDONLY);
1211 if (fd < 0)
1212 goto out;
1213
1214 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1215 if (elf == NULL) {
1216 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1217 goto out_close;
1218 }
1219
1220 ek = elf_kind(elf); 1222 ek = elf_kind(elf);
1221 if (ek != ELF_K_ELF) 1223 if (ek != ELF_K_ELF)
1222 goto out_elf_end; 1224 goto out;
1223 1225
1224 if (gelf_getehdr(elf, &ehdr) == NULL) { 1226 if (gelf_getehdr(elf, &ehdr) == NULL) {
1225 pr_err("%s: cannot get elf header.\n", __func__); 1227 pr_err("%s: cannot get elf header.\n", __func__);
1226 goto out_elf_end; 1228 goto out;
1227 } 1229 }
1228 1230
1229 sec = elf_section_by_name(elf, &ehdr, &shdr, 1231 sec = elf_section_by_name(elf, &ehdr, &shdr,
@@ -1232,12 +1234,12 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
1232 sec = elf_section_by_name(elf, &ehdr, &shdr, 1234 sec = elf_section_by_name(elf, &ehdr, &shdr,
1233 ".notes", NULL); 1235 ".notes", NULL);
1234 if (sec == NULL) 1236 if (sec == NULL)
1235 goto out_elf_end; 1237 goto out;
1236 } 1238 }
1237 1239
1238 data = elf_getdata(sec, NULL); 1240 data = elf_getdata(sec, NULL);
1239 if (data == NULL) 1241 if (data == NULL)
1240 goto out_elf_end; 1242 goto out;
1241 1243
1242 ptr = data->d_buf; 1244 ptr = data->d_buf;
1243 while (ptr < (data->d_buf + data->d_size)) { 1245 while (ptr < (data->d_buf + data->d_size)) {
@@ -1259,7 +1261,31 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
1259 } 1261 }
1260 ptr += descsz; 1262 ptr += descsz;
1261 } 1263 }
1262out_elf_end: 1264
1265out:
1266 return err;
1267}
1268
1269int filename__read_build_id(const char *filename, void *bf, size_t size)
1270{
1271 int fd, err = -1;
1272 Elf *elf;
1273
1274 if (size < BUILD_ID_SIZE)
1275 goto out;
1276
1277 fd = open(filename, O_RDONLY);
1278 if (fd < 0)
1279 goto out;
1280
1281 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1282 if (elf == NULL) {
1283 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1284 goto out_close;
1285 }
1286
1287 err = elf_read_build_id(elf, bf, size);
1288
1263 elf_end(elf); 1289 elf_end(elf);
1264out_close: 1290out_close:
1265 close(fd); 1291 close(fd);
@@ -1335,7 +1361,6 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1335{ 1361{
1336 int size = PATH_MAX; 1362 int size = PATH_MAX;
1337 char *name; 1363 char *name;
1338 u8 build_id[BUILD_ID_SIZE];
1339 int ret = -1; 1364 int ret = -1;
1340 int fd; 1365 int fd;
1341 struct machine *machine; 1366 struct machine *machine;
@@ -1382,16 +1407,14 @@ more:
1382 self->long_name); 1407 self->long_name);
1383 break; 1408 break;
1384 case DSO__ORIG_BUILDID: 1409 case DSO__ORIG_BUILDID:
1385 if (filename__read_build_id(self->long_name, build_id, 1410 if (self->has_build_id) {
1386 sizeof(build_id))) {
1387 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1411 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1388 build_id__sprintf(build_id, sizeof(build_id), 1412 build_id__sprintf(self->build_id,
1413 sizeof(self->build_id),
1389 build_id_hex); 1414 build_id_hex);
1390 snprintf(name, size, 1415 snprintf(name, size,
1391 "/usr/lib/debug/.build-id/%.2s/%s.debug", 1416 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1392 build_id_hex, build_id_hex + 2); 1417 build_id_hex, build_id_hex + 2);
1393 if (self->has_build_id)
1394 goto compare_build_id;
1395 break; 1418 break;
1396 } 1419 }
1397 self->origin++; 1420 self->origin++;
@@ -1410,15 +1433,6 @@ more:
1410 default: 1433 default:
1411 goto out; 1434 goto out;
1412 } 1435 }
1413
1414 if (self->has_build_id) {
1415 if (filename__read_build_id(name, build_id,
1416 sizeof(build_id)) < 0)
1417 goto more;
1418compare_build_id:
1419 if (!dso__build_id_equal(self, build_id))
1420 goto more;
1421 }
1422open_file: 1436open_file:
1423 fd = open(name, O_RDONLY); 1437 fd = open(name, O_RDONLY);
1424 } while (fd < 0); 1438 } while (fd < 0);