bfd/
[deliverable/binutils-gdb.git] / binutils / addr2line.c
CommitLineData
252b5132 1/* addr2line.c -- convert addresses to line number and function name
3f5e193b
NC
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007, 2009 Free Software Foundation, Inc.
c8c5888e 4 Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>
252b5132
RH
5
6 This file is part of GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
32866df7 10 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
32866df7
NC
20 Foundation, 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
252b5132 23
c8c5888e 24/* Derived from objdump.c and nm.c by Ulrich.Lauther@mchp.siemens.de
252b5132 25
f462a9ea 26 Usage:
252b5132
RH
27 addr2line [options] addr addr ...
28 or
f462a9ea 29 addr2line [options]
252b5132
RH
30
31 both forms write results to stdout, the second form reads addresses
32 to be converted from stdin. */
33
3db64b00 34#include "sysdep.h"
252b5132
RH
35#include "bfd.h"
36#include "getopt.h"
37#include "libiberty.h"
38#include "demangle.h"
39#include "bucomm.h"
40
0c552dc1 41static bfd_boolean unwind_inlines; /* -i, unwind inlined functions. */
be6f6493 42static bfd_boolean with_addresses; /* -a, show addresses. */
b34976b6
AM
43static bfd_boolean with_functions; /* -f, show function names. */
44static bfd_boolean do_demangle; /* -C, demangle names. */
45static bfd_boolean base_names; /* -s, strip directory names. */
252b5132
RH
46
47static int naddr; /* Number of addresses to process. */
48static char **addr; /* Hex addresses to process. */
49
50static asymbol **syms; /* Symbol table. */
51
52static struct option long_options[] =
53{
be6f6493 54 {"addresses", no_argument, NULL, 'a'},
252b5132 55 {"basenames", no_argument, NULL, 's'},
28c309a2 56 {"demangle", optional_argument, NULL, 'C'},
252b5132
RH
57 {"exe", required_argument, NULL, 'e'},
58 {"functions", no_argument, NULL, 'f'},
0c552dc1 59 {"inlines", no_argument, NULL, 'i'},
c5f8c388 60 {"section", required_argument, NULL, 'j'},
252b5132
RH
61 {"target", required_argument, NULL, 'b'},
62 {"help", no_argument, NULL, 'H'},
63 {"version", no_argument, NULL, 'V'},
64 {0, no_argument, 0, 0}
65};
66
2da42df6
AJ
67static void usage (FILE *, int);
68static void slurp_symtab (bfd *);
69static void find_address_in_section (bfd *, asection *, void *);
c5f8c388
EB
70static void find_offset_in_section (bfd *, asection *);
71static void translate_addresses (bfd *, asection *);
252b5132
RH
72\f
73/* Print a usage message to STREAM and exit with STATUS. */
74
75static void
2da42df6 76usage (FILE *stream, int status)
252b5132 77{
8b53311e
NC
78 fprintf (stream, _("Usage: %s [option(s)] [addr(s)]\n"), program_name);
79 fprintf (stream, _(" Convert addresses into line number/file name pairs.\n"));
80 fprintf (stream, _(" If no addresses are specified on the command line, they will be read from stdin\n"));
81 fprintf (stream, _(" The options are:\n\
07012eee 82 @<file> Read options from <file>\n\
be6f6493 83 -a --addresses Show addresses\n\
8b53311e
NC
84 -b --target=<bfdname> Set the binary file format\n\
85 -e --exe=<executable> Set the input file name (default is a.out)\n\
c5f8c388
EB
86 -i --inlines Unwind inlined functions\n\
87 -j --section=<name> Read section-relative offsets instead of addresses\n\
8b53311e
NC
88 -s --basenames Strip directory names\n\
89 -f --functions Show function names\n\
90 -C --demangle[=style] Demangle function names\n\
91 -h --help Display this information\n\
92 -v --version Display the program's version\n\
93\n"));
94
252b5132 95 list_supported_targets (program_name, stream);
92f01d61 96 if (REPORT_BUGS_TO[0] && status == 0)
8ad3436c 97 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
98 exit (status);
99}
100\f
101/* Read in the symbol table. */
102
103static void
2da42df6 104slurp_symtab (bfd *abfd)
252b5132 105{
d5e7ea07 106 long storage;
252b5132 107 long symcount;
d5e7ea07 108 bfd_boolean dynamic = FALSE;
252b5132
RH
109
110 if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
111 return;
112
d5e7ea07
AM
113 storage = bfd_get_symtab_upper_bound (abfd);
114 if (storage == 0)
115 {
116 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
117 dynamic = TRUE;
118 }
119 if (storage < 0)
120 bfd_fatal (bfd_get_filename (abfd));
252b5132 121
d5e7ea07
AM
122 syms = (asymbol **) xmalloc (storage);
123 if (dynamic)
124 symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
125 else
126 symcount = bfd_canonicalize_symtab (abfd, syms);
252b5132
RH
127 if (symcount < 0)
128 bfd_fatal (bfd_get_filename (abfd));
129}
130\f
131/* These global variables are used to pass information between
132 translate_addresses and find_address_in_section. */
133
134static bfd_vma pc;
135static const char *filename;
136static const char *functionname;
137static unsigned int line;
b34976b6 138static bfd_boolean found;
252b5132
RH
139
140/* Look for an address in a section. This is called via
141 bfd_map_over_sections. */
142
143static void
2da42df6
AJ
144find_address_in_section (bfd *abfd, asection *section,
145 void *data ATTRIBUTE_UNUSED)
252b5132
RH
146{
147 bfd_vma vma;
148 bfd_size_type size;
149
150 if (found)
151 return;
152
153 if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
154 return;
155
156 vma = bfd_get_section_vma (abfd, section);
157 if (pc < vma)
158 return;
159
135dfb4a 160 size = bfd_get_section_size (section);
252b5132
RH
161 if (pc >= vma + size)
162 return;
163
164 found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
165 &filename, &functionname, &line);
166}
167
c5f8c388
EB
168/* Look for an offset in a section. This is directly called. */
169
170static void
171find_offset_in_section (bfd *abfd, asection *section)
172{
173 bfd_size_type size;
174
175 if (found)
176 return;
177
178 if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
179 return;
180
181 size = bfd_get_section_size (section);
182 if (pc >= size)
183 return;
184
185 found = bfd_find_nearest_line (abfd, section, syms, pc,
186 &filename, &functionname, &line);
187}
188
252b5132
RH
189/* Read hexadecimal addresses from stdin, translate into
190 file_name:line_number and optionally function name. */
191
192static void
c5f8c388 193translate_addresses (bfd *abfd, asection *section)
252b5132
RH
194{
195 int read_stdin = (naddr == 0);
196
197 for (;;)
198 {
199 if (read_stdin)
200 {
201 char addr_hex[100];
202
203 if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
204 break;
205 pc = bfd_scan_vma (addr_hex, NULL, 16);
206 }
207 else
208 {
209 if (naddr <= 0)
210 break;
211 --naddr;
212 pc = bfd_scan_vma (*addr++, NULL, 16);
213 }
214
be6f6493
TG
215 if (with_addresses)
216 {
217 printf ("0x");
218 bfd_printf_vma (abfd, pc);
219 printf ("\n");
220 }
221
b34976b6 222 found = FALSE;
c5f8c388
EB
223 if (section)
224 find_offset_in_section (abfd, section);
225 else
226 bfd_map_over_sections (abfd, find_address_in_section, NULL);
252b5132
RH
227
228 if (! found)
229 {
230 if (with_functions)
231 printf ("??\n");
232 printf ("??:0\n");
233 }
234 else
235 {
0c552dc1
FF
236 do {
237 if (with_functions)
238 {
239 const char *name;
240 char *alloc = NULL;
241
242 name = functionname;
243 if (name == NULL || *name == '\0')
244 name = "??";
245 else if (do_demangle)
246 {
ed180cc5
AM
247 alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
248 if (alloc != NULL)
249 name = alloc;
0c552dc1
FF
250 }
251
252 printf ("%s\n", name);
253
254 if (alloc != NULL)
255 free (alloc);
256 }
257
258 if (base_names && filename != NULL)
259 {
260 char *h;
261
262 h = strrchr (filename, '/');
263 if (h != NULL)
264 filename = h + 1;
265 }
266
267 printf ("%s:%u\n", filename ? filename : "??", line);
268 if (!unwind_inlines)
269 found = FALSE;
270 else
271 found = bfd_find_inliner_info (abfd, &filename, &functionname, &line);
272 } while (found);
252b5132 273
252b5132
RH
274 }
275
276 /* fflush() is essential for using this command as a server
277 child process that reads addresses from a pipe and responds
278 with line number information, processing one address at a
279 time. */
280 fflush (stdout);
281 }
282}
283
d68c385b 284/* Process a file. Returns an exit value for main(). */
252b5132 285
d68c385b 286static int
c5f8c388
EB
287process_file (const char *file_name, const char *section_name,
288 const char *target)
252b5132
RH
289{
290 bfd *abfd;
c5f8c388 291 asection *section;
252b5132
RH
292 char **matching;
293
f24ddbdd 294 if (get_file_size (file_name) < 1)
d68c385b 295 return 1;
f24ddbdd 296
47badb7b 297 abfd = bfd_openr (file_name, target);
252b5132 298 if (abfd == NULL)
47badb7b 299 bfd_fatal (file_name);
252b5132
RH
300
301 if (bfd_check_format (abfd, bfd_archive))
c5f8c388 302 fatal (_("%s: cannot get addresses from archive"), file_name);
252b5132
RH
303
304 if (! bfd_check_format_matches (abfd, bfd_object, &matching))
305 {
306 bfd_nonfatal (bfd_get_filename (abfd));
307 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
308 {
309 list_matching_formats (matching);
310 free (matching);
311 }
312 xexit (1);
313 }
314
c5f8c388
EB
315 if (section_name != NULL)
316 {
317 section = bfd_get_section_by_name (abfd, section_name);
318 if (section == NULL)
319 fatal (_("%s: cannot find section %s"), file_name, section_name);
320 }
321 else
322 section = NULL;
323
252b5132
RH
324 slurp_symtab (abfd);
325
c5f8c388 326 translate_addresses (abfd, section);
252b5132
RH
327
328 if (syms != NULL)
329 {
330 free (syms);
331 syms = NULL;
332 }
333
334 bfd_close (abfd);
d68c385b
NC
335
336 return 0;
252b5132
RH
337}
338\f
339int
2da42df6 340main (int argc, char **argv)
252b5132 341{
47badb7b 342 const char *file_name;
c5f8c388 343 const char *section_name;
252b5132
RH
344 char *target;
345 int c;
346
347#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
348 setlocale (LC_MESSAGES, "");
3882b010
L
349#endif
350#if defined (HAVE_SETLOCALE)
351 setlocale (LC_CTYPE, "");
252b5132
RH
352#endif
353 bindtextdomain (PACKAGE, LOCALEDIR);
354 textdomain (PACKAGE);
355
356 program_name = *argv;
357 xmalloc_set_program_name (program_name);
358
869b9d07
MM
359 expandargv (&argc, &argv);
360
252b5132
RH
361 bfd_init ();
362 set_default_bfd_target ();
363
47badb7b 364 file_name = NULL;
c5f8c388 365 section_name = NULL;
252b5132 366 target = NULL;
be6f6493 367 while ((c = getopt_long (argc, argv, "ab:Ce:sfHhij:Vv", long_options, (int *) 0))
252b5132
RH
368 != EOF)
369 {
370 switch (c)
371 {
372 case 0:
8b53311e 373 break; /* We've been given a long option. */
be6f6493
TG
374 case 'a':
375 with_addresses = TRUE;
376 break;
252b5132
RH
377 case 'b':
378 target = optarg;
379 break;
380 case 'C':
b34976b6 381 do_demangle = TRUE;
28c309a2
NC
382 if (optarg != NULL)
383 {
384 enum demangling_styles style;
f462a9ea 385
28c309a2 386 style = cplus_demangle_name_to_style (optarg);
f462a9ea 387 if (style == unknown_demangling)
28c309a2
NC
388 fatal (_("unknown demangling style `%s'"),
389 optarg);
f462a9ea 390
28c309a2 391 cplus_demangle_set_style (style);
f462a9ea 392 }
252b5132
RH
393 break;
394 case 'e':
47badb7b 395 file_name = optarg;
252b5132
RH
396 break;
397 case 's':
b34976b6 398 base_names = TRUE;
252b5132
RH
399 break;
400 case 'f':
b34976b6 401 with_functions = TRUE;
252b5132 402 break;
8b53311e 403 case 'v':
252b5132
RH
404 case 'V':
405 print_version ("addr2line");
406 break;
8b53311e 407 case 'h':
252b5132
RH
408 case 'H':
409 usage (stdout, 0);
410 break;
0c552dc1
FF
411 case 'i':
412 unwind_inlines = TRUE;
413 break;
c5f8c388
EB
414 case 'j':
415 section_name = optarg;
416 break;
252b5132
RH
417 default:
418 usage (stderr, 1);
419 break;
420 }
421 }
422
47badb7b
NC
423 if (file_name == NULL)
424 file_name = "a.out";
252b5132
RH
425
426 addr = argv + optind;
427 naddr = argc - optind;
428
d68c385b 429 return process_file (file_name, section_name, target);
252b5132 430}
This page took 0.533737 seconds and 4 git commands to generate.