Home | History | Annotate | Download | only in tests
      1 /* Test dwarf_cu_info properties.
      2    Copyright (C) 2018 Red Hat, Inc.
      3    This file is part of elfutils.
      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 #ifdef HAVE_CONFIG_H
     19 # include <config.h>
     20 #endif
     21 
     22 #include <dwarf.h>
     23 #include ELFUTILS_HEADER(dw)
     24 #include <stdio.h>
     25 #include <inttypes.h>
     26 #include <sys/types.h>
     27 #include <sys/stat.h>
     28 #include <fcntl.h>
     29 #include <unistd.h>
     30 
     31 /* Yeah, lazy, 16K CUs should be enough for everybody... */
     32 #define MAX_UNITS 16384
     33 struct info
     34 {
     35   int dietag;
     36   int subtag;
     37   Dwarf_Half version;
     38   uint8_t unit_type;
     39   uint64_t id;
     40   uint8_t addr_size;
     41   uint8_t off_size;
     42 };
     43 static struct info unit_info[MAX_UNITS];
     44 
     45 int
     46 main (int argc, char *argv[])
     47 {
     48   for (int i = 1; i < argc; i++)
     49     {
     50       printf ("file: %s\n", argv[i]);
     51       int fd = open (argv[i], O_RDONLY);
     52       Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
     53       if (dbg == NULL)
     54 	{
     55 	  printf ("%s not usable: %s\n", argv[i], dwarf_errmsg (-1));
     56 	  return -1;
     57 	}
     58 
     59       Dwarf_CU *cu = NULL;
     60       Dwarf_Half version;
     61       Dwarf_Die cudie, subdie;
     62       uint8_t unit_type;
     63       size_t u, units;
     64       u = units = 0;
     65       printf ("Iterate getting all info, compare with dwarf_cu_info.\n");
     66       while (dwarf_get_units (dbg, cu, &cu, &version,
     67 			      &unit_type, &cudie, &subdie) == 0)
     68 	{
     69 	  int dietag = dwarf_tag (&cudie);
     70 	  int subtag = dwarf_tag (&subdie);
     71 
     72 	  unit_info[u].dietag = dietag;
     73 	  unit_info[u].subtag = subtag;
     74 	  unit_info[u].version = version;
     75 	  unit_info[u].unit_type = unit_type;
     76 
     77 	  printf ("%zu cu dietag: %x, subtag: %x, version %" PRIx32
     78 		  ", unit_type %" PRIx8 "\n",
     79 		  u, dietag, subtag, version, unit_type);
     80 
     81 	  uint64_t unit_id;
     82 	  uint8_t addr_size, off_size;
     83 	  if (dwarf_cu_info (cu,
     84 			     &version, &unit_type, &cudie, &subdie,
     85 			     &unit_id, &addr_size, &off_size) != 0)
     86 	    {
     87 	      printf ("Invalid dwarf_cu_info: %s\n", dwarf_errmsg (-1));
     88 	      return -1;
     89 	    }
     90 
     91 	  dietag = dwarf_tag (&cudie);
     92 	  subtag = dwarf_tag (&subdie);
     93 
     94 	  if (unit_info[u].dietag != dietag)
     95 	    {
     96 	      printf("Unequal dietags\n");
     97 	      return -1;
     98 	    }
     99 
    100 	  if (unit_info[u].subtag != subtag)
    101 	    {
    102 	      printf("Unequal subtags\n");
    103 	      return -1;
    104 	    }
    105 
    106 	  if (unit_info[u].version != version)
    107 	    {
    108 	      printf("Unequal versions\n");
    109 	      return -1;
    110 	    }
    111 
    112 	  if (unit_info[u].unit_type != unit_type)
    113 	    {
    114 	      printf("Unequal unit_types\n");
    115 	      return -1;
    116 	    }
    117 
    118 	  unit_info[u].id = unit_id;
    119 	  unit_info[u].addr_size = addr_size;
    120 	  unit_info[u].off_size = off_size;
    121 
    122 	  if (unit_type == DW_UT_skeleton)
    123 	    {
    124 	      if (dwarf_cu_info (subdie.cu,
    125 				 &version, &unit_type, &cudie, &subdie,
    126 				 &unit_id, &addr_size, &off_size) != 0)
    127 		{
    128 		  printf ("Invalid subdie dwarf_cu_info: %s\n",
    129 			  dwarf_errmsg (-1));
    130 		  return -1;
    131 		}
    132 
    133 	      dietag = dwarf_tag (&cudie);
    134 	      subtag = dwarf_tag (&subdie);
    135 
    136 	      printf ("%zu subdietag: %x, subtag: %x, version %" PRIx32
    137 		      ", unit_type %" PRIx8 "\n",
    138 		      u, dietag, subtag, version, unit_type);
    139 
    140 	      /* subdie is now cudie.  */
    141 	      if (unit_info[u].subtag != dietag)
    142 	      {
    143 		printf ("Inconsistent subdie tag\n");
    144 		return -1;
    145 	      }
    146 
    147 	      if (unit_info[u].id != unit_id)
    148 		{
    149 		  printf ("Unequal subdie ids\n");
    150 		  return -1;
    151 		}
    152 
    153 	      if (unit_info[u].addr_size != addr_size)
    154 		{
    155 		  printf ("Unequal subdie addr_size\n");
    156 		  return -1;
    157 		}
    158 
    159 	      if (unit_info[u].off_size != off_size)
    160 		{
    161 		  printf ("Unequal subdie off_size\n");
    162 		  return -1;
    163 		}
    164 	    }
    165 
    166 	  if (u >= MAX_UNITS)
    167 	    {
    168 	      printf ("Oops, more than 16K units...\n");
    169 	      return -1;
    170 	    }
    171 	  u = ++units;
    172 	}
    173 
    174       dwarf_end (dbg);
    175       close (fd);
    176 
    177       /* And again... */
    178       printf ("rechecking: %s\n", argv[i]);
    179       fd = open (argv[i], O_RDONLY);
    180       dbg = dwarf_begin (fd, DWARF_C_READ);
    181       if (dbg == NULL)
    182 	{
    183 	  printf ("%s not usable: %s\n", argv[i], dwarf_errmsg (-1));
    184 	  return -1;
    185 	}
    186 
    187       cu = NULL;
    188       u = 0;
    189       printf ("Iterate no info, compare recorded info with dwarf_cu_info.\n");
    190       while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
    191 	{
    192 	  if (u > units)
    193 	    {
    194 	      printf ("Got too many units???\n");
    195 	      return -1;
    196 	    }
    197 
    198 	  uint64_t unit_id;
    199 	  uint8_t addr_size, off_size;
    200 	  if (dwarf_cu_info (cu,
    201 			     &version, &unit_type, &cudie, &subdie,
    202 			     &unit_id, &addr_size, &off_size) != 0)
    203 	    {
    204 	      printf ("Invalid dwarf_cu_info: %s\n", dwarf_errmsg (-1));
    205 	      return -1;
    206 	    }
    207 
    208 	  int dietag = dwarf_tag (&cudie);
    209 	  int subtag = dwarf_tag (&subdie);
    210 
    211 	  printf ("%zu re dietag: %x, subtag: %x, version %" PRIx32
    212 		  ", unit_type %" PRIx8 "\n",
    213 		  u, dietag, subtag, version, unit_type);
    214 
    215 	  if (unit_info[u].dietag != dietag)
    216 	    {
    217 	      printf("Unequal dietags %x != %x\n", unit_info[u].dietag, dietag);
    218 	      return -1;
    219 	    }
    220 
    221 	  if (unit_info[u].subtag != subtag)
    222 	    {
    223 	      printf("Unequal subtags\n");
    224 	      return -1;
    225 	    }
    226 
    227 	  if (unit_info[u].version != version)
    228 	    {
    229 	      printf("Unequal versions\n");
    230 	      return -1;
    231 	    }
    232 
    233 	  if (unit_info[u].unit_type != unit_type)
    234 	    {
    235 	      printf("Unequal unit_types\n");
    236 	      return -1;
    237 	    }
    238 
    239 	  if (unit_info[u].id != unit_id)
    240 	    {
    241 	      printf ("Unequal subdie ids\n");
    242 	      return -1;
    243 	    }
    244 
    245 	  if (unit_info[u].addr_size != addr_size)
    246 	    {
    247 	      printf ("Unequal subdie addr_size\n");
    248 	      return -1;
    249 	    }
    250 
    251 	  if (unit_info[u].off_size != off_size)
    252 	    {
    253 	      printf ("Unequal subdie off_size\n");
    254 	      return -1;
    255 	    }
    256 
    257 	  if (unit_type == DW_UT_skeleton)
    258 	    {
    259 	      if (dwarf_cu_info (subdie.cu,
    260 				 &version, &unit_type, &cudie, &subdie,
    261 				 &unit_id, &addr_size, &off_size) != 0)
    262 		{
    263 		  printf ("Invalid subdie dwarf_cu_info: %s\n",
    264 			  dwarf_errmsg (-1));
    265 		  return -1;
    266 		}
    267 
    268 	      dietag = dwarf_tag (&cudie);
    269 	      subtag = dwarf_tag (&subdie);
    270 
    271 	      printf ("%zu subdietag: %x, subtag: %x, version %" PRIx32
    272 		      ", unit_type %" PRIx8 "\n",
    273 		      u, dietag, subtag, version, unit_type);
    274 
    275 	      /* subdie is now cudie.  */
    276 	      subtag = dwarf_tag (&cudie);
    277 	      if (unit_info[u].subtag != subtag)
    278 	      {
    279 		printf ("Inconsistent subdie tag\n");
    280 		return -1;
    281 	      }
    282 
    283 	      if (unit_info[u].id != unit_id)
    284 		{
    285 		  printf ("Unequal subdie ids\n");
    286 		  return -1;
    287 		}
    288 
    289 	      if (unit_info[u].addr_size != addr_size)
    290 		{
    291 		  printf ("Unequal subdie addr_size\n");
    292 		  return -1;
    293 		}
    294 
    295 	      if (unit_info[u].off_size != off_size)
    296 		{
    297 		  printf ("Unequal subdie off_size\n");
    298 		  return -1;
    299 		}
    300 	    }
    301 
    302 	  if (u >= MAX_UNITS)
    303 	    {
    304 	      printf ("Oops, more than 16K units...\n");
    305 	      return -1;
    306 	    }
    307 	  u++;
    308 	}
    309 
    310       if (u != units)
    311 	{
    312 	  printf ("Got not enough units???\n");
    313 	  return -1;
    314 	}
    315 
    316       dwarf_end (dbg);
    317       close (fd);
    318 
    319       printf ("\n");
    320     }
    321 
    322   return 0;
    323 }
    324