• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2005 Red Hat, Inc.
2    This file is part of Red Hat elfutils.
3 
4    Red Hat elfutils is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by the
6    Free Software Foundation; version 2 of the License.
7 
8    Red Hat elfutils is distributed in the hope that it will be useful, but
9    WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11    General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License along
14    with Red Hat elfutils; if not, write to the Free Software Foundation,
15    Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
16 
17    Red Hat elfutils is an included package of the Open Invention Network.
18    An included package of the Open Invention Network is a package for which
19    Open Invention Network licensees cross-license their patents.  No patent
20    license is granted, either expressly or impliedly, by designation as an
21    included package.  Should you wish to participate in the Open Invention
22    Network licensing program, please visit www.openinventionnetwork.com
23    <http://www.openinventionnetwork.com>.  */
24 
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include <inttypes.h>
30 #include <assert.h>
31 #include ELFUTILS_HEADER(dwfl)
32 #include <argp.h>
33 #include <stdio.h>
34 #include <locale.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <error.h>
38 
39 
40 static void
print_address(Dwfl_Module * mod,Dwarf_Addr address)41 print_address (Dwfl_Module *mod, Dwarf_Addr address)
42 {
43   int n = dwfl_module_relocations (mod);
44   if (n < 0)
45     error (0, 0, "dwfl_module_relocations: %s", dwfl_errmsg (-1));
46   else if (n > 0)
47     {
48       int i = dwfl_module_relocate_address (mod, &address);
49       if (i < 0)
50 	error (0, 0, "dwfl_module_relocate_address: %s", dwfl_errmsg (-1));
51       else
52 	{
53 	  const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
54 						  NULL, NULL, NULL, NULL);
55 	  const char *secname = dwfl_module_relocation_info (mod, i, NULL);
56 	  if (n > 1 || secname[0] != '\0')
57 	    printf ("%s(%s)+%#" PRIx64, modname, secname, address);
58 	  else
59 	    printf ("%s+%#" PRIx64, modname, address);
60 	  return;
61 	}
62     }
63 
64   printf ("%#" PRIx64, address);
65 }
66 
67 
68 struct args
69 {
70   const char *arg;
71   char *file;
72   int line;
73 };
74 
75 static int
handle_module(Dwfl_Module * mod,void ** udata,const char * modname,Dwarf_Addr base,Dwarf * dbg,Dwarf_Addr bias,void * arg)76 handle_module (Dwfl_Module *mod __attribute__ ((unused)),
77 	       void **udata __attribute__ ((unused)),
78 	       const char *modname, Dwarf_Addr base __attribute__ ((unused)),
79 	       Dwarf *dbg __attribute__ ((unused)),
80 	       Dwarf_Addr bias __attribute__ ((unused)), void *arg)
81 {
82   const struct args *const a = arg;
83 
84   Dwfl_Line **lines = NULL;
85   size_t nlines = 0;
86 
87   if (dwfl_module_getsrc_file (mod, a->file, a->line, 0, &lines, &nlines) == 0)
88     {
89       for (size_t inner = 0; inner < nlines; ++inner)
90 	{
91 	  Dwarf_Addr addr;
92 	  int line = a->line, col = 0;
93 	  const char *file = dwfl_lineinfo (lines[inner], &addr, &line, &col,
94 					    NULL, NULL);
95 	  if (file != NULL)
96 	    {
97 	      printf ("%s -> ", a->arg);
98 	      print_address (mod, addr);
99 	      if (modname[0] != '\0')
100 		printf (" (%s:", modname);
101 	      if (strcmp (file, a->file) || line != a->line || col != 0)
102 		printf (" %s%s:%d", modname[0] != '\0' ? "" : "(",
103 			file, line);
104 	      if (col != 0)
105 		printf (":%d", col);
106 	      if (modname[0] != '\0'
107 		  || strcmp (file, a->file) || line != a->line || col != 0)
108 		puts (")");
109 	      else
110 		puts ("");
111 	    }
112 	}
113       free (lines);
114     }
115 
116   return DWARF_CB_OK;
117 }
118 
119 int
main(int argc,char * argv[])120 main (int argc, char *argv[])
121 {
122   int cnt;
123 
124   /* Set locale.  */
125   (void) setlocale (LC_ALL, "");
126 
127   Dwfl *dwfl = NULL;
128   (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &cnt, &dwfl);
129   assert (dwfl != NULL);
130 
131   for (; cnt < argc; ++cnt)
132     {
133       struct args a = { .arg = argv[cnt] };
134 
135       switch (sscanf (a.arg, "%m[^:]:%d", &a.file, &a.line))
136 	{
137 	default:
138 	case 0:
139 	  printf ("ignored %s\n", argv[cnt]);
140 	  continue;
141 	case 1:
142 	  a.line = 0;
143 	  break;
144 	case 2:
145 	  break;
146 	}
147 
148       (void) dwfl_getdwarf (dwfl, &handle_module, &a, 0);
149 
150       free (a.file);
151     }
152 
153   dwfl_end (dwfl);
154 
155   return 0;
156 }
157