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