]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/addr2line.c
readelf/objdump: Handle DWARF info with mixed types of range section.
[thirdparty/binutils-gdb.git] / binutils / addr2line.c
CommitLineData
252b5132 1/* addr2line.c -- convert addresses to line number and function name
d87bef3a 2 Copyright (C) 1997-2023 Free Software Foundation, Inc.
c8c5888e 3 Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>
252b5132
RH
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
32866df7 9 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
32866df7
NC
19 Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
252b5132 22
c8c5888e 23/* Derived from objdump.c and nm.c by Ulrich.Lauther@mchp.siemens.de
252b5132 24
f462a9ea 25 Usage:
252b5132
RH
26 addr2line [options] addr addr ...
27 or
f462a9ea 28 addr2line [options]
252b5132
RH
29
30 both forms write results to stdout, the second form reads addresses
31 to be converted from stdin. */
32
3db64b00 33#include "sysdep.h"
252b5132
RH
34#include "bfd.h"
35#include "getopt.h"
36#include "libiberty.h"
37#include "demangle.h"
38#include "bucomm.h"
877c169d 39#include "elf-bfd.h"
fd3c5367 40#include "safe-ctype.h"
252b5132 41
015dc7e1
AM
42static bool unwind_inlines; /* -i, unwind inlined functions. */
43static bool with_addresses; /* -a, show addresses. */
44static bool with_functions; /* -f, show function names. */
45static bool do_demangle; /* -C, demangle names. */
46static bool pretty_print; /* -p, print on one line. */
47static bool base_names; /* -s, strip directory names. */
252b5132 48
af03af8f
NC
49/* Flags passed to the name demangler. */
50static int demangle_flags = DMGL_PARAMS | DMGL_ANSI;
51
252b5132
RH
52static int naddr; /* Number of addresses to process. */
53static char **addr; /* Hex addresses to process. */
54
fd3c5367 55static long symcount;
252b5132
RH
56static asymbol **syms; /* Symbol table. */
57
58static struct option long_options[] =
59{
be6f6493 60 {"addresses", no_argument, NULL, 'a'},
252b5132 61 {"basenames", no_argument, NULL, 's'},
28c309a2 62 {"demangle", optional_argument, NULL, 'C'},
252b5132
RH
63 {"exe", required_argument, NULL, 'e'},
64 {"functions", no_argument, NULL, 'f'},
0c552dc1 65 {"inlines", no_argument, NULL, 'i'},
68cdf72f 66 {"pretty-print", no_argument, NULL, 'p'},
af03af8f
NC
67 {"recurse-limit", no_argument, NULL, 'R'},
68 {"recursion-limit", no_argument, NULL, 'R'},
69 {"no-recurse-limit", no_argument, NULL, 'r'},
70 {"no-recursion-limit", no_argument, NULL, 'r'},
c5f8c388 71 {"section", required_argument, NULL, 'j'},
252b5132
RH
72 {"target", required_argument, NULL, 'b'},
73 {"help", no_argument, NULL, 'H'},
74 {"version", no_argument, NULL, 'V'},
75 {0, no_argument, 0, 0}
76};
77
2da42df6
AJ
78static void usage (FILE *, int);
79static void slurp_symtab (bfd *);
80static void find_address_in_section (bfd *, asection *, void *);
c5f8c388
EB
81static void find_offset_in_section (bfd *, asection *);
82static void translate_addresses (bfd *, asection *);
252b5132
RH
83\f
84/* Print a usage message to STREAM and exit with STATUS. */
85
86static void
2da42df6 87usage (FILE *stream, int status)
252b5132 88{
8b53311e
NC
89 fprintf (stream, _("Usage: %s [option(s)] [addr(s)]\n"), program_name);
90 fprintf (stream, _(" Convert addresses into line number/file name pairs.\n"));
91 fprintf (stream, _(" If no addresses are specified on the command line, they will be read from stdin\n"));
92 fprintf (stream, _(" The options are:\n\
07012eee 93 @<file> Read options from <file>\n\
be6f6493 94 -a --addresses Show addresses\n\
8b53311e
NC
95 -b --target=<bfdname> Set the binary file format\n\
96 -e --exe=<executable> Set the input file name (default is a.out)\n\
c5f8c388
EB
97 -i --inlines Unwind inlined functions\n\
98 -j --section=<name> Read section-relative offsets instead of addresses\n\
68cdf72f 99 -p --pretty-print Make the output easier to read for humans\n\
8b53311e
NC
100 -s --basenames Strip directory names\n\
101 -f --functions Show function names\n\
102 -C --demangle[=style] Demangle function names\n\
af03af8f
NC
103 -R --recurse-limit Enable a limit on recursion whilst demangling. [Default]\n\
104 -r --no-recurse-limit Disable a limit on recursion whilst demangling\n\
8b53311e
NC
105 -h --help Display this information\n\
106 -v --version Display the program's version\n\
107\n"));
108
252b5132 109 list_supported_targets (program_name, stream);
92f01d61 110 if (REPORT_BUGS_TO[0] && status == 0)
8ad3436c 111 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
112 exit (status);
113}
114\f
115/* Read in the symbol table. */
116
117static void
2da42df6 118slurp_symtab (bfd *abfd)
252b5132 119{
d5e7ea07 120 long storage;
015dc7e1 121 bool dynamic = false;
252b5132
RH
122
123 if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
124 return;
125
d5e7ea07
AM
126 storage = bfd_get_symtab_upper_bound (abfd);
127 if (storage == 0)
128 {
129 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
015dc7e1 130 dynamic = true;
d5e7ea07
AM
131 }
132 if (storage < 0)
5db0367e
AM
133 {
134 bfd_nonfatal (bfd_get_filename (abfd));
135 return;
136 }
252b5132 137
d5e7ea07
AM
138 syms = (asymbol **) xmalloc (storage);
139 if (dynamic)
140 symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
141 else
142 symcount = bfd_canonicalize_symtab (abfd, syms);
252b5132 143 if (symcount < 0)
5db0367e 144 bfd_nonfatal (bfd_get_filename (abfd));
0d0fb1ba
NC
145
146 /* If there are no symbols left after canonicalization and
147 we have not tried the dynamic symbols then give them a go. */
148 if (symcount == 0
149 && ! dynamic
150 && (storage = bfd_get_dynamic_symtab_upper_bound (abfd)) > 0)
151 {
152 free (syms);
153 syms = xmalloc (storage);
154 symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
155 }
877a8638
NC
156
157 /* PR 17512: file: 2a1d3b5b.
158 Do not pretend that we have some symbols when we don't. */
159 if (symcount <= 0)
160 {
161 free (syms);
162 syms = NULL;
163 }
252b5132
RH
164}
165\f
166/* These global variables are used to pass information between
167 translate_addresses and find_address_in_section. */
168
169static bfd_vma pc;
170static const char *filename;
171static const char *functionname;
172static unsigned int line;
9b8d1a36 173static unsigned int discriminator;
015dc7e1 174static bool found;
252b5132
RH
175
176/* Look for an address in a section. This is called via
177 bfd_map_over_sections. */
178
179static void
2da42df6
AJ
180find_address_in_section (bfd *abfd, asection *section,
181 void *data ATTRIBUTE_UNUSED)
252b5132
RH
182{
183 bfd_vma vma;
184 bfd_size_type size;
185
186 if (found)
187 return;
188
fd361982 189 if ((bfd_section_flags (section) & SEC_ALLOC) == 0)
252b5132
RH
190 return;
191
fd361982 192 vma = bfd_section_vma (section);
252b5132
RH
193 if (pc < vma)
194 return;
195
fd361982 196 size = bfd_section_size (section);
252b5132
RH
197 if (pc >= vma + size)
198 return;
199
9b8d1a36
CC
200 found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc - vma,
201 &filename, &functionname,
202 &line, &discriminator);
252b5132
RH
203}
204
c5f8c388
EB
205/* Look for an offset in a section. This is directly called. */
206
207static void
208find_offset_in_section (bfd *abfd, asection *section)
209{
210 bfd_size_type size;
211
212 if (found)
213 return;
214
fd361982 215 if ((bfd_section_flags (section) & SEC_ALLOC) == 0)
c5f8c388
EB
216 return;
217
fd361982 218 size = bfd_section_size (section);
c5f8c388
EB
219 if (pc >= size)
220 return;
221
9b8d1a36
CC
222 found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc,
223 &filename, &functionname,
224 &line, &discriminator);
c5f8c388
EB
225}
226
fd3c5367
AK
227/* Lookup a symbol with offset in symbol table. */
228
229static bfd_vma
230lookup_symbol (bfd *abfd, char *sym, size_t offset)
231{
232 long i;
233
234 for (i = 0; i < symcount; i++)
235 {
236 if (!strcmp (syms[i]->name, sym))
237 return syms[i]->value + offset + bfd_asymbol_section (syms[i])->vma;
238 }
239 /* Try again mangled */
240 for (i = 0; i < symcount; i++)
241 {
242 char *d = bfd_demangle (abfd, syms[i]->name, demangle_flags);
243 bool match = d && !strcmp (d, sym);
244 free (d);
245
246 if (match)
247 return syms[i]->value + offset + bfd_asymbol_section (syms[i])->vma;
248 }
249 return 0;
250}
251
252/* Split an symbol+offset expression. adr is modified. */
253
254static bool
255is_symbol (char *adr, char **symp, size_t *offset)
256{
257 char *end;
258
259 while (ISSPACE (*adr))
260 adr++;
261 if (ISDIGIT (*adr) || *adr == 0)
262 return false;
263 /* Could be either symbol or hex number. Check if it has +. */
264 if (TOUPPER(*adr) >= 'A' && TOUPPER(*adr) <= 'F' && !strchr (adr, '+'))
265 return false;
266
267 *symp = adr;
268 while (*adr && !ISSPACE (*adr) && *adr != '+')
269 adr++;
270 end = adr;
271 while (ISSPACE (*adr))
272 adr++;
273 *offset = 0;
274 if (*adr == '+')
275 {
276 adr++;
277 *offset = strtoul(adr, NULL, 0);
278 }
279 *end = 0;
280 return true;
281}
282
283/* Read hexadecimal or symbolic with offset addresses from stdin, translate into
252b5132
RH
284 file_name:line_number and optionally function name. */
285
286static void
c5f8c388 287translate_addresses (bfd *abfd, asection *section)
252b5132
RH
288{
289 int read_stdin = (naddr == 0);
fd3c5367
AK
290 char *adr;
291 char addr_hex[100];
292 char *symp;
293 size_t offset;
252b5132
RH
294
295 for (;;)
296 {
297 if (read_stdin)
298 {
252b5132
RH
299 if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
300 break;
fd3c5367 301 adr = addr_hex;
252b5132
RH
302 }
303 else
304 {
305 if (naddr <= 0)
306 break;
307 --naddr;
fd3c5367 308 adr = *addr++;
252b5132
RH
309 }
310
fd3c5367
AK
311 if (is_symbol (adr, &symp, &offset))
312 pc = lookup_symbol (abfd, symp, offset);
313 else
314 pc = bfd_scan_vma (adr, NULL, 16);
670b0bad
AM
315 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
316 {
317 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
318 bfd_vma sign = (bfd_vma) 1 << (bed->s->arch_size - 1);
319
320 pc &= (sign << 1) - 1;
321 if (bed->sign_extend_vma)
322 pc = (pc ^ sign) - sign;
323 }
877c169d 324
be6f6493
TG
325 if (with_addresses)
326 {
327 printf ("0x");
328 bfd_printf_vma (abfd, pc);
68cdf72f
TG
329
330 if (pretty_print)
331 printf (": ");
332 else
333 printf ("\n");
be6f6493
TG
334 }
335
015dc7e1 336 found = false;
c5f8c388
EB
337 if (section)
338 find_offset_in_section (abfd, section);
339 else
340 bfd_map_over_sections (abfd, find_address_in_section, NULL);
252b5132
RH
341
342 if (! found)
343 {
344 if (with_functions)
a477bfd1
NC
345 {
346 if (pretty_print)
347 printf ("?? ");
348 else
349 printf ("??\n");
350 }
252b5132
RH
351 printf ("??:0\n");
352 }
353 else
354 {
68cdf72f
TG
355 while (1)
356 {
357 if (with_functions)
358 {
359 const char *name;
360 char *alloc = NULL;
361
362 name = functionname;
363 if (name == NULL || *name == '\0')
364 name = "??";
365 else if (do_demangle)
366 {
af03af8f 367 alloc = bfd_demangle (abfd, name, demangle_flags);
68cdf72f
TG
368 if (alloc != NULL)
369 name = alloc;
370 }
371
372 printf ("%s", name);
373 if (pretty_print)
9cf03b7e
NC
374 /* Note for translators: This printf is used to join the
375 function name just printed above to the line number/
376 file name pair that is about to be printed below. Eg:
377
378 foo at 123:bar.c */
68cdf72f
TG
379 printf (_(" at "));
380 else
381 printf ("\n");
382
9db70fc3 383 free (alloc);
68cdf72f
TG
384 }
385
386 if (base_names && filename != NULL)
387 {
388 char *h;
389
390 h = strrchr (filename, '/');
391 if (h != NULL)
392 filename = h + 1;
393 }
394
670b0bad
AM
395 printf ("%s:", filename ? filename : "??");
396 if (line != 0)
9b8d1a36
CC
397 {
398 if (discriminator != 0)
399 printf ("%u (discriminator %u)\n", line, discriminator);
400 else
401 printf ("%u\n", line);
402 }
670b0bad
AM
403 else
404 printf ("?\n");
68cdf72f 405 if (!unwind_inlines)
015dc7e1 406 found = false;
68cdf72f 407 else
9cf03b7e
NC
408 found = bfd_find_inliner_info (abfd, &filename, &functionname,
409 &line);
68cdf72f
TG
410 if (! found)
411 break;
412 if (pretty_print)
9cf03b7e
NC
413 /* Note for translators: This printf is used to join the
414 line number/file name pair that has just been printed with
415 the line number/file name pair that is going to be printed
416 by the next iteration of the while loop. Eg:
417
418 123:bar.c (inlined by) 456:main.c */
68cdf72f
TG
419 printf (_(" (inlined by) "));
420 }
252b5132
RH
421 }
422
423 /* fflush() is essential for using this command as a server
424 child process that reads addresses from a pipe and responds
425 with line number information, processing one address at a
426 time. */
427 fflush (stdout);
428 }
429}
430
d68c385b 431/* Process a file. Returns an exit value for main(). */
252b5132 432
d68c385b 433static int
c5f8c388
EB
434process_file (const char *file_name, const char *section_name,
435 const char *target)
252b5132
RH
436{
437 bfd *abfd;
c5f8c388 438 asection *section;
252b5132
RH
439 char **matching;
440
f24ddbdd 441 if (get_file_size (file_name) < 1)
d68c385b 442 return 1;
f24ddbdd 443
47badb7b 444 abfd = bfd_openr (file_name, target);
252b5132 445 if (abfd == NULL)
47badb7b 446 bfd_fatal (file_name);
252b5132 447
4a114e3e
L
448 /* Decompress sections. */
449 abfd->flags |= BFD_DECOMPRESS;
450
252b5132 451 if (bfd_check_format (abfd, bfd_archive))
5db0367e
AM
452 {
453 non_fatal (_("%s: cannot get addresses from archive"), file_name);
a2276a6d 454 bfd_close (abfd);
5db0367e
AM
455 return 1;
456 }
252b5132
RH
457
458 if (! bfd_check_format_matches (abfd, bfd_object, &matching))
459 {
460 bfd_nonfatal (bfd_get_filename (abfd));
461 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
370426d0 462 list_matching_formats (matching);
a2276a6d 463 bfd_close (abfd);
5db0367e 464 return 1;
252b5132
RH
465 }
466
c5f8c388
EB
467 if (section_name != NULL)
468 {
469 section = bfd_get_section_by_name (abfd, section_name);
470 if (section == NULL)
5db0367e
AM
471 {
472 non_fatal (_("%s: cannot find section %s"), file_name, section_name);
a2276a6d 473 bfd_close (abfd);
5db0367e
AM
474 return 1;
475 }
c5f8c388
EB
476 }
477 else
478 section = NULL;
479
252b5132
RH
480 slurp_symtab (abfd);
481
c5f8c388 482 translate_addresses (abfd, section);
252b5132 483
9db70fc3
AM
484 free (syms);
485 syms = NULL;
252b5132
RH
486
487 bfd_close (abfd);
d68c385b
NC
488
489 return 0;
252b5132
RH
490}
491\f
492int
2da42df6 493main (int argc, char **argv)
252b5132 494{
47badb7b 495 const char *file_name;
c5f8c388 496 const char *section_name;
252b5132
RH
497 char *target;
498 int c;
499
87b9f255 500#ifdef HAVE_LC_MESSAGES
252b5132 501 setlocale (LC_MESSAGES, "");
3882b010 502#endif
3882b010 503 setlocale (LC_CTYPE, "");
252b5132
RH
504 bindtextdomain (PACKAGE, LOCALEDIR);
505 textdomain (PACKAGE);
506
507 program_name = *argv;
508 xmalloc_set_program_name (program_name);
86eafac0 509 bfd_set_error_program_name (program_name);
252b5132 510
869b9d07
MM
511 expandargv (&argc, &argv);
512
bf2dd8d7
AM
513 if (bfd_init () != BFD_INIT_MAGIC)
514 fatal (_("fatal error: libbfd ABI mismatch"));
252b5132
RH
515 set_default_bfd_target ();
516
47badb7b 517 file_name = NULL;
c5f8c388 518 section_name = NULL;
252b5132 519 target = NULL;
af03af8f 520 while ((c = getopt_long (argc, argv, "ab:Ce:rRsfHhij:pVv", long_options, (int *) 0))
252b5132
RH
521 != EOF)
522 {
523 switch (c)
524 {
525 case 0:
8b53311e 526 break; /* We've been given a long option. */
be6f6493 527 case 'a':
015dc7e1 528 with_addresses = true;
be6f6493 529 break;
252b5132
RH
530 case 'b':
531 target = optarg;
532 break;
533 case 'C':
015dc7e1 534 do_demangle = true;
28c309a2
NC
535 if (optarg != NULL)
536 {
537 enum demangling_styles style;
f462a9ea 538
28c309a2 539 style = cplus_demangle_name_to_style (optarg);
f462a9ea 540 if (style == unknown_demangling)
28c309a2
NC
541 fatal (_("unknown demangling style `%s'"),
542 optarg);
f462a9ea 543
28c309a2 544 cplus_demangle_set_style (style);
f462a9ea 545 }
252b5132 546 break;
af03af8f
NC
547 case 'r':
548 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
549 break;
550 case 'R':
551 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
552 break;
252b5132 553 case 'e':
47badb7b 554 file_name = optarg;
252b5132
RH
555 break;
556 case 's':
015dc7e1 557 base_names = true;
252b5132
RH
558 break;
559 case 'f':
015dc7e1 560 with_functions = true;
252b5132 561 break;
68cdf72f 562 case 'p':
015dc7e1 563 pretty_print = true;
68cdf72f 564 break;
8b53311e 565 case 'v':
252b5132
RH
566 case 'V':
567 print_version ("addr2line");
568 break;
8b53311e 569 case 'h':
252b5132
RH
570 case 'H':
571 usage (stdout, 0);
572 break;
0c552dc1 573 case 'i':
015dc7e1 574 unwind_inlines = true;
0c552dc1 575 break;
c5f8c388
EB
576 case 'j':
577 section_name = optarg;
578 break;
252b5132
RH
579 default:
580 usage (stderr, 1);
581 break;
582 }
583 }
584
47badb7b
NC
585 if (file_name == NULL)
586 file_name = "a.out";
252b5132
RH
587
588 addr = argv + optind;
589 naddr = argc - optind;
590
d68c385b 591 return process_file (file_name, section_name, target);
252b5132 592}