1 /* Locate source files and line information for given addresses
2    Copyright (C) 2005-2010, 2012, 2013 Red Hat, Inc.
3    This file is part of elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 2005.
5 
6    This file is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    elfutils is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 
23 #include <argp.h>
24 #include <assert.h>
25 #include <errno.h>
26 #include <error.h>
27 #include <fcntl.h>
28 #include <inttypes.h>
29 #include <libdwfl.h>
30 #include <dwarf.h>
31 #include <libintl.h>
32 #include <locale.h>
33 #include <mcheck.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdio_ext.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 
41 #include <system.h>
42 
43 
44 /* Name and version of program.  */
45 static void print_version (FILE *stream, struct argp_state *state);
46 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
47 
48 /* Bug report address.  */
49 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
50 
51 
52 /* Values for the parameters which have no short form.  */
53 #define OPT_DEMANGLER 0x100
54 
55 /* Definitions of arguments for argp functions.  */
56 static const struct argp_option options[] =
57 {
58   { NULL, 0, NULL, 0, N_("Output selection options:"), 2 },
59   { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 },
60   { "absolute", 'A', NULL, 0,
61     N_("Show absolute file names using compilation directory"), 0 },
62   { "functions", 'f', NULL, 0, N_("Also show function names"), 0 },
63   { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 },
64   { "symbols-sections", 'x', NULL, 0, N_("Also show symbol and the section names"), 0 },
65   { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 },
66   { "section", 'j', "NAME", 0,
67     N_("Treat addresses as offsets relative to NAME section."), 0 },
68   { "inlines", 'i', NULL, 0,
69     N_("Show all source locations that caused inline expansion of subroutines at the address."),
70     0 },
71 
72   { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
73   /* Unsupported options.  */
74   { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 },
75   { "demangle", 'C', "ARG", OPTION_HIDDEN | OPTION_ARG_OPTIONAL, NULL, 0 },
76   { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 },
77   { NULL, 0, NULL, 0, NULL, 0 }
78 };
79 
80 /* Short description of program.  */
81 static const char doc[] = N_("\
82 Locate source files and line information for ADDRs (in a.out by default).");
83 
84 /* Strings for arguments in help texts.  */
85 static const char args_doc[] = N_("[ADDR...]");
86 
87 /* Prototype for option handler.  */
88 static error_t parse_opt (int key, char *arg, struct argp_state *state);
89 
90 static struct argp_child argp_children[2]; /* [0] is set in main.  */
91 
92 /* Data structure to communicate with argp functions.  */
93 static const struct argp argp =
94 {
95   options, parse_opt, args_doc, doc, argp_children, NULL, NULL
96 };
97 
98 
99 /* Handle ADDR.  */
100 static int handle_address (const char *addr, Dwfl *dwfl);
101 
102 
103 /* True if only base names of files should be shown.  */
104 static bool only_basenames;
105 
106 /* True if absolute file names based on DW_AT_comp_dir should be shown.  */
107 static bool use_comp_dir;
108 
109 /* True if line flags should be shown.  */
110 static bool show_flags;
111 
112 /* True if function names should be shown.  */
113 static bool show_functions;
114 
115 /* True if ELF symbol or section info should be shown.  */
116 static bool show_symbols;
117 
118 /* True if section associated with a symbol address should be shown.  */
119 static bool show_symbol_sections;
120 
121 /* If non-null, take address parameters as relative to named section.  */
122 static const char *just_section;
123 
124 /* True if all inlined subroutines of the current address should be shown.  */
125 static bool show_inlines;
126 
127 
128 int
main(int argc,char * argv[])129 main (int argc, char *argv[])
130 {
131   int remaining;
132   int result = 0;
133 
134   /* Make memory leak detection possible.  */
135   mtrace ();
136 
137   /* We use no threads here which can interfere with handling a stream.  */
138   (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
139 
140   /* Set locale.  */
141   (void) setlocale (LC_ALL, "");
142 
143   /* Make sure the message catalog can be found.  */
144   (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
145 
146   /* Initialize the message catalog.  */
147   (void) textdomain (PACKAGE_TARNAME);
148 
149   /* Parse and process arguments.  This includes opening the modules.  */
150   argp_children[0].argp = dwfl_standard_argp ();
151   argp_children[0].group = 1;
152   Dwfl *dwfl = NULL;
153   (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl);
154   assert (dwfl != NULL);
155 
156   /* Now handle the addresses.  In case none are given on the command
157      line, read from stdin.  */
158   if (remaining == argc)
159     {
160       /* We use no threads here which can interfere with handling a stream.  */
161       (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
162 
163       char *buf = NULL;
164       size_t len = 0;
165       ssize_t chars;
166       while (!feof_unlocked (stdin))
167 	{
168 	  if ((chars = getline (&buf, &len, stdin)) < 0)
169 	    break;
170 
171 	  if (buf[chars - 1] == '\n')
172 	    buf[chars - 1] = '\0';
173 
174 	  result = handle_address (buf, dwfl);
175 	}
176 
177       free (buf);
178     }
179   else
180     {
181       do
182 	result = handle_address (argv[remaining], dwfl);
183       while (++remaining < argc);
184     }
185 
186   dwfl_end (dwfl);
187   return result;
188 }
189 
190 
191 /* Print the version information.  */
192 static void
print_version(FILE * stream,struct argp_state * state)193 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
194 {
195   fprintf (stream, "addr2line (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
196   fprintf (stream, gettext ("\
197 Copyright (C) %s Red Hat, Inc.\n\
198 This is free software; see the source for copying conditions.  There is NO\n\
199 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
200 "), "2012");
201   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
202 }
203 
204 
205 /* Handle program arguments.  */
206 static error_t
parse_opt(int key,char * arg,struct argp_state * state)207 parse_opt (int key, char *arg, struct argp_state *state)
208 {
209   switch (key)
210     {
211     case ARGP_KEY_INIT:
212       state->child_inputs[0] = state->input;
213       break;
214 
215     case 'b':
216     case 'C':
217     case OPT_DEMANGLER:
218       /* Ignored for compatibility.  */
219       break;
220 
221     case 's':
222       only_basenames = true;
223       break;
224 
225     case 'A':
226       use_comp_dir = true;
227       break;
228 
229     case 'f':
230       show_functions = true;
231       break;
232 
233     case 'F':
234       show_flags = true;
235       break;
236 
237     case 'S':
238       show_symbols = true;
239       break;
240 
241     case 'x':
242       show_symbols = true;
243       show_symbol_sections = true;
244       break;
245 
246     case 'j':
247       just_section = arg;
248       break;
249 
250     case 'i':
251       show_inlines = true;
252       break;
253 
254     default:
255       return ARGP_ERR_UNKNOWN;
256     }
257   return 0;
258 }
259 
260 
261 static const char *
get_diename(Dwarf_Die * die)262 get_diename (Dwarf_Die *die)
263 {
264   Dwarf_Attribute attr;
265   const char *name;
266 
267   name = dwarf_formstring (dwarf_attr_integrate (die, DW_AT_MIPS_linkage_name,
268 						 &attr)
269 			   ?: dwarf_attr_integrate (die, DW_AT_linkage_name,
270 						    &attr));
271 
272   if (name == NULL)
273     name = dwarf_diename (die) ?: "??";
274 
275   return name;
276 }
277 
278 static bool
print_dwarf_function(Dwfl_Module * mod,Dwarf_Addr addr)279 print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
280 {
281   Dwarf_Addr bias = 0;
282   Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias);
283 
284   Dwarf_Die *scopes;
285   int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes);
286   if (nscopes <= 0)
287     return false;
288 
289   for (int i = 0; i < nscopes; ++i)
290     switch (dwarf_tag (&scopes[i]))
291       {
292       case DW_TAG_subprogram:
293 	{
294 	  const char *name = get_diename (&scopes[i]);
295 	  if (name == NULL)
296 	    return false;
297 	  puts (name);
298 	  return true;
299 	}
300 
301       case DW_TAG_inlined_subroutine:
302 	{
303 	  const char *name = get_diename (&scopes[i]);
304 	  if (name == NULL)
305 	    return false;
306 	  printf ("%s inlined", name);
307 
308 	  Dwarf_Files *files;
309 	  if (dwarf_getsrcfiles (cudie, &files, NULL) == 0)
310 	    {
311 	      Dwarf_Attribute attr_mem;
312 	      Dwarf_Word val;
313 	      if (dwarf_formudata (dwarf_attr (&scopes[i],
314 					       DW_AT_call_file,
315 					       &attr_mem), &val) == 0)
316 		{
317 		  const char *file = dwarf_filesrc (files, val, NULL, NULL);
318 		  unsigned int lineno = 0;
319 		  unsigned int colno = 0;
320 		  if (dwarf_formudata (dwarf_attr (&scopes[i],
321 						   DW_AT_call_line,
322 						   &attr_mem), &val) == 0)
323 		    lineno = val;
324 		  if (dwarf_formudata (dwarf_attr (&scopes[i],
325 						   DW_AT_call_column,
326 						   &attr_mem), &val) == 0)
327 		    colno = val;
328 
329 		  const char *comp_dir = "";
330 		  const char *comp_dir_sep = "";
331 
332 		  if (file == NULL)
333 		    file = "???";
334 		  else if (only_basenames)
335 		    file = basename (file);
336 		  else if (use_comp_dir && file[0] != '/')
337 		    {
338 		      const char *const *dirs;
339 		      size_t ndirs;
340 		      if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0
341 			  && dirs[0] != NULL)
342 			{
343 			  comp_dir = dirs[0];
344 			  comp_dir_sep = "/";
345 			}
346 		    }
347 
348 		  if (lineno == 0)
349 		    printf (" from %s%s%s",
350 			    comp_dir, comp_dir_sep, file);
351 		  else if (colno == 0)
352 		    printf (" at %s%s%s:%u",
353 			    comp_dir, comp_dir_sep, file, lineno);
354 		  else
355 		    printf (" at %s%s%s:%u:%u",
356 			    comp_dir, comp_dir_sep, file, lineno, colno);
357 		}
358 	    }
359 	  printf (" in ");
360 	  continue;
361 	}
362       }
363 
364   return false;
365 }
366 
367 static void
print_addrsym(Dwfl_Module * mod,GElf_Addr addr)368 print_addrsym (Dwfl_Module *mod, GElf_Addr addr)
369 {
370   GElf_Sym s;
371   GElf_Off off;
372   const char *name = dwfl_module_addrinfo (mod, addr, &off, &s,
373 					   NULL, NULL, NULL);
374   if (name == NULL)
375     {
376       /* No symbol name.  Get a section name instead.  */
377       int i = dwfl_module_relocate_address (mod, &addr);
378       if (i >= 0)
379 	name = dwfl_module_relocation_info (mod, i, NULL);
380       if (name == NULL)
381 	puts ("??");
382       else
383 	printf ("(%s)+%#" PRIx64 "\n", name, addr);
384     }
385   else
386     {
387       if (off == 0)
388 	printf ("%s", name);
389       else
390 	printf ("%s+%#" PRIx64 "", name, off);
391 
392       // Also show section name for address.
393       if (show_symbol_sections)
394 	{
395 	  Dwarf_Addr ebias;
396 	  Elf_Scn *scn = dwfl_module_address_section (mod, &addr, &ebias);
397 	  if (scn != NULL)
398 	    {
399 	      GElf_Shdr shdr_mem;
400 	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
401 	      if (shdr != NULL)
402 		{
403 		  Elf *elf = dwfl_module_getelf (mod, &ebias);
404 		  GElf_Ehdr ehdr;
405 		  if (gelf_getehdr (elf, &ehdr) != NULL)
406 		    printf (" (%s)", elf_strptr (elf, ehdr.e_shstrndx,
407 						 shdr->sh_name));
408 		}
409 	    }
410 	}
411       puts ("");
412     }
413 }
414 
415 static int
see_one_module(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)416 see_one_module (Dwfl_Module *mod,
417 		void **userdata __attribute__ ((unused)),
418 		const char *name __attribute__ ((unused)),
419 		Dwarf_Addr start __attribute__ ((unused)),
420 		void *arg)
421 {
422   Dwfl_Module **result = arg;
423   if (*result != NULL)
424     return DWARF_CB_ABORT;
425   *result = mod;
426   return DWARF_CB_OK;
427 }
428 
429 static int
find_symbol(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)430 find_symbol (Dwfl_Module *mod,
431 	     void **userdata __attribute__ ((unused)),
432 	     const char *name __attribute__ ((unused)),
433 	     Dwarf_Addr start __attribute__ ((unused)),
434 	     void *arg)
435 {
436   const char *looking_for = ((void **) arg)[0];
437   GElf_Sym *symbol = ((void **) arg)[1];
438   GElf_Addr *value = ((void **) arg)[2];
439 
440   int n = dwfl_module_getsymtab (mod);
441   for (int i = 1; i < n; ++i)
442     {
443       const char *symbol_name = dwfl_module_getsym_info (mod, i, symbol,
444 							 value, NULL, NULL,
445 							 NULL);
446       if (symbol_name == NULL || symbol_name[0] == '\0')
447 	continue;
448       switch (GELF_ST_TYPE (symbol->st_info))
449 	{
450 	case STT_SECTION:
451 	case STT_FILE:
452 	case STT_TLS:
453 	  break;
454 	default:
455 	  if (!strcmp (symbol_name, looking_for))
456 	    {
457 	      ((void **) arg)[0] = NULL;
458 	      return DWARF_CB_ABORT;
459 	    }
460 	}
461     }
462 
463   return DWARF_CB_OK;
464 }
465 
466 static bool
adjust_to_section(const char * name,uintmax_t * addr,Dwfl * dwfl)467 adjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl)
468 {
469   /* It was (section)+offset.  This makes sense if there is
470      only one module to look in for a section.  */
471   Dwfl_Module *mod = NULL;
472   if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0
473       || mod == NULL)
474     error (EXIT_FAILURE, 0, gettext ("Section syntax requires"
475 				     " exactly one module"));
476 
477   int nscn = dwfl_module_relocations (mod);
478   for (int i = 0; i < nscn; ++i)
479     {
480       GElf_Word shndx;
481       const char *scn = dwfl_module_relocation_info (mod, i, &shndx);
482       if (unlikely (scn == NULL))
483 	break;
484       if (!strcmp (scn, name))
485 	{
486 	  /* Found the section.  */
487 	  GElf_Shdr shdr_mem;
488 	  GElf_Addr shdr_bias;
489 	  GElf_Shdr *shdr = gelf_getshdr
490 	    (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx),
491 	     &shdr_mem);
492 	  if (unlikely (shdr == NULL))
493 	    break;
494 
495 	  if (*addr >= shdr->sh_size)
496 	    error (0, 0,
497 		   gettext ("offset %#" PRIxMAX " lies outside"
498 			    " section '%s'"),
499 		   *addr, scn);
500 
501 	  *addr += shdr->sh_addr + shdr_bias;
502 	  return true;
503 	}
504     }
505 
506   return false;
507 }
508 
509 static void
print_src(const char * src,int lineno,int linecol,Dwarf_Die * cu)510 print_src (const char *src, int lineno, int linecol, Dwarf_Die *cu)
511 {
512   const char *comp_dir = "";
513   const char *comp_dir_sep = "";
514 
515   if (only_basenames)
516     src = basename (src);
517   else if (use_comp_dir && src[0] != '/')
518     {
519       Dwarf_Attribute attr;
520       comp_dir = dwarf_formstring (dwarf_attr (cu, DW_AT_comp_dir, &attr));
521       if (comp_dir != NULL)
522 	comp_dir_sep = "/";
523     }
524 
525   if (linecol != 0)
526     printf ("%s%s%s:%d:%d",
527 	    comp_dir, comp_dir_sep, src, lineno, linecol);
528   else
529     printf ("%s%s%s:%d",
530 	    comp_dir, comp_dir_sep, src, lineno);
531 }
532 
533 static int
handle_address(const char * string,Dwfl * dwfl)534 handle_address (const char *string, Dwfl *dwfl)
535 {
536   char *endp;
537   uintmax_t addr = strtoumax (string, &endp, 0);
538   if (endp == string)
539     {
540       bool parsed = false;
541       int i, j;
542       char *name = NULL;
543       if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2
544 	  && string[i] == '\0')
545 	parsed = adjust_to_section (name, &addr, dwfl);
546       switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j))
547 	{
548 	default:
549 	  break;
550 	case 1:
551 	  addr = 0;
552 	  j = i;
553 	case 2:
554 	  if (string[j] != '\0')
555 	    break;
556 
557 	  /* It was symbol[+offset].  */
558 	  GElf_Sym sym;
559 	  GElf_Addr value = 0;
560 	  void *arg[3] = { name, &sym, &value };
561 	  (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0);
562 	  if (arg[0] != NULL)
563 	    error (0, 0, gettext ("cannot find symbol '%s'"), name);
564 	  else
565 	    {
566 	      if (sym.st_size != 0 && addr >= sym.st_size)
567 		error (0, 0,
568 		       gettext ("offset %#" PRIxMAX " lies outside"
569 				" contents of '%s'"),
570 		       addr, name);
571 	      addr += value;
572 	      parsed = true;
573 	    }
574 	  break;
575 	}
576 
577       free (name);
578       if (!parsed)
579 	return 1;
580     }
581   else if (just_section != NULL
582 	   && !adjust_to_section (just_section, &addr, dwfl))
583     return 1;
584 
585   Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr);
586 
587   if (show_functions)
588     {
589       /* First determine the function name.  Use the DWARF information if
590 	 possible.  */
591       if (! print_dwarf_function (mod, addr) && !show_symbols)
592 	puts (dwfl_module_addrname (mod, addr) ?: "??");
593     }
594 
595   if (show_symbols)
596     print_addrsym (mod, addr);
597 
598   Dwfl_Line *line = dwfl_module_getsrc (mod, addr);
599 
600   const char *src;
601   int lineno, linecol;
602 
603   if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
604 					    NULL, NULL)) != NULL)
605     {
606       print_src (src, lineno, linecol, dwfl_linecu (line));
607       if (show_flags)
608 	{
609 	  Dwarf_Addr bias;
610 	  Dwarf_Line *info = dwfl_dwarf_line (line, &bias);
611 	  assert (info != NULL);
612 
613 	  inline void show (int (*get) (Dwarf_Line *, bool *),
614 			    const char *note)
615 	  {
616 	    bool flag;
617 	    if ((*get) (info, &flag) == 0 && flag)
618 	      fputs (note, stdout);
619 	  }
620 	  inline void show_int (int (*get) (Dwarf_Line *, unsigned int *),
621 				const char *name)
622 	  {
623 	    unsigned int val;
624 	    if ((*get) (info, &val) == 0 && val != 0)
625 	      printf (" (%s %u)", name, val);
626 	  }
627 
628 	  show (&dwarf_linebeginstatement, " (is_stmt)");
629 	  show (&dwarf_lineblock, " (basic_block)");
630 	  show (&dwarf_lineprologueend, " (prologue_end)");
631 	  show (&dwarf_lineepiloguebegin, " (epilogue_begin)");
632 	  show_int (&dwarf_lineisa, "isa");
633 	  show_int (&dwarf_linediscriminator, "discriminator");
634 	}
635       putchar ('\n');
636     }
637   else
638     puts ("??:0");
639 
640   if (show_inlines)
641     {
642       Dwarf_Addr bias = 0;
643       Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias);
644 
645       Dwarf_Die *scopes = NULL;
646       int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes);
647       if (nscopes < 0)
648 	return 1;
649 
650       if (nscopes > 0)
651 	{
652 	  Dwarf_Die subroutine;
653 	  Dwarf_Off dieoff = dwarf_dieoffset (&scopes[0]);
654 	  dwarf_offdie (dwfl_module_getdwarf (mod, &bias),
655 			dieoff, &subroutine);
656 	  free (scopes);
657 
658 	  nscopes = dwarf_getscopes_die (&subroutine, &scopes);
659 	  if (nscopes > 1)
660 	    {
661 	      Dwarf_Die cu;
662 	      Dwarf_Files *files;
663 	      if (dwarf_diecu (&scopes[0], &cu, NULL, NULL) != NULL
664 		  && dwarf_getsrcfiles (cudie, &files, NULL) == 0)
665 		{
666 		  for (int i = 0; i < nscopes - 1; i++)
667 		    {
668 		      Dwarf_Word val;
669 		      Dwarf_Attribute attr;
670 		      Dwarf_Die *die = &scopes[i];
671 		      if (dwarf_tag (die) != DW_TAG_inlined_subroutine)
672 			continue;
673 
674 		      if (show_functions)
675 			{
676 			  /* Search for the parent inline or function.  It
677 			     might not be directly above this inline -- e.g.
678 			     there could be a lexical_block in between.  */
679 			  for (int j = i + 1; j < nscopes; j++)
680 			    {
681 			      Dwarf_Die *parent = &scopes[j];
682 			      int tag = dwarf_tag (parent);
683 			      if (tag == DW_TAG_inlined_subroutine
684 				  || tag == DW_TAG_entry_point
685 				  || tag == DW_TAG_subprogram)
686 				{
687 				  puts (get_diename (parent));
688 				  break;
689 				}
690 			    }
691 			}
692 
693 		      src = NULL;
694 		      lineno = 0;
695 		      linecol = 0;
696 		      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file,
697 						       &attr), &val) == 0)
698 			src = dwarf_filesrc (files, val, NULL, NULL);
699 
700 		      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line,
701 						       &attr), &val) == 0)
702 			lineno = val;
703 
704 		      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column,
705 						       &attr), &val) == 0)
706 			linecol = val;
707 
708 		      if (src != NULL)
709 			{
710 			  print_src (src, lineno, linecol, &cu);
711 			  putchar ('\n');
712 			}
713 		      else
714 			puts ("??:0");
715 		    }
716 		}
717 	    }
718 	}
719       free (scopes);
720     }
721 
722   return 0;
723 }
724 
725 
726 #include "debugpred.h"
727