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