2009-09-30 Doug Kwan <dougkwan@google.com>
[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. */
b34976b6
AM
42static bfd_boolean with_functions; /* -f, show function names. */
43static bfd_boolean do_demangle; /* -C, demangle names. */
44static bfd_boolean base_names; /* -s, strip directory names. */
252b5132
RH
45
46static int naddr; /* Number of addresses to process. */
47static char **addr; /* Hex addresses to process. */
48
49static asymbol **syms; /* Symbol table. */
50
51static struct option long_options[] =
52{
53 {"basenames", no_argument, NULL, 's'},
28c309a2 54 {"demangle", optional_argument, NULL, 'C'},
252b5132
RH
55 {"exe", required_argument, NULL, 'e'},
56 {"functions", no_argument, NULL, 'f'},
0c552dc1 57 {"inlines", no_argument, NULL, 'i'},
c5f8c388 58 {"section", required_argument, NULL, 'j'},
252b5132
RH
59 {"target", required_argument, NULL, 'b'},
60 {"help", no_argument, NULL, 'H'},
61 {"version", no_argument, NULL, 'V'},
62 {0, no_argument, 0, 0}
63};
64
2da42df6
AJ
65static void usage (FILE *, int);
66static void slurp_symtab (bfd *);
67static void find_address_in_section (bfd *, asection *, void *);
c5f8c388
EB
68static void find_offset_in_section (bfd *, asection *);
69static void translate_addresses (bfd *, asection *);
252b5132
RH
70\f
71/* Print a usage message to STREAM and exit with STATUS. */
72
73static void
2da42df6 74usage (FILE *stream, int status)
252b5132 75{
8b53311e
NC
76 fprintf (stream, _("Usage: %s [option(s)] [addr(s)]\n"), program_name);
77 fprintf (stream, _(" Convert addresses into line number/file name pairs.\n"));
78 fprintf (stream, _(" If no addresses are specified on the command line, they will be read from stdin\n"));
79 fprintf (stream, _(" The options are:\n\
07012eee 80 @<file> Read options from <file>\n\
8b53311e
NC
81 -b --target=<bfdname> Set the binary file format\n\
82 -e --exe=<executable> Set the input file name (default is a.out)\n\
c5f8c388
EB
83 -i --inlines Unwind inlined functions\n\
84 -j --section=<name> Read section-relative offsets instead of addresses\n\
8b53311e
NC
85 -s --basenames Strip directory names\n\
86 -f --functions Show function names\n\
87 -C --demangle[=style] Demangle function names\n\
88 -h --help Display this information\n\
89 -v --version Display the program's version\n\
90\n"));
91
252b5132 92 list_supported_targets (program_name, stream);
92f01d61 93 if (REPORT_BUGS_TO[0] && status == 0)
8ad3436c 94 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
95 exit (status);
96}
97\f
98/* Read in the symbol table. */
99
100static void
2da42df6 101slurp_symtab (bfd *abfd)
252b5132 102{
252b5132 103 long symcount;
f309035a 104 unsigned int size;
3f5e193b 105 void *minisyms = &syms;
252b5132
RH
106
107 if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
108 return;
109
3f5e193b 110 symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
f309035a 111 if (symcount == 0)
3f5e193b 112 symcount = bfd_read_minisymbols (abfd, TRUE /* dynamic */, &minisyms, &size);
252b5132 113
252b5132
RH
114 if (symcount < 0)
115 bfd_fatal (bfd_get_filename (abfd));
116}
117\f
118/* These global variables are used to pass information between
119 translate_addresses and find_address_in_section. */
120
121static bfd_vma pc;
122static const char *filename;
123static const char *functionname;
124static unsigned int line;
b34976b6 125static bfd_boolean found;
252b5132
RH
126
127/* Look for an address in a section. This is called via
128 bfd_map_over_sections. */
129
130static void
2da42df6
AJ
131find_address_in_section (bfd *abfd, asection *section,
132 void *data ATTRIBUTE_UNUSED)
252b5132
RH
133{
134 bfd_vma vma;
135 bfd_size_type size;
136
137 if (found)
138 return;
139
140 if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
141 return;
142
143 vma = bfd_get_section_vma (abfd, section);
144 if (pc < vma)
145 return;
146
135dfb4a 147 size = bfd_get_section_size (section);
252b5132
RH
148 if (pc >= vma + size)
149 return;
150
151 found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
152 &filename, &functionname, &line);
153}
154
c5f8c388
EB
155/* Look for an offset in a section. This is directly called. */
156
157static void
158find_offset_in_section (bfd *abfd, asection *section)
159{
160 bfd_size_type size;
161
162 if (found)
163 return;
164
165 if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
166 return;
167
168 size = bfd_get_section_size (section);
169 if (pc >= size)
170 return;
171
172 found = bfd_find_nearest_line (abfd, section, syms, pc,
173 &filename, &functionname, &line);
174}
175
252b5132
RH
176/* Read hexadecimal addresses from stdin, translate into
177 file_name:line_number and optionally function name. */
178
179static void
c5f8c388 180translate_addresses (bfd *abfd, asection *section)
252b5132
RH
181{
182 int read_stdin = (naddr == 0);
183
184 for (;;)
185 {
186 if (read_stdin)
187 {
188 char addr_hex[100];
189
190 if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
191 break;
192 pc = bfd_scan_vma (addr_hex, NULL, 16);
193 }
194 else
195 {
196 if (naddr <= 0)
197 break;
198 --naddr;
199 pc = bfd_scan_vma (*addr++, NULL, 16);
200 }
201
b34976b6 202 found = FALSE;
c5f8c388
EB
203 if (section)
204 find_offset_in_section (abfd, section);
205 else
206 bfd_map_over_sections (abfd, find_address_in_section, NULL);
252b5132
RH
207
208 if (! found)
209 {
210 if (with_functions)
211 printf ("??\n");
212 printf ("??:0\n");
213 }
214 else
215 {
0c552dc1
FF
216 do {
217 if (with_functions)
218 {
219 const char *name;
220 char *alloc = NULL;
221
222 name = functionname;
223 if (name == NULL || *name == '\0')
224 name = "??";
225 else if (do_demangle)
226 {
ed180cc5
AM
227 alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
228 if (alloc != NULL)
229 name = alloc;
0c552dc1
FF
230 }
231
232 printf ("%s\n", name);
233
234 if (alloc != NULL)
235 free (alloc);
236 }
237
238 if (base_names && filename != NULL)
239 {
240 char *h;
241
242 h = strrchr (filename, '/');
243 if (h != NULL)
244 filename = h + 1;
245 }
246
247 printf ("%s:%u\n", filename ? filename : "??", line);
248 if (!unwind_inlines)
249 found = FALSE;
250 else
251 found = bfd_find_inliner_info (abfd, &filename, &functionname, &line);
252 } while (found);
252b5132 253
252b5132
RH
254 }
255
256 /* fflush() is essential for using this command as a server
257 child process that reads addresses from a pipe and responds
258 with line number information, processing one address at a
259 time. */
260 fflush (stdout);
261 }
262}
263
d68c385b 264/* Process a file. Returns an exit value for main(). */
252b5132 265
d68c385b 266static int
c5f8c388
EB
267process_file (const char *file_name, const char *section_name,
268 const char *target)
252b5132
RH
269{
270 bfd *abfd;
c5f8c388 271 asection *section;
252b5132
RH
272 char **matching;
273
f24ddbdd 274 if (get_file_size (file_name) < 1)
d68c385b 275 return 1;
f24ddbdd 276
47badb7b 277 abfd = bfd_openr (file_name, target);
252b5132 278 if (abfd == NULL)
47badb7b 279 bfd_fatal (file_name);
252b5132
RH
280
281 if (bfd_check_format (abfd, bfd_archive))
c5f8c388 282 fatal (_("%s: cannot get addresses from archive"), file_name);
252b5132
RH
283
284 if (! bfd_check_format_matches (abfd, bfd_object, &matching))
285 {
286 bfd_nonfatal (bfd_get_filename (abfd));
287 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
288 {
289 list_matching_formats (matching);
290 free (matching);
291 }
292 xexit (1);
293 }
294
c5f8c388
EB
295 if (section_name != NULL)
296 {
297 section = bfd_get_section_by_name (abfd, section_name);
298 if (section == NULL)
299 fatal (_("%s: cannot find section %s"), file_name, section_name);
300 }
301 else
302 section = NULL;
303
252b5132
RH
304 slurp_symtab (abfd);
305
c5f8c388 306 translate_addresses (abfd, section);
252b5132
RH
307
308 if (syms != NULL)
309 {
310 free (syms);
311 syms = NULL;
312 }
313
314 bfd_close (abfd);
d68c385b
NC
315
316 return 0;
252b5132
RH
317}
318\f
319int
2da42df6 320main (int argc, char **argv)
252b5132 321{
47badb7b 322 const char *file_name;
c5f8c388 323 const char *section_name;
252b5132
RH
324 char *target;
325 int c;
326
327#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
328 setlocale (LC_MESSAGES, "");
3882b010
L
329#endif
330#if defined (HAVE_SETLOCALE)
331 setlocale (LC_CTYPE, "");
252b5132
RH
332#endif
333 bindtextdomain (PACKAGE, LOCALEDIR);
334 textdomain (PACKAGE);
335
336 program_name = *argv;
337 xmalloc_set_program_name (program_name);
338
869b9d07
MM
339 expandargv (&argc, &argv);
340
252b5132
RH
341 bfd_init ();
342 set_default_bfd_target ();
343
47badb7b 344 file_name = NULL;
c5f8c388 345 section_name = NULL;
252b5132 346 target = NULL;
c5f8c388 347 while ((c = getopt_long (argc, argv, "b:Ce:sfHhij:Vv", long_options, (int *) 0))
252b5132
RH
348 != EOF)
349 {
350 switch (c)
351 {
352 case 0:
8b53311e 353 break; /* We've been given a long option. */
252b5132
RH
354 case 'b':
355 target = optarg;
356 break;
357 case 'C':
b34976b6 358 do_demangle = TRUE;
28c309a2
NC
359 if (optarg != NULL)
360 {
361 enum demangling_styles style;
f462a9ea 362
28c309a2 363 style = cplus_demangle_name_to_style (optarg);
f462a9ea 364 if (style == unknown_demangling)
28c309a2
NC
365 fatal (_("unknown demangling style `%s'"),
366 optarg);
f462a9ea 367
28c309a2 368 cplus_demangle_set_style (style);
f462a9ea 369 }
252b5132
RH
370 break;
371 case 'e':
47badb7b 372 file_name = optarg;
252b5132
RH
373 break;
374 case 's':
b34976b6 375 base_names = TRUE;
252b5132
RH
376 break;
377 case 'f':
b34976b6 378 with_functions = TRUE;
252b5132 379 break;
8b53311e 380 case 'v':
252b5132
RH
381 case 'V':
382 print_version ("addr2line");
383 break;
8b53311e 384 case 'h':
252b5132
RH
385 case 'H':
386 usage (stdout, 0);
387 break;
0c552dc1
FF
388 case 'i':
389 unwind_inlines = TRUE;
390 break;
c5f8c388
EB
391 case 'j':
392 section_name = optarg;
393 break;
252b5132
RH
394 default:
395 usage (stderr, 1);
396 break;
397 }
398 }
399
47badb7b
NC
400 if (file_name == NULL)
401 file_name = "a.out";
252b5132
RH
402
403 addr = argv + optind;
404 naddr = argc - optind;
405
d68c385b 406 return process_file (file_name, section_name, target);
252b5132 407}
This page took 0.467285 seconds and 4 git commands to generate.