ctf-types.c revision 1.1.1.1
1/* Type handling functions.
2   Copyright (C) 2019-2020 Free Software Foundation, Inc.
3
4   This file is part of libctf.
5
6   libctf is free software; you can redistribute it and/or modify it under
7   the terms of the GNU General Public License as published by the Free
8   Software Foundation; either version 3, or (at your option) any later
9   version.
10
11   This program is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   See the GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; see the file COPYING.  If not see
18   <http://www.gnu.org/licenses/>.  */
19
20#include <ctf-impl.h>
21#include <string.h>
22
23/* Determine whether a type is a parent or a child.  */
24
25int
26ctf_type_isparent (ctf_file_t *fp, ctf_id_t id)
27{
28  return (LCTF_TYPE_ISPARENT (fp, id));
29}
30
31int
32ctf_type_ischild (ctf_file_t * fp, ctf_id_t id)
33{
34  return (LCTF_TYPE_ISCHILD (fp, id));
35}
36
37/* Iterate over the members of a STRUCT or UNION.  We pass the name, member
38   type, and offset of each member to the specified callback function.  */
39
40int
41ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
42{
43  ctf_file_t *ofp = fp;
44  const ctf_type_t *tp;
45  ctf_dtdef_t *dtd;
46  ssize_t size, increment;
47  uint32_t kind, n;
48  int rc;
49
50  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
51    return -1;			/* errno is set for us.  */
52
53  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
54    return -1;			/* errno is set for us.  */
55
56  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
57  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
58
59  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
60    return (ctf_set_errno (ofp, ECTF_NOTSOU));
61
62  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
63    {
64      if (size < CTF_LSTRUCT_THRESH)
65	{
66	  const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
67							   increment);
68
69	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
70	    {
71	      const char *name = ctf_strptr (fp, mp->ctm_name);
72	      if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0)
73	    return rc;
74	    }
75	}
76      else
77	{
78	  const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
79							      increment);
80
81	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
82	    {
83	      const char *name = ctf_strptr (fp, lmp->ctlm_name);
84	      if ((rc = func (name, lmp->ctlm_type,
85			      (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0)
86		return rc;
87	    }
88	}
89    }
90  else
91    {
92      ctf_dmdef_t *dmd;
93
94      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
95	   dmd != NULL; dmd = ctf_list_next (dmd))
96	{
97	  if ((rc = func (dmd->dmd_name, dmd->dmd_type,
98			  dmd->dmd_offset, arg)) != 0)
99	    return rc;
100	}
101    }
102
103  return 0;
104}
105
106/* Iterate over the members of an ENUM.  We pass the string name and associated
107   integer value of each enum element to the specified callback function.  */
108
109int
110ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
111{
112  ctf_file_t *ofp = fp;
113  const ctf_type_t *tp;
114  const ctf_enum_t *ep;
115  ctf_dtdef_t *dtd;
116  ssize_t increment;
117  uint32_t n;
118  int rc;
119
120  if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
121    return -1;			/* errno is set for us.  */
122
123  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
124    return -1;			/* errno is set for us.  */
125
126  if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
127    return (ctf_set_errno (ofp, ECTF_NOTENUM));
128
129  (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
130
131  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
132    {
133      ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
134
135      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
136	{
137	  const char *name = ctf_strptr (fp, ep->cte_name);
138	  if ((rc = func (name, ep->cte_value, arg)) != 0)
139	    return rc;
140	}
141    }
142  else
143    {
144      ctf_dmdef_t *dmd;
145
146      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
147	   dmd != NULL; dmd = ctf_list_next (dmd))
148	{
149	  if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0)
150	    return rc;
151	}
152    }
153
154  return 0;
155}
156
157/* Iterate over every root (user-visible) type in the given CTF container.
158   We pass the type ID of each type to the specified callback function.  */
159
160int
161ctf_type_iter (ctf_file_t *fp, ctf_type_f *func, void *arg)
162{
163  ctf_id_t id, max = fp->ctf_typemax;
164  int rc, child = (fp->ctf_flags & LCTF_CHILD);
165
166  for (id = 1; id <= max; id++)
167    {
168      const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
169      if (LCTF_INFO_ISROOT (fp, tp->ctt_info)
170	  && (rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), arg)) != 0)
171	return rc;
172    }
173
174  return 0;
175}
176
177/* Iterate over every type in the given CTF container, user-visible or not.
178   We pass the type ID of each type to the specified callback function.  */
179
180int
181ctf_type_iter_all (ctf_file_t *fp, ctf_type_all_f *func, void *arg)
182{
183  ctf_id_t id, max = fp->ctf_typemax;
184  int rc, child = (fp->ctf_flags & LCTF_CHILD);
185
186  for (id = 1; id <= max; id++)
187    {
188      const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
189      if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child),
190		      LCTF_INFO_ISROOT(fp, tp->ctt_info)
191		      ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0))
192	return rc;
193    }
194
195  return 0;
196}
197
198/* Iterate over every variable in the given CTF container, in arbitrary order.
199   We pass the name of each variable to the specified callback function.  */
200
201int
202ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg)
203{
204  int rc;
205
206  if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
207    return ECTF_NOPARENT;
208
209  if (!(fp->ctf_flags & LCTF_RDWR))
210    {
211      unsigned long i;
212      for (i = 0; i < fp->ctf_nvars; i++)
213	if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
214			fp->ctf_vars[i].ctv_type, arg)) != 0)
215	  return rc;
216    }
217  else
218    {
219      ctf_dvdef_t *dvd;
220
221      for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
222	   dvd = ctf_list_next (dvd))
223	{
224	  if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
225	    return rc;
226	}
227    }
228
229  return 0;
230}
231
232/* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
233   RESTRICT nodes until we reach a "base" type node.  This is useful when
234   we want to follow a type ID to a node that has members or a size.  To guard
235   against infinite loops, we implement simplified cycle detection and check
236   each link against itself, the previous node, and the topmost node.
237
238   Does not drill down through slices to their contained type.  */
239
240ctf_id_t
241ctf_type_resolve (ctf_file_t *fp, ctf_id_t type)
242{
243  ctf_id_t prev = type, otype = type;
244  ctf_file_t *ofp = fp;
245  const ctf_type_t *tp;
246
247  if (type == 0)
248    return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
249
250  while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
251    {
252      switch (LCTF_INFO_KIND (fp, tp->ctt_info))
253	{
254	case CTF_K_TYPEDEF:
255	case CTF_K_VOLATILE:
256	case CTF_K_CONST:
257	case CTF_K_RESTRICT:
258	  if (tp->ctt_type == type || tp->ctt_type == otype
259	      || tp->ctt_type == prev)
260	    {
261	      ctf_dprintf ("type %ld cycle detected\n", otype);
262	      return (ctf_set_errno (ofp, ECTF_CORRUPT));
263	    }
264	  prev = type;
265	  type = tp->ctt_type;
266	  break;
267	default:
268	  return type;
269	}
270      if (type == 0)
271	return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
272    }
273
274  return CTF_ERR;		/* errno is set for us.  */
275}
276
277/* Like ctf_type_resolve(), but traverse down through slices to their contained
278   type.  */
279
280ctf_id_t
281ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type)
282{
283  const ctf_type_t *tp;
284
285  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
286    return -1;
287
288  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
289    return CTF_ERR;		/* errno is set for us.  */
290
291  if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
292    return ctf_type_reference (fp, type);
293  return type;
294}
295
296/* Look up a name in the given name table, in the appropriate hash given the
297   kind of the identifier.  The name is a raw, undecorated identifier.  */
298
299ctf_id_t ctf_lookup_by_rawname (ctf_file_t *fp, int kind, const char *name)
300{
301  return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
302}
303
304/* Look up a name in the given name table, in the appropriate hash given the
305   readability state of the dictionary.  The name is a raw, undecorated
306   identifier.  */
307
308ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *fp, ctf_names_t *np, const char *name)
309{
310  ctf_id_t id;
311
312  if (fp->ctf_flags & LCTF_RDWR)
313    id = (ctf_id_t) ctf_dynhash_lookup (np->ctn_writable, name);
314  else
315    id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
316  return id;
317}
318
319/* Lookup the given type ID and return its name as a new dynamcally-allocated
320   string.  */
321
322char *
323ctf_type_aname (ctf_file_t *fp, ctf_id_t type)
324{
325  ctf_decl_t cd;
326  ctf_decl_node_t *cdp;
327  ctf_decl_prec_t prec, lp, rp;
328  int ptr, arr;
329  uint32_t k;
330  char *buf;
331
332  if (fp == NULL && type == CTF_ERR)
333    return NULL;	/* Simplify caller code by permitting CTF_ERR.  */
334
335  ctf_decl_init (&cd);
336  ctf_decl_push (&cd, fp, type);
337
338  if (cd.cd_err != 0)
339    {
340      ctf_decl_fini (&cd);
341      ctf_set_errno (fp, cd.cd_err);
342      return NULL;
343    }
344
345  /* If the type graph's order conflicts with lexical precedence order
346     for pointers or arrays, then we need to surround the declarations at
347     the corresponding lexical precedence with parentheses.  This can
348     result in either a parenthesized pointer (*) as in int (*)() or
349     int (*)[], or in a parenthesized pointer and array as in int (*[])().  */
350
351  ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
352  arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
353
354  rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
355  lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
356
357  k = CTF_K_POINTER;		/* Avoid leading whitespace (see below).  */
358
359  for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
360    {
361      for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
362	   cdp != NULL; cdp = ctf_list_next (cdp))
363	{
364	  ctf_file_t *rfp = fp;
365	  const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
366	  const char *name = ctf_strptr (rfp, tp->ctt_name);
367
368	  if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
369	    ctf_decl_sprintf (&cd, " ");
370
371	  if (lp == prec)
372	    {
373	      ctf_decl_sprintf (&cd, "(");
374	      lp = -1;
375	    }
376
377	  switch (cdp->cd_kind)
378	    {
379	    case CTF_K_INTEGER:
380	    case CTF_K_FLOAT:
381	    case CTF_K_TYPEDEF:
382	      ctf_decl_sprintf (&cd, "%s", name);
383	      break;
384	    case CTF_K_POINTER:
385	      ctf_decl_sprintf (&cd, "*");
386	      break;
387	    case CTF_K_ARRAY:
388	      ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
389	      break;
390	    case CTF_K_FUNCTION:
391	      ctf_decl_sprintf (&cd, "()");
392	      break;
393	    case CTF_K_STRUCT:
394	    case CTF_K_FORWARD:
395	      ctf_decl_sprintf (&cd, "struct %s", name);
396	      break;
397	    case CTF_K_UNION:
398	      ctf_decl_sprintf (&cd, "union %s", name);
399	      break;
400	    case CTF_K_ENUM:
401	      ctf_decl_sprintf (&cd, "enum %s", name);
402	      break;
403	    case CTF_K_VOLATILE:
404	      ctf_decl_sprintf (&cd, "volatile");
405	      break;
406	    case CTF_K_CONST:
407	      ctf_decl_sprintf (&cd, "const");
408	      break;
409	    case CTF_K_RESTRICT:
410	      ctf_decl_sprintf (&cd, "restrict");
411	      break;
412	    case CTF_K_SLICE:
413	      /* No representation: just changes encoding of contained type,
414		 which is not in any case printed.  Skip it.  */
415	      break;
416	    }
417
418	  k = cdp->cd_kind;
419	}
420
421      if (rp == prec)
422	ctf_decl_sprintf (&cd, ")");
423    }
424
425  if (cd.cd_enomem)
426    (void) ctf_set_errno (fp, ENOMEM);
427
428  buf = ctf_decl_buf (&cd);
429
430  ctf_decl_fini (&cd);
431  return buf;
432}
433
434/* Lookup the given type ID and print a string name for it into buf.  Return
435   the actual number of bytes (not including \0) needed to format the name.  */
436
437ssize_t
438ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
439{
440  char *str = ctf_type_aname (fp, type);
441  size_t slen;
442
443  if (str == NULL)
444    return CTF_ERR;			/* errno is set for us.  */
445
446  slen = strlen (str);
447  snprintf (buf, len, "%s", str);
448  free (str);
449
450  if (slen >= len)
451    (void) ctf_set_errno (fp, ECTF_NAMELEN);
452
453  return slen;
454}
455
456/* Lookup the given type ID and print a string name for it into buf.  If buf
457   is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */
458
459char *
460ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
461{
462  ssize_t rv = ctf_type_lname (fp, type, buf, len);
463  return (rv >= 0 && (size_t) rv < len ? buf : NULL);
464}
465
466/* Lookup the given type ID and return its raw, unadorned, undecorated name as a
467   new dynamcally-allocated string.  */
468
469char *
470ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
471{
472  const ctf_type_t *tp;
473
474  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
475    return NULL;		/* errno is set for us.  */
476
477  if (ctf_strraw (fp, tp->ctt_name) != NULL)
478    return strdup (ctf_strraw (fp, tp->ctt_name));
479
480  return NULL;
481}
482
483/* Resolve the type down to a base type node, and then return the size
484   of the type storage in bytes.  */
485
486ssize_t
487ctf_type_size (ctf_file_t *fp, ctf_id_t type)
488{
489  const ctf_type_t *tp;
490  ssize_t size;
491  ctf_arinfo_t ar;
492
493  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
494    return -1;			/* errno is set for us.  */
495
496  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
497    return -1;			/* errno is set for us.  */
498
499  switch (LCTF_INFO_KIND (fp, tp->ctt_info))
500    {
501    case CTF_K_POINTER:
502      return fp->ctf_dmodel->ctd_pointer;
503
504    case CTF_K_FUNCTION:
505      return 0;		/* Function size is only known by symtab.  */
506
507    case CTF_K_ENUM:
508      return fp->ctf_dmodel->ctd_int;
509
510    case CTF_K_ARRAY:
511      /* ctf_add_array() does not directly encode the element size, but
512	 requires the user to multiply to determine the element size.
513
514	 If ctf_get_ctt_size() returns nonzero, then use the recorded
515	 size instead.  */
516
517      if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
518	return size;
519
520      if (ctf_array_info (fp, type, &ar) < 0
521	  || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
522	return -1;		/* errno is set for us.  */
523
524      return size * ar.ctr_nelems;
525
526    default: /* including slices of enums, etc */
527      return (ctf_get_ctt_size (fp, tp, NULL, NULL));
528    }
529}
530
531/* Resolve the type down to a base type node, and then return the alignment
532   needed for the type storage in bytes.
533
534   XXX may need arch-dependent attention.  */
535
536ssize_t
537ctf_type_align (ctf_file_t *fp, ctf_id_t type)
538{
539  const ctf_type_t *tp;
540  ctf_file_t *ofp = fp;
541  int kind;
542
543  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
544    return -1;			/* errno is set for us.  */
545
546  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
547    return -1;			/* errno is set for us.  */
548
549  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
550  switch (kind)
551    {
552    case CTF_K_POINTER:
553    case CTF_K_FUNCTION:
554      return fp->ctf_dmodel->ctd_pointer;
555
556    case CTF_K_ARRAY:
557      {
558	ctf_arinfo_t r;
559	if (ctf_array_info (fp, type, &r) < 0)
560	  return -1;		/* errno is set for us.  */
561	return (ctf_type_align (fp, r.ctr_contents));
562      }
563
564    case CTF_K_STRUCT:
565    case CTF_K_UNION:
566      {
567	size_t align = 0;
568	ctf_dtdef_t *dtd;
569
570	if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
571	  {
572	    uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
573	    ssize_t size, increment;
574	    const void *vmp;
575
576	    (void) ctf_get_ctt_size (fp, tp, &size, &increment);
577	    vmp = (unsigned char *) tp + increment;
578
579	    if (kind == CTF_K_STRUCT)
580	      n = MIN (n, 1);	/* Only use first member for structs.  */
581
582	    if (size < CTF_LSTRUCT_THRESH)
583	      {
584		const ctf_member_t *mp = vmp;
585		for (; n != 0; n--, mp++)
586		  {
587		    ssize_t am = ctf_type_align (fp, mp->ctm_type);
588		    align = MAX (align, (size_t) am);
589		  }
590	      }
591	    else
592	      {
593		const ctf_lmember_t *lmp = vmp;
594		for (; n != 0; n--, lmp++)
595		  {
596		    ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
597		    align = MAX (align, (size_t) am);
598		  }
599	      }
600	  }
601	else
602	  {
603	      ctf_dmdef_t *dmd;
604
605	      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
606		   dmd != NULL; dmd = ctf_list_next (dmd))
607		{
608		  ssize_t am = ctf_type_align (fp, dmd->dmd_type);
609		  align = MAX (align, (size_t) am);
610		  if (kind == CTF_K_STRUCT)
611		    break;
612		}
613	  }
614
615	return align;
616      }
617
618    case CTF_K_ENUM:
619      return fp->ctf_dmodel->ctd_int;
620
621    default:  /* including slices of enums, etc */
622      return (ctf_get_ctt_size (fp, tp, NULL, NULL));
623    }
624}
625
626/* Return the kind (CTF_K_* constant) for the specified type ID.  */
627
628int
629ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
630{
631  const ctf_type_t *tp;
632
633  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
634    return -1;			/* errno is set for us.  */
635
636  return (LCTF_INFO_KIND (fp, tp->ctt_info));
637}
638
639/* Return the kind (CTF_K_* constant) for the specified type ID.
640   Slices are considered to be of the same kind as the type sliced.  */
641
642int
643ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
644{
645  int kind;
646
647  if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
648    return -1;
649
650  if (kind == CTF_K_SLICE)
651    {
652      if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
653	return -1;
654      kind = ctf_type_kind_unsliced (fp, type);
655    }
656
657  return kind;
658}
659
660/* If the type is one that directly references another type (such as POINTER),
661   then return the ID of the type to which it refers.  */
662
663ctf_id_t
664ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
665{
666  ctf_file_t *ofp = fp;
667  const ctf_type_t *tp;
668
669  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
670    return CTF_ERR;		/* errno is set for us.  */
671
672  switch (LCTF_INFO_KIND (fp, tp->ctt_info))
673    {
674    case CTF_K_POINTER:
675    case CTF_K_TYPEDEF:
676    case CTF_K_VOLATILE:
677    case CTF_K_CONST:
678    case CTF_K_RESTRICT:
679      return tp->ctt_type;
680      /* Slices store their type in an unusual place.  */
681    case CTF_K_SLICE:
682      {
683	const ctf_slice_t *sp;
684	ssize_t increment;
685	(void) ctf_get_ctt_size (fp, tp, NULL, &increment);
686	sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
687	return sp->cts_type;
688      }
689    default:
690      return (ctf_set_errno (ofp, ECTF_NOTREF));
691    }
692}
693
694/* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
695   pointer to the given type, see if we can compute a pointer to the type
696   resulting from resolving the type down to its base type and use that
697   instead.  This helps with cases where the CTF data includes "struct foo *"
698   but not "foo_t *" and the user accesses "foo_t *" in the debugger.
699
700   XXX what about parent containers?  */
701
702ctf_id_t
703ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
704{
705  ctf_file_t *ofp = fp;
706  ctf_id_t ntype;
707
708  if (ctf_lookup_by_id (&fp, type) == NULL)
709    return CTF_ERR;		/* errno is set for us.  */
710
711  if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
712    return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
713
714  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
715    return (ctf_set_errno (ofp, ECTF_NOTYPE));
716
717  if (ctf_lookup_by_id (&fp, type) == NULL)
718    return (ctf_set_errno (ofp, ECTF_NOTYPE));
719
720  if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
721    return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
722
723  return (ctf_set_errno (ofp, ECTF_NOTYPE));
724}
725
726/* Return the encoding for the specified INTEGER or FLOAT.  */
727
728int
729ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
730{
731  ctf_file_t *ofp = fp;
732  ctf_dtdef_t *dtd;
733  const ctf_type_t *tp;
734  ssize_t increment;
735  uint32_t data;
736
737  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
738    return -1;			/* errno is set for us.  */
739
740  if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
741    {
742      switch (LCTF_INFO_KIND (fp, tp->ctt_info))
743	{
744	case CTF_K_INTEGER:
745	case CTF_K_FLOAT:
746	  *ep = dtd->dtd_u.dtu_enc;
747	  break;
748	case CTF_K_SLICE:
749	  {
750	    const ctf_slice_t *slice;
751	    ctf_encoding_t underlying_en;
752	    slice = &dtd->dtd_u.dtu_slice;
753
754	    data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
755	    ep->cte_format = underlying_en.cte_format;
756	    ep->cte_offset = slice->cts_offset;
757	    ep->cte_bits = slice->cts_bits;
758	    break;
759	  }
760	default:
761	  return (ctf_set_errno (ofp, ECTF_NOTINTFP));
762	}
763      return 0;
764    }
765
766  (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
767
768  switch (LCTF_INFO_KIND (fp, tp->ctt_info))
769    {
770    case CTF_K_INTEGER:
771      data = *(const uint32_t *) ((uintptr_t) tp + increment);
772      ep->cte_format = CTF_INT_ENCODING (data);
773      ep->cte_offset = CTF_INT_OFFSET (data);
774      ep->cte_bits = CTF_INT_BITS (data);
775      break;
776    case CTF_K_FLOAT:
777      data = *(const uint32_t *) ((uintptr_t) tp + increment);
778      ep->cte_format = CTF_FP_ENCODING (data);
779      ep->cte_offset = CTF_FP_OFFSET (data);
780      ep->cte_bits = CTF_FP_BITS (data);
781      break;
782    case CTF_K_SLICE:
783      {
784	const ctf_slice_t *slice;
785	ctf_encoding_t underlying_en;
786
787	slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
788	data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
789
790	ep->cte_format = underlying_en.cte_format;
791	ep->cte_offset = slice->cts_offset;
792	ep->cte_bits = slice->cts_bits;
793	break;
794      }
795    default:
796      return (ctf_set_errno (ofp, ECTF_NOTINTFP));
797    }
798
799  return 0;
800}
801
802int
803ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
804	      ctf_id_t rtype)
805{
806  int rval;
807
808  if (ltype < rtype)
809    rval = -1;
810  else if (ltype > rtype)
811    rval = 1;
812  else
813    rval = 0;
814
815  if (lfp == rfp)
816    return rval;
817
818  if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
819    lfp = lfp->ctf_parent;
820
821  if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
822    rfp = rfp->ctf_parent;
823
824  if (lfp < rfp)
825    return -1;
826
827  if (lfp > rfp)
828    return 1;
829
830  return rval;
831}
832
833/* Return a boolean value indicating if two types are compatible.  This function
834   returns true if the two types are the same, or if they (or their ultimate
835   base type) have the same encoding properties, or (for structs / unions /
836   enums / forward declarations) if they have the same name and (for structs /
837   unions) member count.  */
838
839int
840ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
841		 ctf_file_t *rfp, ctf_id_t rtype)
842{
843  const ctf_type_t *ltp, *rtp;
844  ctf_encoding_t le, re;
845  ctf_arinfo_t la, ra;
846  uint32_t lkind, rkind;
847  int same_names = 0;
848
849  if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
850    return 1;
851
852  ltype = ctf_type_resolve (lfp, ltype);
853  lkind = ctf_type_kind (lfp, ltype);
854
855  rtype = ctf_type_resolve (rfp, rtype);
856  rkind = ctf_type_kind (rfp, rtype);
857
858  ltp = ctf_lookup_by_id (&lfp, ltype);
859  rtp = ctf_lookup_by_id (&rfp, rtype);
860
861  if (ltp != NULL && rtp != NULL)
862    same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
863			  ctf_strptr (rfp, rtp->ctt_name)) == 0);
864
865  if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
866      ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
867    return 1;
868
869  if (lkind != rkind)
870    return 0;
871
872  switch (lkind)
873    {
874    case CTF_K_INTEGER:
875    case CTF_K_FLOAT:
876      memset (&le, 0, sizeof (le));
877      memset (&re, 0, sizeof (re));
878      return (ctf_type_encoding (lfp, ltype, &le) == 0
879	      && ctf_type_encoding (rfp, rtype, &re) == 0
880	      && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
881    case CTF_K_POINTER:
882      return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
883			       rfp, ctf_type_reference (rfp, rtype)));
884    case CTF_K_ARRAY:
885      return (ctf_array_info (lfp, ltype, &la) == 0
886	      && ctf_array_info (rfp, rtype, &ra) == 0
887	      && la.ctr_nelems == ra.ctr_nelems
888	      && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
889	      && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
890    case CTF_K_STRUCT:
891    case CTF_K_UNION:
892      return (same_names && (ctf_type_size (lfp, ltype)
893			     == ctf_type_size (rfp, rtype)));
894    case CTF_K_ENUM:
895      {
896	int lencoded, rencoded;
897	lencoded = ctf_type_encoding (lfp, ltype, &le);
898	rencoded = ctf_type_encoding (rfp, rtype, &re);
899
900	if ((lencoded != rencoded) ||
901	    ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
902	  return 0;
903      }
904      /* FALLTHRU */
905    case CTF_K_FORWARD:
906      return same_names;   /* No other checks required for these type kinds.  */
907    default:
908      return 0;		      /* Should not get here since we did a resolve.  */
909    }
910}
911
912/* Return the type and offset for a given member of a STRUCT or UNION.  */
913
914int
915ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
916		 ctf_membinfo_t *mip)
917{
918  ctf_file_t *ofp = fp;
919  const ctf_type_t *tp;
920  ctf_dtdef_t *dtd;
921  ssize_t size, increment;
922  uint32_t kind, n;
923
924  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
925    return -1;			/* errno is set for us.  */
926
927  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
928    return -1;			/* errno is set for us.  */
929
930  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
931  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
932
933  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
934    return (ctf_set_errno (ofp, ECTF_NOTSOU));
935
936  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
937    {
938      if (size < CTF_LSTRUCT_THRESH)
939	{
940	  const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
941							   increment);
942
943	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
944	    {
945	      if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
946		{
947		  mip->ctm_type = mp->ctm_type;
948		  mip->ctm_offset = mp->ctm_offset;
949		  return 0;
950		}
951	    }
952	}
953      else
954	{
955	  const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
956							      increment);
957
958	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
959	    {
960	      if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
961		{
962		  mip->ctm_type = lmp->ctlm_type;
963		  mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
964		  return 0;
965		}
966	    }
967	}
968    }
969  else
970    {
971      ctf_dmdef_t *dmd;
972
973      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
974	   dmd != NULL; dmd = ctf_list_next (dmd))
975	{
976	  if (strcmp (dmd->dmd_name, name) == 0)
977	    {
978	      mip->ctm_type = dmd->dmd_type;
979	      mip->ctm_offset = dmd->dmd_offset;
980	      return 0;
981	    }
982	}
983    }
984
985  return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
986}
987
988/* Return the array type, index, and size information for the specified ARRAY.  */
989
990int
991ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
992{
993  ctf_file_t *ofp = fp;
994  const ctf_type_t *tp;
995  const ctf_array_t *ap;
996  const ctf_dtdef_t *dtd;
997  ssize_t increment;
998
999  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1000    return -1;			/* errno is set for us.  */
1001
1002  if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1003    return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1004
1005  if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1006    {
1007      *arp = dtd->dtd_u.dtu_arr;
1008      return 0;
1009    }
1010
1011  (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1012
1013  ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1014  arp->ctr_contents = ap->cta_contents;
1015  arp->ctr_index = ap->cta_index;
1016  arp->ctr_nelems = ap->cta_nelems;
1017
1018  return 0;
1019}
1020
1021/* Convert the specified value to the corresponding enum tag name, if a
1022   matching name can be found.  Otherwise NULL is returned.  */
1023
1024const char *
1025ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1026{
1027  ctf_file_t *ofp = fp;
1028  const ctf_type_t *tp;
1029  const ctf_enum_t *ep;
1030  const ctf_dtdef_t *dtd;
1031  ssize_t increment;
1032  uint32_t n;
1033
1034  if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1035    return NULL;		/* errno is set for us.  */
1036
1037  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1038    return NULL;		/* errno is set for us.  */
1039
1040  if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1041    {
1042      (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1043      return NULL;
1044    }
1045
1046  (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1047
1048  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1049    {
1050      ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1051
1052      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1053	{
1054	  if (ep->cte_value == value)
1055	    return (ctf_strptr (fp, ep->cte_name));
1056	}
1057    }
1058  else
1059    {
1060      ctf_dmdef_t *dmd;
1061
1062      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1063	   dmd != NULL; dmd = ctf_list_next (dmd))
1064	{
1065	  if (dmd->dmd_value == value)
1066	    return dmd->dmd_name;
1067	}
1068    }
1069
1070  (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1071  return NULL;
1072}
1073
1074/* Convert the specified enum tag name to the corresponding value, if a
1075   matching name can be found.  Otherwise CTF_ERR is returned.  */
1076
1077int
1078ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1079{
1080  ctf_file_t *ofp = fp;
1081  const ctf_type_t *tp;
1082  const ctf_enum_t *ep;
1083  const ctf_dtdef_t *dtd;
1084  ssize_t increment;
1085  uint32_t n;
1086
1087  if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1088    return -1;			/* errno is set for us.  */
1089
1090  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1091    return -1;			/* errno is set for us.  */
1092
1093  if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1094    {
1095      (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1096      return -1;
1097    }
1098
1099  (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1100
1101  ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1102
1103  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1104    {
1105      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1106	{
1107	  if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1108	    {
1109	      if (valp != NULL)
1110		*valp = ep->cte_value;
1111	      return 0;
1112	    }
1113	}
1114    }
1115  else
1116    {
1117      ctf_dmdef_t *dmd;
1118
1119      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1120	   dmd != NULL; dmd = ctf_list_next (dmd))
1121	{
1122	  if (strcmp (dmd->dmd_name, name) == 0)
1123	    {
1124	      if (valp != NULL)
1125		*valp = dmd->dmd_value;
1126	      return 0;
1127	    }
1128	}
1129    }
1130
1131  (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1132  return -1;
1133}
1134
1135/* Given a type ID relating to a function type, return info on return types and
1136   arg counts for that function.  */
1137
1138int
1139ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1140{
1141  const ctf_type_t *tp;
1142  uint32_t kind;
1143  const uint32_t *args;
1144  const ctf_dtdef_t *dtd;
1145  ssize_t size, increment;
1146
1147  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1148    return -1;			/* errno is set for us.  */
1149
1150  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1151    return -1;			/* errno is set for us.  */
1152
1153  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1154  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1155
1156  if (kind != CTF_K_FUNCTION)
1157    return (ctf_set_errno (fp, ECTF_NOTFUNC));
1158
1159  fip->ctc_return = tp->ctt_type;
1160  fip->ctc_flags = 0;
1161  fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1162
1163  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1164    args = (uint32_t *) ((uintptr_t) tp + increment);
1165  else
1166    args = (uint32_t *) dtd->dtd_u.dtu_argv;
1167
1168  if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1169    {
1170      fip->ctc_flags |= CTF_FUNC_VARARG;
1171      fip->ctc_argc--;
1172    }
1173
1174  return 0;
1175}
1176
1177/* Given a type ID relating to a function type,, return the arguments for the
1178   function.  */
1179
1180int
1181ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1182{
1183  const ctf_type_t *tp;
1184  const uint32_t *args;
1185  const ctf_dtdef_t *dtd;
1186  ssize_t size, increment;
1187  ctf_funcinfo_t f;
1188
1189  if (ctf_func_type_info (fp, type, &f) < 0)
1190    return -1;			/* errno is set for us.  */
1191
1192  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1193    return -1;			/* errno is set for us.  */
1194
1195  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1196    return -1;			/* errno is set for us.  */
1197
1198  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1199
1200  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1201    args = (uint32_t *) ((uintptr_t) tp + increment);
1202  else
1203    args = (uint32_t *) dtd->dtd_u.dtu_argv;
1204
1205  for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1206    *argv++ = *args++;
1207
1208  return 0;
1209}
1210
1211/* Recursively visit the members of any type.  This function is used as the
1212   engine for ctf_type_visit, below.  We resolve the input type, recursively
1213   invoke ourself for each type member if the type is a struct or union, and
1214   then invoke the callback function on the current type.  If any callback
1215   returns non-zero, we abort and percolate the error code back up to the top.  */
1216
1217static int
1218ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1219		 void *arg, const char *name, unsigned long offset, int depth)
1220{
1221  ctf_id_t otype = type;
1222  const ctf_type_t *tp;
1223  const ctf_dtdef_t *dtd;
1224  ssize_t size, increment;
1225  uint32_t kind, n;
1226  int rc;
1227
1228  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1229    return -1;			/* errno is set for us.  */
1230
1231  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1232    return -1;			/* errno is set for us.  */
1233
1234  if ((rc = func (name, otype, offset, depth, arg)) != 0)
1235    return rc;
1236
1237  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1238
1239  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1240    return 0;
1241
1242  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1243
1244  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1245    {
1246      if (size < CTF_LSTRUCT_THRESH)
1247	{
1248	  const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1249							   increment);
1250
1251	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1252	    {
1253	      if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1254					 func, arg, ctf_strptr (fp,
1255								mp->ctm_name),
1256					 offset + mp->ctm_offset,
1257					 depth + 1)) != 0)
1258		return rc;
1259	    }
1260	}
1261      else
1262	{
1263	  const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1264							      increment);
1265
1266	  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1267	    {
1268	      if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1269					 func, arg, ctf_strptr (fp,
1270								lmp->ctlm_name),
1271					 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1272					 depth + 1)) != 0)
1273		return rc;
1274	    }
1275	}
1276    }
1277  else
1278    {
1279      ctf_dmdef_t *dmd;
1280
1281      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1282	   dmd != NULL; dmd = ctf_list_next (dmd))
1283	{
1284	  if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1285				     dmd->dmd_name, dmd->dmd_offset,
1286				     depth + 1)) != 0)
1287	    return rc;
1288	}
1289    }
1290
1291  return 0;
1292}
1293
1294/* Recursively visit the members of any type.  We pass the name, member
1295 type, and offset of each member to the specified callback function.  */
1296int
1297ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1298{
1299  return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1300}
1301