Home | History | Annotate | Download | only in tests
      1 /* Copyright (C) 1998-2002, 2004, 2006, 2012, 2015 Red Hat, Inc.
      2    This file is part of elfutils.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      4 
      5    This file is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation; either version 3 of the License, or
      8    (at your option) any later version.
      9 
     10    elfutils is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     17 
     18 #include <config.h>
     19 
     20 #include <dwarf.h>
     21 #include <inttypes.h>
     22 #include <libelf.h>
     23 #include ELFUTILS_HEADER(dw)
     24 #include <fcntl.h>
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <unistd.h>
     28 
     29 #include "../libdw/known-dwarf.h"
     30 
     31 static const char *
     32 dwarf_tag_string (unsigned int tag)
     33 {
     34   switch (tag)
     35     {
     36 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
     37       DWARF_ALL_KNOWN_DW_TAG
     38 #undef DWARF_ONE_KNOWN_DW_TAG
     39     default:
     40       return NULL;
     41     }
     42 }
     43 
     44 static const char *
     45 dwarf_attr_string (unsigned int attrnum)
     46 {
     47   switch (attrnum)
     48     {
     49 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
     50       DWARF_ALL_KNOWN_DW_AT
     51 #undef DWARF_ONE_KNOWN_DW_AT
     52     default:
     53       return NULL;
     54     }
     55 }
     56 
     57 
     58 void
     59 handle (Dwarf *dbg, Dwarf_Die *die, int n)
     60 {
     61   Dwarf_Die child;
     62   unsigned int tag;
     63   const char *str;
     64   char buf[30];
     65   const char *name;
     66   Dwarf_Off off;
     67   Dwarf_Off cuoff;
     68   size_t cnt;
     69   Dwarf_Addr addr;
     70   int i;
     71 
     72   tag = dwarf_tag (die);
     73   if (tag != DW_TAG_invalid)
     74     {
     75       str = dwarf_tag_string (tag);
     76       if (str == NULL)
     77 	{
     78 	  snprintf (buf, sizeof buf, "%#x", tag);
     79 	  str = buf;
     80 	}
     81     }
     82   else
     83     str = "* NO TAG *";
     84 
     85   name = dwarf_diename (die);
     86   if (name == 0)
     87     name = "* NO NAME *";
     88 
     89   off = dwarf_dieoffset (die);
     90   cuoff = dwarf_cuoffset (die);
     91 
     92   printf ("%*sDW_TAG_%s\n", n * 5, "", str);
     93   printf ("%*s Name      : %s\n", n * 5, "", name);
     94   printf ("%*s Offset    : %lld\n", n * 5, "", (long long int) off);
     95   printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff);
     96 
     97   printf ("%*s Attrs     :", n * 5, "");
     98   for (cnt = 0; cnt < 0xffff; ++cnt)
     99     if (dwarf_hasattr (die, cnt))
    100       printf (" %s", dwarf_attr_string (cnt));
    101   puts ("");
    102 
    103   if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0)
    104     {
    105       Dwarf_Attribute attr;
    106       Dwarf_Addr addr2;
    107       printf ("%*s low PC    : %#llx\n",
    108 	      n * 5, "", (unsigned long long int) addr);
    109 
    110       if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL
    111 	  || dwarf_formaddr (&attr, &addr2) != 0
    112 	  || addr != addr2)
    113 	puts ("************* DW_AT_low_pc verify failed ************");
    114       else if (! dwarf_hasform (&attr, DW_FORM_addr))
    115 	puts ("************* DW_AT_low_pc form failed ************");
    116       else if (dwarf_whatform (&attr) != DW_FORM_addr)
    117 	puts ("************* DW_AT_low_pc form (2) failed ************");
    118       else if (dwarf_whatattr (&attr) != DW_AT_low_pc)
    119 	puts ("************* DW_AT_low_pc attr failed ************");
    120     }
    121   if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0)
    122     {
    123       Dwarf_Attribute attr;
    124       Dwarf_Addr addr2;
    125       printf ("%*s high PC   : %#llx\n",
    126 	      n * 5, "", (unsigned long long int) addr);
    127       if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL
    128 	  || dwarf_formaddr (&attr, &addr2) != 0
    129 	  || addr != addr2)
    130 	puts ("************* DW_AT_high_pc verify failed ************");
    131       else if (! dwarf_hasform (&attr, DW_FORM_addr))
    132 	puts ("************* DW_AT_high_pc form failed ************");
    133       else if (dwarf_whatform (&attr) != DW_FORM_addr)
    134 	puts ("************* DW_AT_high_pc form (2) failed ************");
    135       else if (dwarf_whatattr (&attr) != DW_AT_high_pc)
    136 	puts ("************* DW_AT_high_pc attr failed ************");
    137     }
    138 
    139   if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1)
    140     {
    141       Dwarf_Attribute attr;
    142       Dwarf_Word u2;
    143       unsigned int u;
    144       printf ("%*s byte size : %d\n", n * 5, "", i);
    145       if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL
    146 	  || dwarf_formudata (&attr, &u2) != 0
    147 	  || i != (int) u2)
    148 	puts ("************* DW_AT_byte_size verify failed ************");
    149       else if (! dwarf_hasform (&attr, DW_FORM_data1)
    150 	       && ! dwarf_hasform (&attr, DW_FORM_data2)
    151 	       && ! dwarf_hasform (&attr, DW_FORM_data4)
    152 	       && ! dwarf_hasform (&attr, DW_FORM_data8)
    153 	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
    154 	       && ! dwarf_hasform (&attr, DW_FORM_udata))
    155 	puts ("************* DW_AT_byte_size form failed ************");
    156       else if ((u = dwarf_whatform (&attr)) == 0
    157 	       || (u != DW_FORM_data1
    158 		   && u != DW_FORM_data2
    159 		   && u != DW_FORM_data4
    160 		   && u != DW_FORM_data8
    161 		   && u != DW_FORM_sdata
    162 		   && u != DW_FORM_udata))
    163 	puts ("************* DW_AT_byte_size form (2) failed ************");
    164       else if (dwarf_whatattr (&attr) != DW_AT_byte_size)
    165 	puts ("************* DW_AT_byte_size attr failed ************");
    166     }
    167   if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1)
    168     {
    169       Dwarf_Attribute attr;
    170       Dwarf_Word u2;
    171       unsigned int u;
    172       printf ("%*s bit size  : %d\n", n * 5, "", i);
    173       if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL
    174 	  || dwarf_formudata (&attr, &u2) != 0
    175 	  || i != (int) u2)
    176 	puts ("************* DW_AT_bit_size test failed ************");
    177       else if (! dwarf_hasform (&attr, DW_FORM_data1)
    178 	       && ! dwarf_hasform (&attr, DW_FORM_data2)
    179 	       && ! dwarf_hasform (&attr, DW_FORM_data4)
    180 	       && ! dwarf_hasform (&attr, DW_FORM_data8)
    181 	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
    182 	       && ! dwarf_hasform (&attr, DW_FORM_udata))
    183 	puts ("************* DW_AT_bit_size form failed ************");
    184       else if ((u = dwarf_whatform (&attr)) == 0
    185 	       || (u != DW_FORM_data1
    186 		   && u != DW_FORM_data2
    187 		   && u != DW_FORM_data4
    188 		   && u != DW_FORM_data8
    189 		   && u != DW_FORM_sdata
    190 		   && u != DW_FORM_udata))
    191 	puts ("************* DW_AT_bit_size form (2) failed ************");
    192       else if (dwarf_whatattr (&attr) != DW_AT_bit_size)
    193 	puts ("************* DW_AT_bit_size attr failed ************");
    194     }
    195   if (dwarf_hasattr (die, DW_AT_bit_offset)
    196       && (i = dwarf_bitoffset (die)) != -1)
    197     {
    198       Dwarf_Attribute attr;
    199       Dwarf_Word u2;
    200       unsigned int u;
    201       printf ("%*s bit offset: %d\n", n * 5, "", i);
    202       if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL
    203 	  || dwarf_formudata (&attr, &u2) != 0
    204 	  || i != (int) u2)
    205 	puts ("************* DW_AT_bit_offset test failed ************");
    206       else if (! dwarf_hasform (&attr, DW_FORM_data1)
    207 	       && ! dwarf_hasform (&attr, DW_FORM_data2)
    208 	       && ! dwarf_hasform (&attr, DW_FORM_data4)
    209 	       && ! dwarf_hasform (&attr, DW_FORM_data8)
    210 	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
    211 	       && ! dwarf_hasform (&attr, DW_FORM_udata))
    212 	puts ("************* DW_AT_bit_offset form failed ************");
    213       else if ((u = dwarf_whatform (&attr)) == 0
    214 	       || (u != DW_FORM_data1
    215 		   && u != DW_FORM_data2
    216 		   && u != DW_FORM_data4
    217 		   && u != DW_FORM_data8
    218 		   && u != DW_FORM_sdata
    219 		   && u != DW_FORM_udata))
    220 	puts ("************* DW_AT_bit_offset form (2) failed ************");
    221       else if (dwarf_whatattr (&attr) != DW_AT_bit_offset)
    222 	puts ("************* DW_AT_bit_offset attr failed ************");
    223     }
    224 
    225   if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1)
    226     {
    227       Dwarf_Attribute attr;
    228       Dwarf_Word u2;
    229       unsigned int u;
    230       printf ("%*s language  : %d\n", n * 5, "", i);
    231       if (dwarf_attr (die, DW_AT_language, &attr) == NULL
    232 	  || dwarf_formudata (&attr, &u2) != 0
    233 	  || i != (int) u2)
    234 	puts ("************* DW_AT_language test failed ************");
    235       else if (! dwarf_hasform (&attr, DW_FORM_data1)
    236 	       && ! dwarf_hasform (&attr, DW_FORM_data2)
    237 	       && ! dwarf_hasform (&attr, DW_FORM_data4)
    238 	       && ! dwarf_hasform (&attr, DW_FORM_data8)
    239 	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
    240 	       && ! dwarf_hasform (&attr, DW_FORM_udata))
    241 	puts ("************* DW_AT_language form failed ************");
    242       else if ((u = dwarf_whatform (&attr)) == 0
    243 	       || (u != DW_FORM_data1
    244 		   && u != DW_FORM_data2
    245 		   && u != DW_FORM_data4
    246 		   && u != DW_FORM_data8
    247 		   && u != DW_FORM_sdata
    248 		   && u != DW_FORM_udata))
    249 	puts ("************* DW_AT_language form (2) failed ************");
    250       else if (dwarf_whatattr (&attr) != DW_AT_language)
    251 	puts ("************* DW_AT_language attr failed ************");
    252     }
    253 
    254   if (dwarf_hasattr (die, DW_AT_ordering)
    255       && (i = dwarf_arrayorder (die)) != -1)
    256     {
    257       Dwarf_Attribute attr;
    258       Dwarf_Word u2;
    259       unsigned int u;
    260       printf ("%*s ordering  : %d\n", n * 5, "", i);
    261       if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL
    262 	  || dwarf_formudata (&attr, &u2) != 0
    263 	  || i != (int) u2)
    264 	puts ("************* DW_AT_ordering test failed ************");
    265       else if (! dwarf_hasform (&attr, DW_FORM_data1)
    266 	       && ! dwarf_hasform (&attr, DW_FORM_data2)
    267 	       && ! dwarf_hasform (&attr, DW_FORM_data4)
    268 	       && ! dwarf_hasform (&attr, DW_FORM_data8)
    269 	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
    270 	       && ! dwarf_hasform (&attr, DW_FORM_udata))
    271 	puts ("************* DW_AT_ordering failed ************");
    272       else if ((u = dwarf_whatform (&attr)) == 0
    273 	       || (u != DW_FORM_data1
    274 		   && u != DW_FORM_data2
    275 		   && u != DW_FORM_data4
    276 		   && u != DW_FORM_data8
    277 		   && u != DW_FORM_sdata
    278 		   && u != DW_FORM_udata))
    279 	puts ("************* DW_AT_ordering form (2) failed ************");
    280       else if (dwarf_whatattr (&attr) != DW_AT_ordering)
    281 	puts ("************* DW_AT_ordering attr failed ************");
    282     }
    283 
    284   if (dwarf_hasattr (die, DW_AT_comp_dir))
    285     {
    286       Dwarf_Attribute attr;
    287       if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL
    288 	  || (name = dwarf_formstring (&attr)) == NULL)
    289 	puts ("************* DW_AT_comp_dir attr failed ************");
    290       else
    291 	printf ("%*s directory : %s\n", n * 5, "", name);
    292     }
    293 
    294   if (dwarf_hasattr (die, DW_AT_producer))
    295     {
    296       Dwarf_Attribute attr;
    297       if (dwarf_attr (die, DW_AT_producer, &attr) == NULL
    298 	  || (name = dwarf_formstring (&attr)) == NULL)
    299 	puts ("************* DW_AT_comp_dir attr failed ************");
    300       else
    301 	printf ("%*s producer  : %s\n", n * 5, "", name);
    302     }
    303 
    304   if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0)
    305     handle (dbg, &child, n + 1);
    306   if (dwarf_siblingof (die, die) == 0)
    307     handle (dbg, die, n);
    308 }
    309 
    310 
    311 int
    312 main (int argc, char *argv[])
    313 {
    314  int cnt;
    315 
    316   for (cnt = 1; cnt < argc; ++cnt)
    317     {
    318       int fd = open (argv[cnt], O_RDONLY);
    319       Dwarf *dbg;
    320 
    321       printf ("file: %s\n", basename (argv[cnt]));
    322 
    323       dbg = dwarf_begin (fd, DWARF_C_READ);
    324       if (dbg == NULL)
    325 	{
    326 	  printf ("%s not usable\n", argv[cnt]);
    327 	  close (fd);
    328 	  continue;
    329 	}
    330 
    331       Dwarf_Off off = 0;
    332       Dwarf_Off old_off = 0;
    333       size_t hsize;
    334       Dwarf_Off abbrev;
    335       uint8_t addresssize;
    336       uint8_t offsetsize;
    337       while (dwarf_nextcu (dbg, off, &off, &hsize, &abbrev, &addresssize,
    338 			   &offsetsize) == 0)
    339 	{
    340 	  printf ("New CU: off = %llu, hsize = %zu, ab = %llu, as = %" PRIu8
    341 		  ", os = %" PRIu8 "\n",
    342 		  (unsigned long long int) old_off, hsize,
    343 		  (unsigned long long int) abbrev, addresssize,
    344 		  offsetsize);
    345 
    346 	  Dwarf_Die die;
    347 	  if (dwarf_offdie (dbg, old_off + hsize, &die) != NULL)
    348 	    handle (dbg, &die, 1);
    349 
    350 	  old_off = off;
    351 	}
    352 
    353       dwarf_end (dbg);
    354       close (fd);
    355     }
    356 
    357   return 0;
    358 }
    359