blob: 286f7e3cd0a2c56fa95b998501b54131a015aba1 [file] [log] [blame]
Petr Machata7f617342015-03-18 19:42:02 +01001/* Copyright (C) 2005, 2006, 2015 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02002 This file is part of elfutils.
Roland McGrath994b4892005-12-05 22:46:21 +00003
Mark Wielaardde2ed972012-06-05 17:15:16 +02004 This file is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
Roland McGrath994b4892005-12-05 22:46:21 +00008
Mark Wielaardde2ed972012-06-05 17:15:16 +02009 elfutils is distributed in the hope that it will be useful, but
Ulrich Drepper361df7d2006-04-04 21:38:57 +000010 WITHOUT ANY WARRANTY; without even the implied warranty of
Mark Wielaardde2ed972012-06-05 17:15:16 +020011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
Ulrich Drepper361df7d2006-04-04 21:38:57 +000013
Mark Wielaardde2ed972012-06-05 17:15:16 +020014 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
Roland McGrath994b4892005-12-05 22:46:21 +000016
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <error.h>
25#include <locale.h>
26#include <argp.h>
27#include <assert.h>
28#include ELFUTILS_HEADER(dwfl)
Roland McGrathc373d852006-10-10 00:25:21 +000029#include <dwarf.h>
Roland McGrath994b4892005-12-05 22:46:21 +000030
Mark Wielaardf31c4412012-08-17 00:35:03 +020031#include "../libdw/known-dwarf.h"
Roland McGrath994b4892005-12-05 22:46:21 +000032
Roland McGrathc373d852006-10-10 00:25:21 +000033static const char *
34dwarf_encoding_string (unsigned int code)
35{
Mark Wielaardf31c4412012-08-17 00:35:03 +020036 static const char *const known[] =
Roland McGrathc373d852006-10-10 00:25:21 +000037 {
Petr Machata7f617342015-03-18 19:42:02 +010038#define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
39 DWARF_ALL_KNOWN_DW_ATE
40#undef DWARF_ONE_KNOWN_DW_ATE
Roland McGrathc373d852006-10-10 00:25:21 +000041 };
42
Mark Wielaardf31c4412012-08-17 00:35:03 +020043 if (likely (code < sizeof (known) / sizeof (known[0])))
Roland McGrathc373d852006-10-10 00:25:21 +000044 return known[code];
45
Mark Wielaardf31c4412012-08-17 00:35:03 +020046 return NULL;
Roland McGrathc373d852006-10-10 00:25:21 +000047}
48
Mark Wielaardf31c4412012-08-17 00:35:03 +020049
Roland McGrath994b4892005-12-05 22:46:21 +000050static int
51first_module (Dwfl_Module *mod,
52 void **userdatap __attribute__ ((unused)),
53 const char *name __attribute__ ((unused)),
54 Dwarf_Addr low_addr __attribute__ ((unused)),
55 void *arg)
56{
57 Dwarf_Addr bias;
58 if (dwfl_module_getelf (mod, &bias) == NULL) /* Not really a module. */
59 return DWARF_CB_OK;
60
61 *(Dwfl_Module **) arg = mod;
62 return DWARF_CB_ABORT;
63}
64
65
66struct state
67{
68 struct reginfo *info;
69 int nregs;
70};
71
72struct reginfo
73{
74 const char *set, *pfx;
75 int regno;
Roland McGrathc373d852006-10-10 00:25:21 +000076 int bits;
77 int type;
Roland McGrath95024622006-07-21 10:06:31 +000078 char name[32];
Roland McGrath994b4892005-12-05 22:46:21 +000079};
80
81static int
82compare (const void *r1, const void *r2)
83{
84 const struct reginfo *a = r1, *b = r2;
85 if (a->set == b->set)
86 return a->regno - b->regno;
87 if (a->set == NULL)
88 return 1;
89 if (b->set == NULL)
90 return -1;
91 if (!strcmp (a->set, "integer"))
92 return -1;
93 if (!strcmp (b->set, "integer"))
94 return 1;
95 return strcmp (a->set, b->set);
96}
97
98static int
99one_register (void *arg,
100 int regno,
101 const char *setname,
102 const char *prefix,
Roland McGrathc373d852006-10-10 00:25:21 +0000103 const char *regname,
104 int bits, int type)
Roland McGrath994b4892005-12-05 22:46:21 +0000105{
106 struct state *state = arg;
107
108 if (regno >= state->nregs)
109 {
110 state->info = realloc (state->info, (regno + 1) * sizeof state->info[0]);
111 memset (&state->info[state->nregs], 0,
112 ((void *) &state->info[regno + 1]
113 - (void *) &state->info[state->nregs]));
114 state->nregs = regno + 1;
115 }
116
117 state->info[regno].regno = regno;
118 state->info[regno].set = setname;
119 state->info[regno].pfx = prefix;
Roland McGrathc373d852006-10-10 00:25:21 +0000120 state->info[regno].bits = bits;
121 state->info[regno].type = type;
Roland McGrath95024622006-07-21 10:06:31 +0000122 assert (strlen (regname) < sizeof state->info[regno].name);
Roland McGrath994b4892005-12-05 22:46:21 +0000123 strcpy (state->info[regno].name, regname);
124
125 return DWARF_CB_OK;
126}
127
128
129static int
130match_register (void *arg,
131 int regno,
132 const char *setname,
133 const char *prefix,
Roland McGrathc373d852006-10-10 00:25:21 +0000134 const char *regname,
135 int bits, int type)
Roland McGrath994b4892005-12-05 22:46:21 +0000136{
137 if (regno == *(int *) arg)
Roland McGrathc373d852006-10-10 00:25:21 +0000138 printf ("%5d => %s register %s%s %s %d bits\n",
139 regno, setname, prefix, regname,
140 dwarf_encoding_string (type), bits);
Roland McGrath994b4892005-12-05 22:46:21 +0000141
Roland McGrath94d26ad2005-12-13 23:24:37 +0000142 return DWARF_CB_ABORT;
Roland McGrath994b4892005-12-05 22:46:21 +0000143}
144
145
146int
147main (int argc, char **argv)
148{
149 int remaining;
150
151 /* Set locale. */
152 (void) setlocale (LC_ALL, "");
153
154 Dwfl *dwfl = NULL;
155 (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
156 assert (dwfl != NULL);
157
158 Dwfl_Module *mod = NULL;
159 if (dwfl_getmodules (dwfl, &first_module, &mod, 0) < 0)
160 error (EXIT_FAILURE, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
161
162 if (remaining == argc)
163 {
164 struct state state = { NULL, 0 };
165 int result = dwfl_module_register_names (mod, &one_register, &state);
Roland McGrath94d26ad2005-12-13 23:24:37 +0000166 if (result != 0 || state.nregs == 0)
Roland McGrath994b4892005-12-05 22:46:21 +0000167 error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s",
Roland McGrath94d26ad2005-12-13 23:24:37 +0000168 result ? dwfl_errmsg (-1) : "no backend registers known");
Roland McGrath994b4892005-12-05 22:46:21 +0000169
170 qsort (state.info, state.nregs, sizeof state.info[0], &compare);
171
172 const char *set = NULL;
173 for (int i = 0; i < state.nregs; ++i)
174 if (state.info[i].set != NULL)
175 {
176 if (set != state.info[i].set)
177 printf ("%s registers:\n", state.info[i].set);
178 set = state.info[i].set;
179
Roland McGrathc373d852006-10-10 00:25:21 +0000180 printf ("\t%3d: %s%s (%s), %s %d bits\n",
181 state.info[i].regno,
Roland McGrath994b4892005-12-05 22:46:21 +0000182 state.info[i].pfx ?: "", state.info[i].name,
Roland McGrathc373d852006-10-10 00:25:21 +0000183 state.info[i].name,
184 dwarf_encoding_string (state.info[i].type),
185 state.info[i].bits);
Roland McGrath994b4892005-12-05 22:46:21 +0000186 }
Mark Wielaarda1372e02015-12-01 15:55:08 +0100187 free (state.info);
Roland McGrath994b4892005-12-05 22:46:21 +0000188 }
189 else
190 do
191 {
192 const char *arg = argv[remaining++];
193 int regno = atoi (arg);
194 int result = dwfl_module_register_names (mod, &match_register, &regno);
Roland McGrath94d26ad2005-12-13 23:24:37 +0000195 if (result != DWARF_CB_ABORT)
Roland McGrath994b4892005-12-05 22:46:21 +0000196 error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s",
Roland McGrath94d26ad2005-12-13 23:24:37 +0000197 result ? dwfl_errmsg (-1) : "no backend registers known");
Roland McGrath994b4892005-12-05 22:46:21 +0000198 }
199 while (remaining < argc);
200
201 dwfl_end (dwfl);
202
203 return 0;
204}