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
usage(FILE * stream,int status)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
slurp_symtab(bfd * abfd)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
find_address_in_section(bfd * abfd,asection * section,void * data ATTRIBUTE_UNUSED)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
find_offset_in_section(bfd * abfd,asection * section)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
translate_addresses(bfd * abfd,asection * section)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
process_file(const char * file_name,const char * section_name,const char * target)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
main(int argc,char ** argv)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