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