aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2017-09-04 12:22:54 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2017-09-04 12:22:54 -0400
commita6cbfa1e6d38c4b3ab0ce7e3aea4bb4e744f24b8 (patch)
tree8960e571a398b5d32e72bdb9c89ce965daa870ab /tools/perf/util/annotate.c
parentf5308d1b83eba20e69df5e0926ba7257c8dd9074 (diff)
parent08d6ac9ee5fedd82040bc878705981b67a116a3f (diff)
Merge branch 'next' into for-linus
Prepare input updates for 4.14 merge window.
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c72
1 files changed, 43 insertions, 29 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 683f8340460c..ddbd56df9187 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -239,10 +239,20 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
239 const char *s = strchr(ops->raw, '+'); 239 const char *s = strchr(ops->raw, '+');
240 const char *c = strchr(ops->raw, ','); 240 const char *c = strchr(ops->raw, ',');
241 241
242 if (c++ != NULL) 242 /*
243 * skip over possible up to 2 operands to get to address, e.g.:
244 * tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
245 */
246 if (c++ != NULL) {
243 ops->target.addr = strtoull(c, NULL, 16); 247 ops->target.addr = strtoull(c, NULL, 16);
244 else 248 if (!ops->target.addr) {
249 c = strchr(c, ',');
250 if (c++ != NULL)
251 ops->target.addr = strtoull(c, NULL, 16);
252 }
253 } else {
245 ops->target.addr = strtoull(ops->raw, NULL, 16); 254 ops->target.addr = strtoull(ops->raw, NULL, 16);
255 }
246 256
247 if (s++ != NULL) { 257 if (s++ != NULL) {
248 ops->target.offset = strtoull(s, NULL, 16); 258 ops->target.offset = strtoull(s, NULL, 16);
@@ -257,10 +267,27 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
257static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 267static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
258 struct ins_operands *ops) 268 struct ins_operands *ops)
259{ 269{
270 const char *c = strchr(ops->raw, ',');
271
260 if (!ops->target.addr || ops->target.offset < 0) 272 if (!ops->target.addr || ops->target.offset < 0)
261 return ins__raw_scnprintf(ins, bf, size, ops); 273 return ins__raw_scnprintf(ins, bf, size, ops);
262 274
263 return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset); 275 if (c != NULL) {
276 const char *c2 = strchr(c + 1, ',');
277
278 /* check for 3-op insn */
279 if (c2 != NULL)
280 c = c2;
281 c++;
282
283 /* mirror arch objdump's space-after-comma style */
284 if (*c == ' ')
285 c++;
286 }
287
288 return scnprintf(bf, size, "%-6.6s %.*s%" PRIx64,
289 ins->name, c ? c - ops->raw : 0, ops->raw,
290 ops->target.offset);
264} 291}
265 292
266static struct ins_ops jump_ops = { 293static struct ins_ops jump_ops = {
@@ -1294,6 +1321,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
1294 char linkname[PATH_MAX]; 1321 char linkname[PATH_MAX];
1295 char *build_id_filename; 1322 char *build_id_filename;
1296 char *build_id_path = NULL; 1323 char *build_id_path = NULL;
1324 char *pos;
1297 1325
1298 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 1326 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
1299 !dso__is_kcore(dso)) 1327 !dso__is_kcore(dso))
@@ -1313,7 +1341,14 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
1313 if (!build_id_path) 1341 if (!build_id_path)
1314 return -1; 1342 return -1;
1315 1343
1316 dirname(build_id_path); 1344 /*
1345 * old style build-id cache has name of XX/XXXXXXX.. while
1346 * new style has XX/XXXXXXX../{elf,kallsyms,vdso}.
1347 * extract the build-id part of dirname in the new style only.
1348 */
1349 pos = strrchr(build_id_path, '/');
1350 if (pos && strlen(pos) < SBUILD_ID_SIZE - 2)
1351 dirname(build_id_path);
1317 1352
1318 if (dso__is_kcore(dso) || 1353 if (dso__is_kcore(dso) ||
1319 readlink(build_id_path, linkname, sizeof(linkname)) < 0 || 1354 readlink(build_id_path, linkname, sizeof(linkname)) < 0 ||
@@ -1396,31 +1431,10 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
1396 sizeof(symfs_filename)); 1431 sizeof(symfs_filename));
1397 } 1432 }
1398 } else if (dso__needs_decompress(dso)) { 1433 } else if (dso__needs_decompress(dso)) {
1399 char tmp[PATH_MAX]; 1434 char tmp[KMOD_DECOMP_LEN];
1400 struct kmod_path m;
1401 int fd;
1402 bool ret;
1403
1404 if (kmod_path__parse_ext(&m, symfs_filename))
1405 goto out;
1406
1407 snprintf(tmp, PATH_MAX, "/tmp/perf-kmod-XXXXXX");
1408
1409 fd = mkstemp(tmp);
1410 if (fd < 0) {
1411 free(m.ext);
1412 goto out;
1413 }
1414
1415 ret = decompress_to_file(m.ext, symfs_filename, fd);
1416
1417 if (ret)
1418 pr_err("Cannot decompress %s %s\n", m.ext, symfs_filename);
1419
1420 free(m.ext);
1421 close(fd);
1422 1435
1423 if (!ret) 1436 if (dso__decompress_kmodule_path(dso, symfs_filename,
1437 tmp, sizeof(tmp)) < 0)
1424 goto out; 1438 goto out;
1425 1439
1426 strcpy(symfs_filename, tmp); 1440 strcpy(symfs_filename, tmp);
@@ -1429,7 +1443,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
1429 snprintf(command, sizeof(command), 1443 snprintf(command, sizeof(command),
1430 "%s %s%s --start-address=0x%016" PRIx64 1444 "%s %s%s --start-address=0x%016" PRIx64
1431 " --stop-address=0x%016" PRIx64 1445 " --stop-address=0x%016" PRIx64
1432 " -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand", 1446 " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
1433 objdump_path ? objdump_path : "objdump", 1447 objdump_path ? objdump_path : "objdump",
1434 disassembler_style ? "-M " : "", 1448 disassembler_style ? "-M " : "",
1435 disassembler_style ? disassembler_style : "", 1449 disassembler_style ? disassembler_style : "",