xref: /third_party/elfutils/tests/unit-info.c (revision da0c48c4)
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
33struct 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};
43static struct info unit_info[MAX_UNITS];
44
45int
46main (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