1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include <linux/kernel.h> 6 7 #include "util/dso.h" 8 #include "util/util.h" 9 #include "util/debug.h" 10 #include "util/callchain.h" 11 12 #include "symbol.h" 13 14 bool srcline_full_filename; 15 16 static const char *dso__name(struct dso *dso) 17 { 18 const char *dso_name; 19 20 if (dso->symsrc_filename) 21 dso_name = dso->symsrc_filename; 22 else 23 dso_name = dso->long_name; 24 25 if (dso_name[0] == '[') 26 return NULL; 27 28 if (!strncmp(dso_name, "/tmp/perf-", 10)) 29 return NULL; 30 31 return dso_name; 32 } 33 34 static int inline_list__append(char *filename, char *funcname, int line_nr, 35 struct inline_node *node, struct dso *dso) 36 { 37 struct inline_list *ilist; 38 char *demangled; 39 40 ilist = zalloc(sizeof(*ilist)); 41 if (ilist == NULL) 42 return -1; 43 44 ilist->filename = filename; 45 ilist->line_nr = line_nr; 46 47 if (dso != NULL) { 48 demangled = dso__demangle_sym(dso, 0, funcname); 49 if (demangled == NULL) { 50 ilist->funcname = funcname; 51 } else { 52 ilist->funcname = demangled; 53 free(funcname); 54 } 55 } 56 57 list_add_tail(&ilist->list, &node->val); 58 59 return 0; 60 } 61 62 #ifdef HAVE_LIBBFD_SUPPORT 63 64 /* 65 * Implement addr2line using libbfd. 66 */ 67 #define PACKAGE "perf" 68 #include <bfd.h> 69 70 struct a2l_data { 71 const char *input; 72 u64 addr; 73 74 bool found; 75 const char *filename; 76 const char *funcname; 77 unsigned line; 78 79 bfd *abfd; 80 asymbol **syms; 81 }; 82 83 static int bfd_error(const char *string) 84 { 85 const char *errmsg; 86 87 errmsg = bfd_errmsg(bfd_get_error()); 88 fflush(stdout); 89 90 if (string) 91 pr_debug("%s: %s\n", string, errmsg); 92 else 93 pr_debug("%s\n", errmsg); 94 95 return -1; 96 } 97 98 static int slurp_symtab(bfd *abfd, struct a2l_data *a2l) 99 { 100 long storage; 101 long symcount; 102 asymbol **syms; 103 bfd_boolean dynamic = FALSE; 104 105 if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) 106 return bfd_error(bfd_get_filename(abfd)); 107 108 storage = bfd_get_symtab_upper_bound(abfd); 109 if (storage == 0L) { 110 storage = bfd_get_dynamic_symtab_upper_bound(abfd); 111 dynamic = TRUE; 112 } 113 if (storage < 0L) 114 return bfd_error(bfd_get_filename(abfd)); 115 116 syms = malloc(storage); 117 if (dynamic) 118 symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); 119 else 120 symcount = bfd_canonicalize_symtab(abfd, syms); 121 122 if (symcount < 0) { 123 free(syms); 124 return bfd_error(bfd_get_filename(abfd)); 125 } 126 127 a2l->syms = syms; 128 return 0; 129 } 130 131 static void find_address_in_section(bfd *abfd, asection *section, void *data) 132 { 133 bfd_vma pc, vma; 134 bfd_size_type size; 135 struct a2l_data *a2l = data; 136 137 if (a2l->found) 138 return; 139 140 if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) 141 return; 142 143 pc = a2l->addr; 144 vma = bfd_get_section_vma(abfd, section); 145 size = bfd_get_section_size(section); 146 147 if (pc < vma || pc >= vma + size) 148 return; 149 150 a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, 151 &a2l->filename, &a2l->funcname, 152 &a2l->line); 153 } 154 155 static struct a2l_data *addr2line_init(const char *path) 156 { 157 bfd *abfd; 158 struct a2l_data *a2l = NULL; 159 160 abfd = bfd_openr(path, NULL); 161 if (abfd == NULL) 162 return NULL; 163 164 if (!bfd_check_format(abfd, bfd_object)) 165 goto out; 166 167 a2l = zalloc(sizeof(*a2l)); 168 if (a2l == NULL) 169 goto out; 170 171 a2l->abfd = abfd; 172 a2l->input = strdup(path); 173 if (a2l->input == NULL) 174 goto out; 175 176 if (slurp_symtab(abfd, a2l)) 177 goto out; 178 179 return a2l; 180 181 out: 182 if (a2l) { 183 zfree((char **)&a2l->input); 184 free(a2l); 185 } 186 bfd_close(abfd); 187 return NULL; 188 } 189 190 static void addr2line_cleanup(struct a2l_data *a2l) 191 { 192 if (a2l->abfd) 193 bfd_close(a2l->abfd); 194 zfree((char **)&a2l->input); 195 zfree(&a2l->syms); 196 free(a2l); 197 } 198 199 #define MAX_INLINE_NEST 1024 200 201 static void inline_list__reverse(struct inline_node *node) 202 { 203 struct inline_list *ilist, *n; 204 205 list_for_each_entry_safe_reverse(ilist, n, &node->val, list) 206 list_move_tail(&ilist->list, &node->val); 207 } 208 209 static int addr2line(const char *dso_name, u64 addr, 210 char **file, unsigned int *line, struct dso *dso, 211 bool unwind_inlines, struct inline_node *node) 212 { 213 int ret = 0; 214 struct a2l_data *a2l = dso->a2l; 215 216 if (!a2l) { 217 dso->a2l = addr2line_init(dso_name); 218 a2l = dso->a2l; 219 } 220 221 if (a2l == NULL) { 222 pr_warning("addr2line_init failed for %s\n", dso_name); 223 return 0; 224 } 225 226 a2l->addr = addr; 227 a2l->found = false; 228 229 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); 230 231 if (a2l->found && unwind_inlines) { 232 int cnt = 0; 233 234 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, 235 &a2l->funcname, &a2l->line) && 236 cnt++ < MAX_INLINE_NEST) { 237 238 if (node != NULL) { 239 if (inline_list__append(strdup(a2l->filename), 240 strdup(a2l->funcname), 241 a2l->line, node, 242 dso) != 0) 243 return 0; 244 } 245 } 246 247 if ((node != NULL) && 248 (callchain_param.order != ORDER_CALLEE)) { 249 inline_list__reverse(node); 250 } 251 } 252 253 if (a2l->found && a2l->filename) { 254 *file = strdup(a2l->filename); 255 *line = a2l->line; 256 257 if (*file) 258 ret = 1; 259 } 260 261 return ret; 262 } 263 264 void dso__free_a2l(struct dso *dso) 265 { 266 struct a2l_data *a2l = dso->a2l; 267 268 if (!a2l) 269 return; 270 271 addr2line_cleanup(a2l); 272 273 dso->a2l = NULL; 274 } 275 276 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 277 struct dso *dso) 278 { 279 char *file = NULL; 280 unsigned int line = 0; 281 struct inline_node *node; 282 283 node = zalloc(sizeof(*node)); 284 if (node == NULL) { 285 perror("not enough memory for the inline node"); 286 return NULL; 287 } 288 289 INIT_LIST_HEAD(&node->val); 290 node->addr = addr; 291 292 if (!addr2line(dso_name, addr, &file, &line, dso, TRUE, node)) 293 goto out_free_inline_node; 294 295 if (list_empty(&node->val)) 296 goto out_free_inline_node; 297 298 return node; 299 300 out_free_inline_node: 301 inline_node__delete(node); 302 return NULL; 303 } 304 305 #else /* HAVE_LIBBFD_SUPPORT */ 306 307 static int filename_split(char *filename, unsigned int *line_nr) 308 { 309 char *sep; 310 311 sep = strchr(filename, '\n'); 312 if (sep) 313 *sep = '\0'; 314 315 if (!strcmp(filename, "??:0")) 316 return 0; 317 318 sep = strchr(filename, ':'); 319 if (sep) { 320 *sep++ = '\0'; 321 *line_nr = strtoul(sep, NULL, 0); 322 return 1; 323 } 324 325 return 0; 326 } 327 328 static int addr2line(const char *dso_name, u64 addr, 329 char **file, unsigned int *line_nr, 330 struct dso *dso __maybe_unused, 331 bool unwind_inlines __maybe_unused, 332 struct inline_node *node __maybe_unused) 333 { 334 FILE *fp; 335 char cmd[PATH_MAX]; 336 char *filename = NULL; 337 size_t len; 338 int ret = 0; 339 340 scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, 341 dso_name, addr); 342 343 fp = popen(cmd, "r"); 344 if (fp == NULL) { 345 pr_warning("popen failed for %s\n", dso_name); 346 return 0; 347 } 348 349 if (getline(&filename, &len, fp) < 0 || !len) { 350 pr_warning("addr2line has no output for %s\n", dso_name); 351 goto out; 352 } 353 354 ret = filename_split(filename, line_nr); 355 if (ret != 1) { 356 free(filename); 357 goto out; 358 } 359 360 *file = filename; 361 362 out: 363 pclose(fp); 364 return ret; 365 } 366 367 void dso__free_a2l(struct dso *dso __maybe_unused) 368 { 369 } 370 371 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 372 struct dso *dso __maybe_unused) 373 { 374 FILE *fp; 375 char cmd[PATH_MAX]; 376 struct inline_node *node; 377 char *filename = NULL; 378 size_t len; 379 unsigned int line_nr = 0; 380 381 scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i %016"PRIx64, 382 dso_name, addr); 383 384 fp = popen(cmd, "r"); 385 if (fp == NULL) { 386 pr_err("popen failed for %s\n", dso_name); 387 return NULL; 388 } 389 390 node = zalloc(sizeof(*node)); 391 if (node == NULL) { 392 perror("not enough memory for the inline node"); 393 goto out; 394 } 395 396 INIT_LIST_HEAD(&node->val); 397 node->addr = addr; 398 399 while (getline(&filename, &len, fp) != -1) { 400 if (filename_split(filename, &line_nr) != 1) { 401 free(filename); 402 goto out; 403 } 404 405 if (inline_list__append(filename, NULL, line_nr, node, 406 NULL) != 0) 407 goto out; 408 409 filename = NULL; 410 } 411 412 out: 413 pclose(fp); 414 415 if (list_empty(&node->val)) { 416 inline_node__delete(node); 417 return NULL; 418 } 419 420 return node; 421 } 422 423 #endif /* HAVE_LIBBFD_SUPPORT */ 424 425 /* 426 * Number of addr2line failures (without success) before disabling it for that 427 * dso. 428 */ 429 #define A2L_FAIL_LIMIT 123 430 431 char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 432 bool show_sym, bool unwind_inlines) 433 { 434 char *file = NULL; 435 unsigned line = 0; 436 char *srcline; 437 const char *dso_name; 438 439 if (!dso->has_srcline) 440 goto out; 441 442 dso_name = dso__name(dso); 443 if (dso_name == NULL) 444 goto out; 445 446 if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines, NULL)) 447 goto out; 448 449 if (asprintf(&srcline, "%s:%u", 450 srcline_full_filename ? file : basename(file), 451 line) < 0) { 452 free(file); 453 goto out; 454 } 455 456 dso->a2l_fails = 0; 457 458 free(file); 459 return srcline; 460 461 out: 462 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 463 dso->has_srcline = 0; 464 dso__free_a2l(dso); 465 } 466 if (sym) { 467 if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", 468 addr - sym->start) < 0) 469 return SRCLINE_UNKNOWN; 470 } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0) 471 return SRCLINE_UNKNOWN; 472 return srcline; 473 } 474 475 void free_srcline(char *srcline) 476 { 477 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) 478 free(srcline); 479 } 480 481 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 482 bool show_sym) 483 { 484 return __get_srcline(dso, addr, sym, show_sym, false); 485 } 486 487 struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr) 488 { 489 const char *dso_name; 490 491 dso_name = dso__name(dso); 492 if (dso_name == NULL) 493 return NULL; 494 495 return addr2inlines(dso_name, addr, dso); 496 } 497 498 void inline_node__delete(struct inline_node *node) 499 { 500 struct inline_list *ilist, *tmp; 501 502 list_for_each_entry_safe(ilist, tmp, &node->val, list) { 503 list_del_init(&ilist->list); 504 zfree(&ilist->filename); 505 zfree(&ilist->funcname); 506 free(ilist); 507 } 508 509 free(node); 510 } 511