Home | History | Annotate | Download | only in tests
      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 }
    230