• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2005, 2006 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 <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <error.h>
33 #include <locale.h>
34 #include <argp.h>
35 #include <assert.h>
36 #include ELFUTILS_HEADER(dwfl)
37 #include <dwarf.h>
38 
39 
40 static const char *
dwarf_encoding_string(unsigned int code)41 dwarf_encoding_string (unsigned int code)
42 {
43   static const char *known[] =
44     {
45       [DW_ATE_void] = "void",
46       [DW_ATE_address] = "address",
47       [DW_ATE_boolean] = "boolean",
48       [DW_ATE_complex_float] = "complex_float",
49       [DW_ATE_float] = "float",
50       [DW_ATE_signed] = "signed",
51       [DW_ATE_signed_char] = "signed_char",
52       [DW_ATE_unsigned] = "unsigned",
53       [DW_ATE_unsigned_char] = "unsigned_char",
54       [DW_ATE_imaginary_float] = "imaginary_float",
55       [DW_ATE_packed_decimal] = "packed_decimal",
56       [DW_ATE_numeric_string] = "numeric_string",
57       [DW_ATE_edited] = "edited",
58       [DW_ATE_signed_fixed] = "signed_fixed",
59       [DW_ATE_unsigned_fixed] = "unsigned_fixed",
60       [DW_ATE_decimal_float] = "decimal_float",
61     };
62 
63   if (code < sizeof (known) / sizeof (known[0]))
64     return known[code];
65 
66   if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user)
67     {
68       static char buf[30];
69       snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user);
70       return buf;
71     }
72 
73   return "???";
74 }
75 
76 static int
first_module(Dwfl_Module * mod,void ** userdatap,const char * name,Dwarf_Addr low_addr,void * arg)77 first_module (Dwfl_Module *mod,
78 	      void **userdatap __attribute__ ((unused)),
79 	      const char *name __attribute__ ((unused)),
80 	      Dwarf_Addr low_addr __attribute__ ((unused)),
81 	      void *arg)
82 {
83   Dwarf_Addr bias;
84   if (dwfl_module_getelf (mod, &bias) == NULL) /* Not really a module.  */
85     return DWARF_CB_OK;
86 
87   *(Dwfl_Module **) arg = mod;
88   return DWARF_CB_ABORT;
89 }
90 
91 
92 struct state
93 {
94   struct reginfo *info;
95   int nregs;
96 };
97 
98 struct reginfo
99 {
100   const char *set, *pfx;
101   int regno;
102   int bits;
103   int type;
104   char name[32];
105 };
106 
107 static int
compare(const void * r1,const void * r2)108 compare (const void *r1, const void *r2)
109 {
110   const struct reginfo *a = r1, *b = r2;
111   if (a->set == b->set)
112     return a->regno - b->regno;
113   if (a->set == NULL)
114     return 1;
115   if (b->set == NULL)
116     return -1;
117   if (!strcmp (a->set, "integer"))
118     return -1;
119   if (!strcmp (b->set, "integer"))
120     return 1;
121   return strcmp (a->set, b->set);
122 }
123 
124 static int
one_register(void * arg,int regno,const char * setname,const char * prefix,const char * regname,int bits,int type)125 one_register (void *arg,
126 	      int regno,
127 	      const char *setname,
128 	      const char *prefix,
129 	      const char *regname,
130 	      int bits, int type)
131 {
132   struct state *state = arg;
133 
134   if (regno >= state->nregs)
135     {
136       state->info = realloc (state->info, (regno + 1) * sizeof state->info[0]);
137       memset (&state->info[state->nregs], 0,
138 	      ((void *) &state->info[regno + 1]
139 	       - (void *) &state->info[state->nregs]));
140       state->nregs = regno + 1;
141     }
142 
143   state->info[regno].regno = regno;
144   state->info[regno].set = setname;
145   state->info[regno].pfx = prefix;
146   state->info[regno].bits = bits;
147   state->info[regno].type = type;
148   assert (strlen (regname) < sizeof state->info[regno].name);
149   strcpy (state->info[regno].name, regname);
150 
151   return DWARF_CB_OK;
152 }
153 
154 
155 static int
match_register(void * arg,int regno,const char * setname,const char * prefix,const char * regname,int bits,int type)156 match_register (void *arg,
157 		int regno,
158 		const char *setname,
159 		const char *prefix,
160 		const char *regname,
161 		int bits, int type)
162 {
163   if (regno == *(int *) arg)
164     printf ("%5d => %s register %s%s %s %d bits\n",
165 	    regno, setname, prefix, regname,
166 	    dwarf_encoding_string (type), bits);
167 
168   return DWARF_CB_ABORT;
169 }
170 
171 
172 int
main(int argc,char ** argv)173 main (int argc, char **argv)
174 {
175   int remaining;
176 
177   /* Set locale.  */
178   (void) setlocale (LC_ALL, "");
179 
180   Dwfl *dwfl = NULL;
181   (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
182   assert (dwfl != NULL);
183 
184   Dwfl_Module *mod = NULL;
185   if (dwfl_getmodules (dwfl, &first_module, &mod, 0) < 0)
186     error (EXIT_FAILURE, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
187 
188   if (remaining == argc)
189     {
190       struct state state = { NULL, 0 };
191       int result = dwfl_module_register_names (mod, &one_register, &state);
192       if (result != 0 || state.nregs == 0)
193 	error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s",
194 	       result ? dwfl_errmsg (-1) : "no backend registers known");
195 
196       qsort (state.info, state.nregs, sizeof state.info[0], &compare);
197 
198       const char *set = NULL;
199       for (int i = 0; i < state.nregs; ++i)
200 	if (state.info[i].set != NULL)
201 	  {
202 	    if (set != state.info[i].set)
203 	      printf ("%s registers:\n", state.info[i].set);
204 	    set = state.info[i].set;
205 
206 	    printf ("\t%3d: %s%s (%s), %s %d bits\n",
207 		    state.info[i].regno,
208 		    state.info[i].pfx ?: "", state.info[i].name,
209 		    state.info[i].name,
210 		    dwarf_encoding_string (state.info[i].type),
211 		    state.info[i].bits);
212 	  }
213     }
214   else
215     do
216       {
217 	const char *arg = argv[remaining++];
218 	int regno = atoi (arg);
219 	int result = dwfl_module_register_names (mod, &match_register, &regno);
220 	if (result != DWARF_CB_ABORT)
221 	  error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s",
222 		 result ? dwfl_errmsg (-1) : "no backend registers known");
223       }
224     while (remaining < argc);
225 
226   dwfl_end (dwfl);
227 
228   return 0;
229 }
230