* ld.texinfo: Make it clear that --nmagic disables linking
[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{
d5e7ea07 103 long storage;
252b5132 104 long symcount;
d5e7ea07 105 bfd_boolean dynamic = FALSE;
252b5132
RH
106
107 if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
108 return;
109
d5e7ea07
AM
110 storage = bfd_get_symtab_upper_bound (abfd);
111 if (storage == 0)
112 {
113 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
114 dynamic = TRUE;
115 }
116 if (storage < 0)
117 bfd_fatal (bfd_get_filename (abfd));
252b5132 118
d5e7ea07
AM
119 syms = (asymbol **) xmalloc (storage);
120 if (dynamic)
121 symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
122 else
123 symcount = bfd_canonicalize_symtab (abfd, syms);
252b5132
RH
124 if (symcount < 0)
125 bfd_fatal (bfd_get_filename (abfd));
126}
127\f
128/* These global variables are used to pass information between
129 translate_addresses and find_address_in_section. */
130
131static bfd_vma pc;
132static const char *filename;
133static const char *functionname;
134static unsigned int line;
b34976b6 135static bfd_boolean found;
252b5132
RH
136
137/* Look for an address in a section. This is called via
138 bfd_map_over_sections. */
139
140static void
2da42df6
AJ
141find_address_in_section (bfd *abfd, asection *section,
142 void *data ATTRIBUTE_UNUSED)
252b5132
RH
143{
144 bfd_vma vma;
145 bfd_size_type size;
146
147 if (found)
148 return;
149
150 if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
151 return;
152
153 vma = bfd_get_section_vma (abfd, section);
154 if (pc < vma)
155 return;
156
135dfb4a 157 size = bfd_get_section_size (section);
252b5132
RH
158 if (pc >= vma + size)
159 return;
160
161 found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
162 &filename, &functionname, &line);
163}
164
c5f8c388
EB
165/* Look for an offset in a section. This is directly called. */
166
167static void
168find_offset_in_section (bfd *abfd, asection *section)
169{
170 bfd_size_type size;
171
172 if (found)
173 return;
174
175 if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
176 return;
177
178 size = bfd_get_section_size (section);
179 if (pc >= size)
180 return;
181
182 found = bfd_find_nearest_line (abfd, section, syms, pc,
183 &filename, &functionname, &line);
184}
185
252b5132
RH
186/* Read hexadecimal addresses from stdin, translate into
187 file_name:line_number and optionally function name. */
188
189static void
c5f8c388 190translate_addresses (bfd *abfd, asection *section)
252b5132
RH
191{
192 int read_stdin = (naddr == 0);
193
194 for (;;)
195 {
196 if (read_stdin)
197 {
198 char addr_hex[100];
199
200 if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
201 break;
202 pc = bfd_scan_vma (addr_hex, NULL, 16);
203 }
204 else
205 {
206 if (naddr <= 0)
207 break;
208 --naddr;
209 pc = bfd_scan_vma (*addr++, NULL, 16);
210 }
211
b34976b6 212 found = FALSE;
c5f8c388
EB
213 if (section)
214 find_offset_in_section (abfd, section);
215 else
216 bfd_map_over_sections (abfd, find_address_in_section, NULL);
252b5132
RH
217
218 if (! found)
219 {
220 if (with_functions)
221 printf ("??\n");
222 printf ("??:0\n");
223 }
224 else
225 {
0c552dc1
FF
226 do {
227 if (with_functions)
228 {
229 const char *name;
230 char *alloc = NULL;
231
232 name = functionname;
233 if (name == NULL || *name == '\0')
234 name = "??";
235 else if (do_demangle)
236 {
ed180cc5
AM
237 alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
238 if (alloc != NULL)
239 name = alloc;
0c552dc1
FF
240 }
241
242 printf ("%s\n", name);
243
244 if (alloc != NULL)
245 free (alloc);
246 }
247
248 if (base_names && filename != NULL)
249 {
250 char *h;
251
252 h = strrchr (filename, '/');
253 if (h != NULL)
254 filename = h + 1;
255 }
256
257 printf ("%s:%u\n", filename ? filename : "??", line);
258 if (!unwind_inlines)
259 found = FALSE;
260 else
261 found = bfd_find_inliner_info (abfd, &filename, &functionname, &line);
262 } while (found);
252b5132 263
252b5132
RH
264 }
265
266 /* fflush() is essential for using this command as a server
267 child process that reads addresses from a pipe and responds
268 with line number information, processing one address at a
269 time. */
270 fflush (stdout);
271 }
272}
273
d68c385b 274/* Process a file. Returns an exit value for main(). */
252b5132 275
d68c385b 276static int
c5f8c388
EB
277process_file (const char *file_name, const char *section_name,
278 const char *target)
252b5132
RH
279{
280 bfd *abfd;
c5f8c388 281 asection *section;
252b5132
RH
282 char **matching;
283
f24ddbdd 284 if (get_file_size (file_name) < 1)
d68c385b 285 return 1;
f24ddbdd 286
47badb7b 287 abfd = bfd_openr (file_name, target);
252b5132 288 if (abfd == NULL)
47badb7b 289 bfd_fatal (file_name);
252b5132
RH
290
291 if (bfd_check_format (abfd, bfd_archive))
c5f8c388 292 fatal (_("%s: cannot get addresses from archive"), file_name);
252b5132
RH
293
294 if (! bfd_check_format_matches (abfd, bfd_object, &matching))
295 {
296 bfd_nonfatal (bfd_get_filename (abfd));
297 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
298 {
299 list_matching_formats (matching);
300 free (matching);
301 }
302 xexit (1);
303 }
304
c5f8c388
EB
305 if (section_name != NULL)
306 {
307 section = bfd_get_section_by_name (abfd, section_name);
308 if (section == NULL)
309 fatal (_("%s: cannot find section %s"), file_name, section_name);
310 }
311 else
312 section = NULL;
313
252b5132
RH
314 slurp_symtab (abfd);
315
c5f8c388 316 translate_addresses (abfd, section);
252b5132
RH
317
318 if (syms != NULL)
319 {
320 free (syms);
321 syms = NULL;
322 }
323
324 bfd_close (abfd);
d68c385b
NC
325
326 return 0;
252b5132
RH
327}
328\f
329int
2da42df6 330main (int argc, char **argv)
252b5132 331{
47badb7b 332 const char *file_name;
c5f8c388 333 const char *section_name;
252b5132
RH
334 char *target;
335 int c;
336
337#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
338 setlocale (LC_MESSAGES, "");
3882b010
L
339#endif
340#if defined (HAVE_SETLOCALE)
341 setlocale (LC_CTYPE, "");
252b5132
RH
342#endif
343 bindtextdomain (PACKAGE, LOCALEDIR);
344 textdomain (PACKAGE);
345
346 program_name = *argv;
347 xmalloc_set_program_name (program_name);
348
869b9d07
MM
349 expandargv (&argc, &argv);
350
252b5132
RH
351 bfd_init ();
352 set_default_bfd_target ();
353
47badb7b 354 file_name = NULL;
c5f8c388 355 section_name = NULL;
252b5132 356 target = NULL;
c5f8c388 357 while ((c = getopt_long (argc, argv, "b:Ce:sfHhij:Vv", long_options, (int *) 0))
252b5132
RH
358 != EOF)
359 {
360 switch (c)
361 {
362 case 0:
8b53311e 363 break; /* We've been given a long option. */
252b5132
RH
364 case 'b':
365 target = optarg;
366 break;
367 case 'C':
b34976b6 368 do_demangle = TRUE;
28c309a2
NC
369 if (optarg != NULL)
370 {
371 enum demangling_styles style;
f462a9ea 372
28c309a2 373 style = cplus_demangle_name_to_style (optarg);
f462a9ea 374 if (style == unknown_demangling)
28c309a2
NC
375 fatal (_("unknown demangling style `%s'"),
376 optarg);
f462a9ea 377
28c309a2 378 cplus_demangle_set_style (style);
f462a9ea 379 }
252b5132
RH
380 break;
381 case 'e':
47badb7b 382 file_name = optarg;
252b5132
RH
383 break;
384 case 's':
b34976b6 385 base_names = TRUE;
252b5132
RH
386 break;
387 case 'f':
b34976b6 388 with_functions = TRUE;
252b5132 389 break;
8b53311e 390 case 'v':
252b5132
RH
391 case 'V':
392 print_version ("addr2line");
393 break;
8b53311e 394 case 'h':
252b5132
RH
395 case 'H':
396 usage (stdout, 0);
397 break;
0c552dc1
FF
398 case 'i':
399 unwind_inlines = TRUE;
400 break;
c5f8c388
EB
401 case 'j':
402 section_name = optarg;
403 break;
252b5132
RH
404 default:
405 usage (stderr, 1);
406 break;
407 }
408 }
409
47badb7b
NC
410 if (file_name == NULL)
411 file_name = "a.out";
252b5132
RH
412
413 addr = argv + optind;
414 naddr = argc - optind;
415
d68c385b 416 return process_file (file_name, section_name, target);
252b5132 417}
This page took 0.42214 seconds and 4 git commands to generate.