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.c173
1 files changed, 59 insertions, 114 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index c324bdf8baba..cb086cbe6b10 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -27,6 +27,8 @@ static void dsos__add(struct dso *dso);
27static struct dso *dsos__find(const char *name); 27static struct dso *dsos__find(const char *name);
28static struct map *map__new2(u64 start, struct dso *dso); 28static struct map *map__new2(u64 start, struct dso *dso);
29static void kernel_maps__insert(struct map *map); 29static void kernel_maps__insert(struct map *map);
30static int dso__load_kernel_sym(struct dso *self, struct map *map,
31 symbol_filter_t filter);
30unsigned int symbol__priv_size; 32unsigned int symbol__priv_size;
31 33
32static struct rb_root kernel_maps; 34static struct rb_root kernel_maps;
@@ -69,12 +71,6 @@ static void kernel_maps__fixup_end(void)
69 curr = rb_entry(nd, struct map, rb_node); 71 curr = rb_entry(nd, struct map, rb_node);
70 prev->end = curr->start - 1; 72 prev->end = curr->start - 1;
71 } 73 }
72
73 nd = rb_last(&curr->dso->syms);
74 if (nd) {
75 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
76 curr->end = sym->end;
77 }
78} 74}
79 75
80static struct symbol *symbol__new(u64 start, u64 len, const char *name) 76static struct symbol *symbol__new(u64 start, u64 len, const char *name)
@@ -324,7 +320,7 @@ out_failure:
324 * kernel range is broken in several maps, named [kernel].N, as we don't have 320 * kernel range is broken in several maps, named [kernel].N, as we don't have
325 * the original ELF section names vmlinux have. 321 * the original ELF section names vmlinux have.
326 */ 322 */
327static int kernel_maps__split_kallsyms(symbol_filter_t filter, int use_modules) 323static int kernel_maps__split_kallsyms(symbol_filter_t filter)
328{ 324{
329 struct map *map = kernel_map; 325 struct map *map = kernel_map;
330 struct symbol *pos; 326 struct symbol *pos;
@@ -340,9 +336,6 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter, int use_modules)
340 336
341 module = strchr(pos->name, '\t'); 337 module = strchr(pos->name, '\t');
342 if (module) { 338 if (module) {
343 if (!use_modules)
344 goto delete_symbol;
345
346 *module++ = '\0'; 339 *module++ = '\0';
347 340
348 if (strcmp(map->dso->name, module)) { 341 if (strcmp(map->dso->name, module)) {
@@ -382,7 +375,6 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter, int use_modules)
382 } 375 }
383 376
384 if (filter && filter(map, pos)) { 377 if (filter && filter(map, pos)) {
385delete_symbol:
386 rb_erase(&pos->rb_node, &kernel_map->dso->syms); 378 rb_erase(&pos->rb_node, &kernel_map->dso->syms);
387 symbol__delete(pos); 379 symbol__delete(pos);
388 } else { 380 } else {
@@ -398,17 +390,18 @@ delete_symbol:
398} 390}
399 391
400 392
401static int kernel_maps__load_kallsyms(symbol_filter_t filter, int use_modules) 393static int kernel_maps__load_kallsyms(symbol_filter_t filter)
402{ 394{
403 if (kernel_maps__load_all_kallsyms()) 395 if (kernel_maps__load_all_kallsyms())
404 return -1; 396 return -1;
405 397
406 dso__fixup_sym_end(kernel_map->dso); 398 dso__fixup_sym_end(kernel_map->dso);
399 kernel_map->dso->origin = DSO__ORIG_KERNEL;
407 400
408 return kernel_maps__split_kallsyms(filter, use_modules); 401 return kernel_maps__split_kallsyms(filter);
409} 402}
410 403
411static size_t kernel_maps__fprintf(FILE *fp) 404size_t kernel_maps__fprintf(FILE *fp)
412{ 405{
413 size_t printed = fprintf(fp, "Kernel maps:\n"); 406 size_t printed = fprintf(fp, "Kernel maps:\n");
414 struct rb_node *nd; 407 struct rb_node *nd;
@@ -1042,13 +1035,17 @@ char dso__symtab_origin(const struct dso *self)
1042int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) 1035int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1043{ 1036{
1044 int size = PATH_MAX; 1037 int size = PATH_MAX;
1045 char *name = malloc(size); 1038 char *name;
1046 u8 build_id[BUILD_ID_SIZE]; 1039 u8 build_id[BUILD_ID_SIZE];
1047 int ret = -1; 1040 int ret = -1;
1048 int fd; 1041 int fd;
1049 1042
1050 self->loaded = 1; 1043 self->loaded = 1;
1051 1044
1045 if (self->kernel)
1046 return dso__load_kernel_sym(self, map, filter);
1047
1048 name = malloc(size);
1052 if (!name) 1049 if (!name)
1053 return -1; 1050 return -1;
1054 1051
@@ -1139,7 +1136,8 @@ static void kernel_maps__insert(struct map *map)
1139 maps__insert(&kernel_maps, map); 1136 maps__insert(&kernel_maps, map);
1140} 1137}
1141 1138
1142struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp) 1139struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp,
1140 symbol_filter_t filter)
1143{ 1141{
1144 struct map *map = maps__find(&kernel_maps, ip); 1142 struct map *map = maps__find(&kernel_maps, ip);
1145 1143
@@ -1148,7 +1146,7 @@ struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp)
1148 1146
1149 if (map) { 1147 if (map) {
1150 ip = map->map_ip(map, ip); 1148 ip = map->map_ip(map, ip);
1151 return map->dso->find_symbol(map->dso, ip); 1149 return map__find_symbol(map, ip, filter);
1152 } 1150 }
1153 1151
1154 return NULL; 1152 return NULL;
@@ -1168,28 +1166,9 @@ struct map *kernel_maps__find_by_dso_name(const char *name)
1168 return NULL; 1166 return NULL;
1169} 1167}
1170 1168
1171static int dso__load_module_sym(struct dso *self, struct map *map, 1169static int dsos__set_modules_path_dir(char *dirname)
1172 symbol_filter_t filter)
1173{
1174 int err = 0, fd = open(self->long_name, O_RDONLY);
1175
1176 self->loaded = 1;
1177
1178 if (fd < 0) {
1179 pr_err("%s: cannot open %s\n", __func__, self->long_name);
1180 return err;
1181 }
1182
1183 err = dso__load_sym(self, map, self->long_name, fd, filter, 0, 1);
1184 close(fd);
1185
1186 return err;
1187}
1188
1189static int dsos__load_modules_sym_dir(char *dirname, symbol_filter_t filter)
1190{ 1170{
1191 struct dirent *dent; 1171 struct dirent *dent;
1192 int nr_symbols = 0, err;
1193 DIR *dir = opendir(dirname); 1172 DIR *dir = opendir(dirname);
1194 1173
1195 if (!dir) { 1174 if (!dir) {
@@ -1207,14 +1186,12 @@ static int dsos__load_modules_sym_dir(char *dirname, symbol_filter_t filter)
1207 1186
1208 snprintf(path, sizeof(path), "%s/%s", 1187 snprintf(path, sizeof(path), "%s/%s",
1209 dirname, dent->d_name); 1188 dirname, dent->d_name);
1210 err = dsos__load_modules_sym_dir(path, filter); 1189 if (dsos__set_modules_path_dir(path) < 0)
1211 if (err < 0)
1212 goto failure; 1190 goto failure;
1213 } else { 1191 } else {
1214 char *dot = strrchr(dent->d_name, '.'), 1192 char *dot = strrchr(dent->d_name, '.'),
1215 dso_name[PATH_MAX]; 1193 dso_name[PATH_MAX];
1216 struct map *map; 1194 struct map *map;
1217 struct rb_node *last;
1218 char *long_name; 1195 char *long_name;
1219 1196
1220 if (dot == NULL || strcmp(dot, ".ko")) 1197 if (dot == NULL || strcmp(dot, ".ko"))
@@ -1234,36 +1211,16 @@ static int dsos__load_modules_sym_dir(char *dirname, symbol_filter_t filter)
1234 if (long_name == NULL) 1211 if (long_name == NULL)
1235 goto failure; 1212 goto failure;
1236 dso__set_long_name(map->dso, long_name); 1213 dso__set_long_name(map->dso, long_name);
1237 dso__set_basename(map->dso);
1238
1239 err = dso__load_module_sym(map->dso, map, filter);
1240 if (err < 0)
1241 goto failure;
1242 last = rb_last(&map->dso->syms);
1243 if (last) {
1244 struct symbol *sym;
1245 /*
1246 * We do this here as well, even having the
1247 * symbol size found in the symtab because
1248 * misannotated ASM symbols may have the size
1249 * set to zero.
1250 */
1251 dso__fixup_sym_end(map->dso);
1252
1253 sym = rb_entry(last, struct symbol, rb_node);
1254 map->end = map->start + sym->end;
1255 }
1256 } 1214 }
1257 nr_symbols += err;
1258 } 1215 }
1259 1216
1260 return nr_symbols; 1217 return 0;
1261failure: 1218failure:
1262 closedir(dir); 1219 closedir(dir);
1263 return -1; 1220 return -1;
1264} 1221}
1265 1222
1266int dsos__load_modules_sym(symbol_filter_t filter) 1223static int dsos__set_modules_path(void)
1267{ 1224{
1268 struct utsname uts; 1225 struct utsname uts;
1269 char modules_path[PATH_MAX]; 1226 char modules_path[PATH_MAX];
@@ -1274,7 +1231,7 @@ int dsos__load_modules_sym(symbol_filter_t filter)
1274 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", 1231 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1275 uts.release); 1232 uts.release);
1276 1233
1277 return dsos__load_modules_sym_dir(modules_path, filter); 1234 return dsos__set_modules_path_dir(modules_path);
1278} 1235}
1279 1236
1280/* 1237/*
@@ -1296,7 +1253,7 @@ static struct map *map__new2(u64 start, struct dso *dso)
1296 return self; 1253 return self;
1297} 1254}
1298 1255
1299int dsos__load_modules(void) 1256static int kernel_maps__create_module_maps(void)
1300{ 1257{
1301 char *line = NULL; 1258 char *line = NULL;
1302 size_t n; 1259 size_t n;
@@ -1360,7 +1317,13 @@ int dsos__load_modules(void)
1360 free(line); 1317 free(line);
1361 fclose(file); 1318 fclose(file);
1362 1319
1363 return 0; 1320 /*
1321 * Now that we have all sorted out, just set the ->end of all
1322 * maps:
1323 */
1324 kernel_maps__fixup_end();
1325
1326 return dsos__set_modules_path();
1364 1327
1365out_delete_line: 1328out_delete_line:
1366 free(line); 1329 free(line);
@@ -1385,40 +1348,17 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
1385 return err; 1348 return err;
1386} 1349}
1387 1350
1388int dso__load_kernel_sym(struct dso *self, symbol_filter_t filter, 1351static int dso__load_kernel_sym(struct dso *self, struct map *map,
1389 int use_modules) 1352 symbol_filter_t filter)
1390{ 1353{
1391 int err; 1354 int err = dso__load_vmlinux(self, map, self->name, filter);
1392 1355
1393 kernel_map = map__new2(0, self);
1394 if (kernel_map == NULL)
1395 return -1;
1396
1397 kernel_map->map_ip = kernel_map->unmap_ip = identity__map_ip;
1398
1399 err = dso__load_vmlinux(self, kernel_map, self->name, filter);
1400 if (err <= 0) 1356 if (err <= 0)
1401 err = kernel_maps__load_kallsyms(filter, use_modules); 1357 err = kernel_maps__load_kallsyms(filter);
1402 1358
1403 if (err > 0) { 1359 if (err > 0) {
1404 struct rb_node *node = rb_first(&self->syms); 1360 map__fixup_start(map);
1405 struct symbol *sym = rb_entry(node, struct symbol, rb_node); 1361 map__fixup_end(map);
1406
1407 kernel_map->start = sym->start;
1408 node = rb_last(&self->syms);
1409 sym = rb_entry(node, struct symbol, rb_node);
1410 kernel_map->end = sym->end;
1411
1412 self->origin = DSO__ORIG_KERNEL;
1413 kernel_maps__insert(kernel_map);
1414 /*
1415 * Now that we have all sorted out, just set the ->end of all
1416 * maps:
1417 */
1418 kernel_maps__fixup_end();
1419
1420 if (verbose)
1421 kernel_maps__fprintf(stderr);
1422 } 1362 }
1423 1363
1424 return err; 1364 return err;
@@ -1479,46 +1419,51 @@ size_t dsos__fprintf_buildid(FILE *fp)
1479 return ret; 1419 return ret;
1480} 1420}
1481 1421
1482struct dso *dsos__load_kernel(void) 1422static int kernel_maps__create_kernel_map(void)
1483{ 1423{
1484 struct dso *kernel = dso__new(vmlinux_name); 1424 struct dso *kernel = dso__new(vmlinux_name);
1485 1425
1486 if (kernel == NULL) 1426 if (kernel == NULL)
1487 return NULL; 1427 return -1;
1428
1429 kernel_map = map__new2(0, kernel);
1430 if (kernel_map == NULL)
1431 goto out_delete_kernel_dso;
1432
1433 kernel_map->map_ip = kernel_map->unmap_ip = identity__map_ip;
1488 1434
1489 kernel->short_name = "[kernel]"; 1435 kernel->short_name = "[kernel]";
1436 kernel->kernel = 1;
1490 vdso = dso__new("[vdso]"); 1437 vdso = dso__new("[vdso]");
1491 if (!vdso) 1438 if (vdso == NULL)
1492 return NULL; 1439 goto out_delete_kernel_map;
1493 1440
1494 if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id, 1441 if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
1495 sizeof(kernel->build_id)) == 0) 1442 sizeof(kernel->build_id)) == 0)
1496 kernel->has_build_id = true; 1443 kernel->has_build_id = true;
1497 1444
1445 kernel_maps__insert(kernel_map);
1498 dsos__add(kernel); 1446 dsos__add(kernel);
1499 dsos__add(vdso); 1447 dsos__add(vdso);
1500 1448
1501 return kernel; 1449 return 0;
1450
1451out_delete_kernel_map:
1452 map__delete(kernel_map);
1453 kernel_map = NULL;
1454out_delete_kernel_dso:
1455 dso__delete(kernel);
1456 return -1;
1502} 1457}
1503 1458
1504int load_kernel(symbol_filter_t filter, bool use_modules) 1459int kernel_maps__init(bool use_modules)
1505{ 1460{
1506 struct dso *kernel = dsos__load_kernel(); 1461 if (kernel_maps__create_kernel_map() < 0)
1507
1508 if (kernel == NULL)
1509 return -1; 1462 return -1;
1510 1463
1511 if (use_modules) { 1464 if (use_modules && kernel_maps__create_module_maps() < 0)
1512 if (dsos__load_modules() < 0) 1465 pr_warning("Failed to load list of modules in use, "
1513 pr_warning("Failed to load list of modules in use, " 1466 "continuing...\n");
1514 "continuing...\n");
1515 else if (dsos__load_modules_sym(filter) < 0)
1516 pr_warning("Failed to read module symbols, "
1517 "continuing...\n");
1518 }
1519
1520 if (dso__load_kernel_sym(kernel, filter, use_modules) < 0)
1521 pr_warning("Failed to read kernel symbols, continuing...\n");
1522 1467
1523 return 0; 1468 return 0;
1524} 1469}