Imported Upstream version 0.153
[platform/upstream/elfutils.git] / tests / allregs.c
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 *
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
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
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
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
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
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 }