xref: /netbsd-src/external/gpl3/binutils.old/dist/libctf/ctf-open.c (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1867d70fcSchristos /* Opening CTF files.
2*c42dbd0eSchristos    Copyright (C) 2019-2022 Free Software Foundation, Inc.
3867d70fcSchristos 
4867d70fcSchristos    This file is part of libctf.
5867d70fcSchristos 
6867d70fcSchristos    libctf is free software; you can redistribute it and/or modify it under
7867d70fcSchristos    the terms of the GNU General Public License as published by the Free
8867d70fcSchristos    Software Foundation; either version 3, or (at your option) any later
9867d70fcSchristos    version.
10867d70fcSchristos 
11867d70fcSchristos    This program is distributed in the hope that it will be useful, but
12867d70fcSchristos    WITHOUT ANY WARRANTY; without even the implied warranty of
13867d70fcSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14867d70fcSchristos    See the GNU General Public License for more details.
15867d70fcSchristos 
16867d70fcSchristos    You should have received a copy of the GNU General Public License
17867d70fcSchristos    along with this program; see the file COPYING.  If not see
18867d70fcSchristos    <http://www.gnu.org/licenses/>.  */
19867d70fcSchristos 
20867d70fcSchristos #include <ctf-impl.h>
21867d70fcSchristos #include <stddef.h>
22867d70fcSchristos #include <string.h>
23867d70fcSchristos #include <sys/types.h>
24867d70fcSchristos #include <elf.h>
25867d70fcSchristos #include "swap.h"
26867d70fcSchristos #include <bfd.h>
27867d70fcSchristos #include <zlib.h>
28867d70fcSchristos 
29867d70fcSchristos static const ctf_dmodel_t _libctf_models[] = {
30867d70fcSchristos   {"ILP32", CTF_MODEL_ILP32, 4, 1, 2, 4, 4},
31867d70fcSchristos   {"LP64", CTF_MODEL_LP64, 8, 1, 2, 4, 8},
32867d70fcSchristos   {NULL, 0, 0, 0, 0, 0, 0}
33867d70fcSchristos };
34867d70fcSchristos 
35867d70fcSchristos const char _CTF_SECTION[] = ".ctf";
36867d70fcSchristos const char _CTF_NULLSTR[] = "";
37867d70fcSchristos 
38867d70fcSchristos /* Version-sensitive accessors.  */
39867d70fcSchristos 
40867d70fcSchristos static uint32_t
get_kind_v1(uint32_t info)41867d70fcSchristos get_kind_v1 (uint32_t info)
42867d70fcSchristos {
43867d70fcSchristos   return (CTF_V1_INFO_KIND (info));
44867d70fcSchristos }
45867d70fcSchristos 
46867d70fcSchristos static uint32_t
get_root_v1(uint32_t info)47867d70fcSchristos get_root_v1 (uint32_t info)
48867d70fcSchristos {
49867d70fcSchristos   return (CTF_V1_INFO_ISROOT (info));
50867d70fcSchristos }
51867d70fcSchristos 
52867d70fcSchristos static uint32_t
get_vlen_v1(uint32_t info)53867d70fcSchristos get_vlen_v1 (uint32_t info)
54867d70fcSchristos {
55867d70fcSchristos   return (CTF_V1_INFO_VLEN (info));
56867d70fcSchristos }
57867d70fcSchristos 
58867d70fcSchristos static uint32_t
get_kind_v2(uint32_t info)59867d70fcSchristos get_kind_v2 (uint32_t info)
60867d70fcSchristos {
61867d70fcSchristos   return (CTF_V2_INFO_KIND (info));
62867d70fcSchristos }
63867d70fcSchristos 
64867d70fcSchristos static uint32_t
get_root_v2(uint32_t info)65867d70fcSchristos get_root_v2 (uint32_t info)
66867d70fcSchristos {
67867d70fcSchristos   return (CTF_V2_INFO_ISROOT (info));
68867d70fcSchristos }
69867d70fcSchristos 
70867d70fcSchristos static uint32_t
get_vlen_v2(uint32_t info)71867d70fcSchristos get_vlen_v2 (uint32_t info)
72867d70fcSchristos {
73867d70fcSchristos   return (CTF_V2_INFO_VLEN (info));
74867d70fcSchristos }
75867d70fcSchristos 
76867d70fcSchristos static inline ssize_t
get_ctt_size_common(const ctf_dict_t * fp _libctf_unused_,const ctf_type_t * tp _libctf_unused_,ssize_t * sizep,ssize_t * incrementp,size_t lsize,size_t csize,size_t ctf_type_size,size_t ctf_stype_size,size_t ctf_lsize_sent)77*c42dbd0eSchristos get_ctt_size_common (const ctf_dict_t *fp _libctf_unused_,
78867d70fcSchristos 		     const ctf_type_t *tp _libctf_unused_,
79867d70fcSchristos 		     ssize_t *sizep, ssize_t *incrementp, size_t lsize,
80867d70fcSchristos 		     size_t csize, size_t ctf_type_size,
81867d70fcSchristos 		     size_t ctf_stype_size, size_t ctf_lsize_sent)
82867d70fcSchristos {
83867d70fcSchristos   ssize_t size, increment;
84867d70fcSchristos 
85867d70fcSchristos   if (csize == ctf_lsize_sent)
86867d70fcSchristos     {
87867d70fcSchristos       size = lsize;
88867d70fcSchristos       increment = ctf_type_size;
89867d70fcSchristos     }
90867d70fcSchristos   else
91867d70fcSchristos     {
92867d70fcSchristos       size = csize;
93867d70fcSchristos       increment = ctf_stype_size;
94867d70fcSchristos     }
95867d70fcSchristos 
96867d70fcSchristos   if (sizep)
97867d70fcSchristos     *sizep = size;
98867d70fcSchristos   if (incrementp)
99867d70fcSchristos     *incrementp = increment;
100867d70fcSchristos 
101867d70fcSchristos   return size;
102867d70fcSchristos }
103867d70fcSchristos 
104867d70fcSchristos static ssize_t
get_ctt_size_v1(const ctf_dict_t * fp,const ctf_type_t * tp,ssize_t * sizep,ssize_t * incrementp)105*c42dbd0eSchristos get_ctt_size_v1 (const ctf_dict_t *fp, const ctf_type_t *tp,
106867d70fcSchristos 		 ssize_t *sizep, ssize_t *incrementp)
107867d70fcSchristos {
108867d70fcSchristos   ctf_type_v1_t *t1p = (ctf_type_v1_t *) tp;
109867d70fcSchristos 
110867d70fcSchristos   return (get_ctt_size_common (fp, tp, sizep, incrementp,
111867d70fcSchristos 			       CTF_TYPE_LSIZE (t1p), t1p->ctt_size,
112867d70fcSchristos 			       sizeof (ctf_type_v1_t), sizeof (ctf_stype_v1_t),
113867d70fcSchristos 			       CTF_LSIZE_SENT_V1));
114867d70fcSchristos }
115867d70fcSchristos 
116867d70fcSchristos /* Return the size that a v1 will be once it is converted to v2.  */
117867d70fcSchristos 
118867d70fcSchristos static ssize_t
get_ctt_size_v2_unconverted(const ctf_dict_t * fp,const ctf_type_t * tp,ssize_t * sizep,ssize_t * incrementp)119*c42dbd0eSchristos get_ctt_size_v2_unconverted (const ctf_dict_t *fp, const ctf_type_t *tp,
120867d70fcSchristos 			     ssize_t *sizep, ssize_t *incrementp)
121867d70fcSchristos {
122867d70fcSchristos   ctf_type_v1_t *t1p = (ctf_type_v1_t *) tp;
123867d70fcSchristos 
124867d70fcSchristos   return (get_ctt_size_common (fp, tp, sizep, incrementp,
125867d70fcSchristos 			       CTF_TYPE_LSIZE (t1p), t1p->ctt_size,
126867d70fcSchristos 			       sizeof (ctf_type_t), sizeof (ctf_stype_t),
127867d70fcSchristos 			       CTF_LSIZE_SENT));
128867d70fcSchristos }
129867d70fcSchristos 
130867d70fcSchristos static ssize_t
get_ctt_size_v2(const ctf_dict_t * fp,const ctf_type_t * tp,ssize_t * sizep,ssize_t * incrementp)131*c42dbd0eSchristos get_ctt_size_v2 (const ctf_dict_t *fp, const ctf_type_t *tp,
132867d70fcSchristos 		 ssize_t *sizep, ssize_t *incrementp)
133867d70fcSchristos {
134867d70fcSchristos   return (get_ctt_size_common (fp, tp, sizep, incrementp,
135867d70fcSchristos 			       CTF_TYPE_LSIZE (tp), tp->ctt_size,
136867d70fcSchristos 			       sizeof (ctf_type_t), sizeof (ctf_stype_t),
137867d70fcSchristos 			       CTF_LSIZE_SENT));
138867d70fcSchristos }
139867d70fcSchristos 
140867d70fcSchristos static ssize_t
get_vbytes_common(ctf_dict_t * fp,unsigned short kind,ssize_t size _libctf_unused_,size_t vlen)141*c42dbd0eSchristos get_vbytes_common (ctf_dict_t *fp, unsigned short kind,
142*c42dbd0eSchristos 		   ssize_t size _libctf_unused_, size_t vlen)
143867d70fcSchristos {
144867d70fcSchristos   switch (kind)
145867d70fcSchristos     {
146867d70fcSchristos     case CTF_K_INTEGER:
147867d70fcSchristos     case CTF_K_FLOAT:
148867d70fcSchristos       return (sizeof (uint32_t));
149867d70fcSchristos     case CTF_K_SLICE:
150867d70fcSchristos       return (sizeof (ctf_slice_t));
151867d70fcSchristos     case CTF_K_ENUM:
152867d70fcSchristos       return (sizeof (ctf_enum_t) * vlen);
153867d70fcSchristos     case CTF_K_FORWARD:
154867d70fcSchristos     case CTF_K_UNKNOWN:
155867d70fcSchristos     case CTF_K_POINTER:
156867d70fcSchristos     case CTF_K_TYPEDEF:
157867d70fcSchristos     case CTF_K_VOLATILE:
158867d70fcSchristos     case CTF_K_CONST:
159867d70fcSchristos     case CTF_K_RESTRICT:
160867d70fcSchristos       return 0;
161867d70fcSchristos     default:
162*c42dbd0eSchristos       ctf_set_errno (fp, ECTF_CORRUPT);
163*c42dbd0eSchristos       ctf_err_warn (fp, 0, 0, _("detected invalid CTF kind: %x"), kind);
164*c42dbd0eSchristos       return -1;
165867d70fcSchristos     }
166867d70fcSchristos }
167867d70fcSchristos 
168867d70fcSchristos static ssize_t
get_vbytes_v1(ctf_dict_t * fp,unsigned short kind,ssize_t size,size_t vlen)169*c42dbd0eSchristos get_vbytes_v1 (ctf_dict_t *fp, unsigned short kind, ssize_t size, size_t vlen)
170867d70fcSchristos {
171867d70fcSchristos   switch (kind)
172867d70fcSchristos     {
173867d70fcSchristos     case CTF_K_ARRAY:
174867d70fcSchristos       return (sizeof (ctf_array_v1_t));
175867d70fcSchristos     case CTF_K_FUNCTION:
176867d70fcSchristos       return (sizeof (unsigned short) * (vlen + (vlen & 1)));
177867d70fcSchristos     case CTF_K_STRUCT:
178867d70fcSchristos     case CTF_K_UNION:
179867d70fcSchristos       if (size < CTF_LSTRUCT_THRESH_V1)
180867d70fcSchristos 	return (sizeof (ctf_member_v1_t) * vlen);
181867d70fcSchristos       else
182867d70fcSchristos 	return (sizeof (ctf_lmember_v1_t) * vlen);
183867d70fcSchristos     }
184867d70fcSchristos 
185*c42dbd0eSchristos   return (get_vbytes_common (fp, kind, size, vlen));
186867d70fcSchristos }
187867d70fcSchristos 
188867d70fcSchristos static ssize_t
get_vbytes_v2(ctf_dict_t * fp,unsigned short kind,ssize_t size,size_t vlen)189*c42dbd0eSchristos get_vbytes_v2 (ctf_dict_t *fp, unsigned short kind, ssize_t size, size_t vlen)
190867d70fcSchristos {
191867d70fcSchristos   switch (kind)
192867d70fcSchristos     {
193867d70fcSchristos     case CTF_K_ARRAY:
194867d70fcSchristos       return (sizeof (ctf_array_t));
195867d70fcSchristos     case CTF_K_FUNCTION:
196867d70fcSchristos       return (sizeof (uint32_t) * (vlen + (vlen & 1)));
197867d70fcSchristos     case CTF_K_STRUCT:
198867d70fcSchristos     case CTF_K_UNION:
199867d70fcSchristos       if (size < CTF_LSTRUCT_THRESH)
200867d70fcSchristos 	return (sizeof (ctf_member_t) * vlen);
201867d70fcSchristos       else
202867d70fcSchristos 	return (sizeof (ctf_lmember_t) * vlen);
203867d70fcSchristos     }
204867d70fcSchristos 
205*c42dbd0eSchristos   return (get_vbytes_common (fp, kind, size, vlen));
206867d70fcSchristos }
207867d70fcSchristos 
208*c42dbd0eSchristos static const ctf_dictops_t ctf_dictops[] = {
209867d70fcSchristos   {NULL, NULL, NULL, NULL, NULL},
210867d70fcSchristos   /* CTF_VERSION_1 */
211867d70fcSchristos   {get_kind_v1, get_root_v1, get_vlen_v1, get_ctt_size_v1, get_vbytes_v1},
212867d70fcSchristos   /* CTF_VERSION_1_UPGRADED_3 */
213867d70fcSchristos   {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
214867d70fcSchristos   /* CTF_VERSION_2 */
215867d70fcSchristos   {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
216867d70fcSchristos   /* CTF_VERSION_3, identical to 2: only new type kinds */
217867d70fcSchristos   {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
218867d70fcSchristos };
219867d70fcSchristos 
220*c42dbd0eSchristos /* Initialize the symtab translation table as appropriate for its indexing
221*c42dbd0eSchristos    state.  For unindexed symtypetabs, fill each entry with the offset of the CTF
222*c42dbd0eSchristos    type or function data corresponding to each STT_FUNC or STT_OBJECT entry in
223*c42dbd0eSchristos    the symbol table.  For indexed symtypetabs, do nothing: the needed
224*c42dbd0eSchristos    initialization for indexed lookups may be quite expensive, so it is done only
225*c42dbd0eSchristos    as needed, when lookups happen.  (In particular, the majority of indexed
226*c42dbd0eSchristos    symtypetabs come from the compiler, and all the linker does is iteration over
227*c42dbd0eSchristos    all entries, which doesn't need this initialization.)
228*c42dbd0eSchristos 
229*c42dbd0eSchristos    The SP symbol table section may be NULL if there is no symtab.
230*c42dbd0eSchristos 
231*c42dbd0eSchristos    If init_symtab works on one call, it cannot fail on future calls to the same
232*c42dbd0eSchristos    fp: ctf_symsect_endianness relies on this.  */
233867d70fcSchristos 
234867d70fcSchristos static int
init_symtab(ctf_dict_t * fp,const ctf_header_t * hp,const ctf_sect_t * sp)235*c42dbd0eSchristos init_symtab (ctf_dict_t *fp, const ctf_header_t *hp, const ctf_sect_t *sp)
236867d70fcSchristos {
237*c42dbd0eSchristos   const unsigned char *symp;
238*c42dbd0eSchristos   int skip_func_info = 0;
239*c42dbd0eSchristos   int i;
240867d70fcSchristos   uint32_t *xp = fp->ctf_sxlate;
241*c42dbd0eSchristos   uint32_t *xend = PTR_ADD (xp, fp->ctf_nsyms);
242867d70fcSchristos 
243867d70fcSchristos   uint32_t objtoff = hp->cth_objtoff;
244867d70fcSchristos   uint32_t funcoff = hp->cth_funcoff;
245867d70fcSchristos 
246*c42dbd0eSchristos   /* If the CTF_F_NEWFUNCINFO flag is not set, pretend the func info section
247*c42dbd0eSchristos      is empty: this compiler is too old to emit a function info section we
248*c42dbd0eSchristos      understand.  */
249867d70fcSchristos 
250*c42dbd0eSchristos   if (!(hp->cth_flags & CTF_F_NEWFUNCINFO))
251*c42dbd0eSchristos     skip_func_info = 1;
252867d70fcSchristos 
253*c42dbd0eSchristos   if (hp->cth_objtidxoff < hp->cth_funcidxoff)
254*c42dbd0eSchristos     fp->ctf_objtidx_names = (uint32_t *) (fp->ctf_buf + hp->cth_objtidxoff);
255*c42dbd0eSchristos   if (hp->cth_funcidxoff < hp->cth_varoff && !skip_func_info)
256*c42dbd0eSchristos     fp->ctf_funcidx_names = (uint32_t *) (fp->ctf_buf + hp->cth_funcidxoff);
257*c42dbd0eSchristos 
258*c42dbd0eSchristos   /* Don't bother doing the rest if everything is indexed, or if we don't have a
259*c42dbd0eSchristos      symbol table: we will never use it.  */
260*c42dbd0eSchristos   if ((fp->ctf_objtidx_names && fp->ctf_funcidx_names) || !sp || !sp->cts_data)
261*c42dbd0eSchristos     return 0;
262*c42dbd0eSchristos 
263*c42dbd0eSchristos   /* The CTF data object and function type sections are ordered to match the
264*c42dbd0eSchristos      relative order of the respective symbol types in the symtab, unless there
265*c42dbd0eSchristos      is an index section, in which case the order is arbitrary and the index
266*c42dbd0eSchristos      gives the mapping.  If no type information is available for a symbol table
267*c42dbd0eSchristos      entry, a pad is inserted in the CTF section.  As a further optimization,
268*c42dbd0eSchristos      anonymous or undefined symbols are omitted from the CTF data.  If an
269*c42dbd0eSchristos      index is available for function symbols but not object symbols, or vice
270*c42dbd0eSchristos      versa, we populate the xslate table for the unindexed symbols only.  */
271*c42dbd0eSchristos 
272*c42dbd0eSchristos   for (i = 0, symp = sp->cts_data; xp < xend; xp++, symp += sp->cts_entsize,
273*c42dbd0eSchristos 	 i++)
274867d70fcSchristos     {
275*c42dbd0eSchristos       ctf_link_sym_t sym;
276867d70fcSchristos 
277*c42dbd0eSchristos       switch (sp->cts_entsize)
278*c42dbd0eSchristos 	{
279*c42dbd0eSchristos 	case sizeof (Elf64_Sym):
280*c42dbd0eSchristos 	  {
281*c42dbd0eSchristos 	    const Elf64_Sym *symp64 = (Elf64_Sym *) (uintptr_t) symp;
282*c42dbd0eSchristos 	    ctf_elf64_to_link_sym (fp, &sym, symp64, i);
283*c42dbd0eSchristos 	  }
284*c42dbd0eSchristos 	  break;
285*c42dbd0eSchristos 	case sizeof (Elf32_Sym):
286*c42dbd0eSchristos 	  {
287*c42dbd0eSchristos 	    const Elf32_Sym *symp32 = (Elf32_Sym *) (uintptr_t) symp;
288*c42dbd0eSchristos 	    ctf_elf32_to_link_sym (fp, &sym, symp32, i);
289*c42dbd0eSchristos 	  }
290*c42dbd0eSchristos 	  break;
291*c42dbd0eSchristos 	default:
292*c42dbd0eSchristos 	  return ECTF_SYMTAB;
293*c42dbd0eSchristos 	}
294867d70fcSchristos 
295*c42dbd0eSchristos       /* This call may be led astray if our idea of the symtab's endianness is
296*c42dbd0eSchristos 	 wrong, but when this is fixed by a call to ctf_symsect_endianness,
297*c42dbd0eSchristos 	 init_symtab will be called again with the right endianness in
298*c42dbd0eSchristos 	 force.  */
299*c42dbd0eSchristos       if (ctf_symtab_skippable (&sym))
300867d70fcSchristos 	{
301867d70fcSchristos 	  *xp = -1u;
302867d70fcSchristos 	  continue;
303867d70fcSchristos 	}
304867d70fcSchristos 
305*c42dbd0eSchristos       switch (sym.st_type)
306867d70fcSchristos 	{
307867d70fcSchristos 	case STT_OBJECT:
308*c42dbd0eSchristos 	  if (fp->ctf_objtidx_names || objtoff >= hp->cth_funcoff)
309867d70fcSchristos 	    {
310867d70fcSchristos 	      *xp = -1u;
311867d70fcSchristos 	      break;
312867d70fcSchristos 	    }
313867d70fcSchristos 
314867d70fcSchristos 	  *xp = objtoff;
315867d70fcSchristos 	  objtoff += sizeof (uint32_t);
316867d70fcSchristos 	  break;
317867d70fcSchristos 
318867d70fcSchristos 	case STT_FUNC:
319*c42dbd0eSchristos 	  if (fp->ctf_funcidx_names || funcoff >= hp->cth_objtidxoff
320*c42dbd0eSchristos 	      || skip_func_info)
321867d70fcSchristos 	    {
322867d70fcSchristos 	      *xp = -1u;
323867d70fcSchristos 	      break;
324867d70fcSchristos 	    }
325867d70fcSchristos 
326867d70fcSchristos 	  *xp = funcoff;
327*c42dbd0eSchristos 	  funcoff += sizeof (uint32_t);
328867d70fcSchristos 	  break;
329867d70fcSchristos 
330867d70fcSchristos 	default:
331867d70fcSchristos 	  *xp = -1u;
332867d70fcSchristos 	  break;
333867d70fcSchristos 	}
334867d70fcSchristos     }
335867d70fcSchristos 
336867d70fcSchristos   ctf_dprintf ("loaded %lu symtab entries\n", fp->ctf_nsyms);
337867d70fcSchristos   return 0;
338867d70fcSchristos }
339867d70fcSchristos 
340867d70fcSchristos /* Reset the CTF base pointer and derive the buf pointer from it, initializing
341*c42dbd0eSchristos    everything in the ctf_dict that depends on the base or buf pointers.
342867d70fcSchristos 
343867d70fcSchristos    The original gap between the buf and base pointers, if any -- the original,
344867d70fcSchristos    unconverted CTF header -- is kept, but its contents are not specified and are
345867d70fcSchristos    never used.  */
346867d70fcSchristos 
347867d70fcSchristos static void
ctf_set_base(ctf_dict_t * fp,const ctf_header_t * hp,unsigned char * base)348*c42dbd0eSchristos ctf_set_base (ctf_dict_t *fp, const ctf_header_t *hp, unsigned char *base)
349867d70fcSchristos {
350867d70fcSchristos   fp->ctf_buf = base + (fp->ctf_buf - fp->ctf_base);
351867d70fcSchristos   fp->ctf_base = base;
352867d70fcSchristos   fp->ctf_vars = (ctf_varent_t *) ((const char *) fp->ctf_buf +
353867d70fcSchristos 				   hp->cth_varoff);
354867d70fcSchristos   fp->ctf_nvars = (hp->cth_typeoff - hp->cth_varoff) / sizeof (ctf_varent_t);
355867d70fcSchristos 
356867d70fcSchristos   fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *) fp->ctf_buf
357867d70fcSchristos     + hp->cth_stroff;
358867d70fcSchristos   fp->ctf_str[CTF_STRTAB_0].cts_len = hp->cth_strlen;
359867d70fcSchristos 
360*c42dbd0eSchristos   /* If we have a parent dict name and label, store the relocated string
361*c42dbd0eSchristos      pointers in the CTF dict for easy access later. */
362867d70fcSchristos 
363867d70fcSchristos   /* Note: before conversion, these will be set to values that will be
364867d70fcSchristos      immediately invalidated by the conversion process, but the conversion
365867d70fcSchristos      process will call ctf_set_base() again to fix things up.  */
366867d70fcSchristos 
367867d70fcSchristos   if (hp->cth_parlabel != 0)
368867d70fcSchristos     fp->ctf_parlabel = ctf_strptr (fp, hp->cth_parlabel);
369867d70fcSchristos   if (hp->cth_parname != 0)
370867d70fcSchristos     fp->ctf_parname = ctf_strptr (fp, hp->cth_parname);
371867d70fcSchristos   if (hp->cth_cuname != 0)
372867d70fcSchristos     fp->ctf_cuname = ctf_strptr (fp, hp->cth_cuname);
373867d70fcSchristos 
374867d70fcSchristos   if (fp->ctf_cuname)
375867d70fcSchristos     ctf_dprintf ("ctf_set_base: CU name %s\n", fp->ctf_cuname);
376867d70fcSchristos   if (fp->ctf_parname)
377867d70fcSchristos     ctf_dprintf ("ctf_set_base: parent name %s (label %s)\n",
378867d70fcSchristos 	       fp->ctf_parname,
379867d70fcSchristos 	       fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>");
380867d70fcSchristos }
381867d70fcSchristos 
382867d70fcSchristos /* Set the version of the CTF file. */
383867d70fcSchristos 
384867d70fcSchristos /* When this is reset, LCTF_* changes behaviour, but there is no guarantee that
385867d70fcSchristos    the variable data list associated with each type has been upgraded: the
386867d70fcSchristos    caller must ensure this has been done in advance.  */
387867d70fcSchristos 
388867d70fcSchristos static void
ctf_set_version(ctf_dict_t * fp,ctf_header_t * cth,int ctf_version)389*c42dbd0eSchristos ctf_set_version (ctf_dict_t *fp, ctf_header_t *cth, int ctf_version)
390867d70fcSchristos {
391867d70fcSchristos   fp->ctf_version = ctf_version;
392867d70fcSchristos   cth->cth_version = ctf_version;
393*c42dbd0eSchristos   fp->ctf_dictops = &ctf_dictops[ctf_version];
394867d70fcSchristos }
395867d70fcSchristos 
396867d70fcSchristos 
397867d70fcSchristos /* Upgrade the header to CTF_VERSION_3.  The upgrade is done in-place.  */
398867d70fcSchristos static void
upgrade_header(ctf_header_t * hp)399867d70fcSchristos upgrade_header (ctf_header_t *hp)
400867d70fcSchristos {
401867d70fcSchristos   ctf_header_v2_t *oldhp = (ctf_header_v2_t *) hp;
402867d70fcSchristos 
403867d70fcSchristos   hp->cth_strlen = oldhp->cth_strlen;
404867d70fcSchristos   hp->cth_stroff = oldhp->cth_stroff;
405867d70fcSchristos   hp->cth_typeoff = oldhp->cth_typeoff;
406867d70fcSchristos   hp->cth_varoff = oldhp->cth_varoff;
407867d70fcSchristos   hp->cth_funcidxoff = hp->cth_varoff;		/* No index sections.  */
408867d70fcSchristos   hp->cth_objtidxoff = hp->cth_funcidxoff;
409867d70fcSchristos   hp->cth_funcoff = oldhp->cth_funcoff;
410867d70fcSchristos   hp->cth_objtoff = oldhp->cth_objtoff;
411867d70fcSchristos   hp->cth_lbloff = oldhp->cth_lbloff;
412867d70fcSchristos   hp->cth_cuname = 0;				/* No CU name.  */
413867d70fcSchristos }
414867d70fcSchristos 
415867d70fcSchristos /* Upgrade the type table to CTF_VERSION_3 (really CTF_VERSION_1_UPGRADED_3)
416867d70fcSchristos    from CTF_VERSION_1.
417867d70fcSchristos 
418867d70fcSchristos    The upgrade is not done in-place: the ctf_base is moved.  ctf_strptr() must
419867d70fcSchristos    not be called before reallocation is complete.
420867d70fcSchristos 
421867d70fcSchristos    Sections not checked here due to nonexistence or nonpopulated state in older
422867d70fcSchristos    formats: objtidx, funcidx.
423867d70fcSchristos 
424867d70fcSchristos    Type kinds not checked here due to nonexistence in older formats:
425867d70fcSchristos       CTF_K_SLICE.  */
426867d70fcSchristos static int
upgrade_types_v1(ctf_dict_t * fp,ctf_header_t * cth)427*c42dbd0eSchristos upgrade_types_v1 (ctf_dict_t *fp, ctf_header_t *cth)
428867d70fcSchristos {
429867d70fcSchristos   const ctf_type_v1_t *tbuf;
430867d70fcSchristos   const ctf_type_v1_t *tend;
431867d70fcSchristos   unsigned char *ctf_base, *old_ctf_base = (unsigned char *) fp->ctf_dynbase;
432867d70fcSchristos   ctf_type_t *t2buf;
433867d70fcSchristos 
434867d70fcSchristos   ssize_t increase = 0, size, increment, v2increment, vbytes, v2bytes;
435867d70fcSchristos   const ctf_type_v1_t *tp;
436867d70fcSchristos   ctf_type_t *t2p;
437867d70fcSchristos 
438867d70fcSchristos   tbuf = (ctf_type_v1_t *) (fp->ctf_buf + cth->cth_typeoff);
439867d70fcSchristos   tend = (ctf_type_v1_t *) (fp->ctf_buf + cth->cth_stroff);
440867d70fcSchristos 
441867d70fcSchristos   /* Much like init_types(), this is a two-pass process.
442867d70fcSchristos 
443867d70fcSchristos      First, figure out the new type-section size needed.  (It is possible,
444867d70fcSchristos      in theory, for it to be less than the old size, but this is very
445867d70fcSchristos      unlikely.  It cannot be so small that cth_typeoff ends up of negative
446867d70fcSchristos      size.  We validate this with an assertion below.)
447867d70fcSchristos 
448867d70fcSchristos      We must cater not only for changes in vlen and types sizes but also
449867d70fcSchristos      for changes in 'increment', which happen because v2 places some types
450867d70fcSchristos      into ctf_stype_t where v1 would be forced to use the larger non-stype.  */
451867d70fcSchristos 
452867d70fcSchristos   for (tp = tbuf; tp < tend;
453867d70fcSchristos        tp = (ctf_type_v1_t *) ((uintptr_t) tp + increment + vbytes))
454867d70fcSchristos     {
455867d70fcSchristos       unsigned short kind = CTF_V1_INFO_KIND (tp->ctt_info);
456867d70fcSchristos       unsigned long vlen = CTF_V1_INFO_VLEN (tp->ctt_info);
457867d70fcSchristos 
458867d70fcSchristos       size = get_ctt_size_v1 (fp, (const ctf_type_t *) tp, NULL, &increment);
459*c42dbd0eSchristos       vbytes = get_vbytes_v1 (fp, kind, size, vlen);
460867d70fcSchristos 
461867d70fcSchristos       get_ctt_size_v2_unconverted (fp, (const ctf_type_t *) tp, NULL,
462867d70fcSchristos 				   &v2increment);
463*c42dbd0eSchristos       v2bytes = get_vbytes_v2 (fp, kind, size, vlen);
464867d70fcSchristos 
465867d70fcSchristos       if ((vbytes < 0) || (size < 0))
466867d70fcSchristos 	return ECTF_CORRUPT;
467867d70fcSchristos 
468867d70fcSchristos       increase += v2increment - increment;	/* May be negative.  */
469867d70fcSchristos       increase += v2bytes - vbytes;
470867d70fcSchristos     }
471867d70fcSchristos 
472867d70fcSchristos   /* Allocate enough room for the new buffer, then copy everything but the type
473867d70fcSchristos      section into place, and reset the base accordingly.  Leave the version
474867d70fcSchristos      number unchanged, so that LCTF_INFO_* still works on the
475867d70fcSchristos      as-yet-untranslated type info.  */
476867d70fcSchristos 
477867d70fcSchristos   if ((ctf_base = malloc (fp->ctf_size + increase)) == NULL)
478867d70fcSchristos     return ECTF_ZALLOC;
479867d70fcSchristos 
480867d70fcSchristos   /* Start at ctf_buf, not ctf_base, to squeeze out the original header: we
481867d70fcSchristos      never use it and it is unconverted.  */
482867d70fcSchristos 
483867d70fcSchristos   memcpy (ctf_base, fp->ctf_buf, cth->cth_typeoff);
484867d70fcSchristos   memcpy (ctf_base + cth->cth_stroff + increase,
485867d70fcSchristos 	  fp->ctf_buf + cth->cth_stroff, cth->cth_strlen);
486867d70fcSchristos 
487867d70fcSchristos   memset (ctf_base + cth->cth_typeoff, 0, cth->cth_stroff - cth->cth_typeoff
488867d70fcSchristos 	  + increase);
489867d70fcSchristos 
490867d70fcSchristos   cth->cth_stroff += increase;
491867d70fcSchristos   fp->ctf_size += increase;
492867d70fcSchristos   assert (cth->cth_stroff >= cth->cth_typeoff);
493867d70fcSchristos   fp->ctf_base = ctf_base;
494867d70fcSchristos   fp->ctf_buf = ctf_base;
495867d70fcSchristos   fp->ctf_dynbase = ctf_base;
496867d70fcSchristos   ctf_set_base (fp, cth, ctf_base);
497867d70fcSchristos 
498867d70fcSchristos   t2buf = (ctf_type_t *) (fp->ctf_buf + cth->cth_typeoff);
499867d70fcSchristos 
500867d70fcSchristos   /* Iterate through all the types again, upgrading them.
501867d70fcSchristos 
502867d70fcSchristos      Everything that hasn't changed can just be outright memcpy()ed.
503867d70fcSchristos      Things that have changed need field-by-field consideration.  */
504867d70fcSchristos 
505867d70fcSchristos   for (tp = tbuf, t2p = t2buf; tp < tend;
506867d70fcSchristos        tp = (ctf_type_v1_t *) ((uintptr_t) tp + increment + vbytes),
507867d70fcSchristos        t2p = (ctf_type_t *) ((uintptr_t) t2p + v2increment + v2bytes))
508867d70fcSchristos     {
509867d70fcSchristos       unsigned short kind = CTF_V1_INFO_KIND (tp->ctt_info);
510867d70fcSchristos       int isroot = CTF_V1_INFO_ISROOT (tp->ctt_info);
511867d70fcSchristos       unsigned long vlen = CTF_V1_INFO_VLEN (tp->ctt_info);
512867d70fcSchristos       ssize_t v2size;
513867d70fcSchristos       void *vdata, *v2data;
514867d70fcSchristos 
515867d70fcSchristos       size = get_ctt_size_v1 (fp, (const ctf_type_t *) tp, NULL, &increment);
516*c42dbd0eSchristos       vbytes = get_vbytes_v1 (fp, kind, size, vlen);
517867d70fcSchristos 
518867d70fcSchristos       t2p->ctt_name = tp->ctt_name;
519867d70fcSchristos       t2p->ctt_info = CTF_TYPE_INFO (kind, isroot, vlen);
520867d70fcSchristos 
521867d70fcSchristos       switch (kind)
522867d70fcSchristos 	{
523867d70fcSchristos 	case CTF_K_FUNCTION:
524867d70fcSchristos 	case CTF_K_FORWARD:
525867d70fcSchristos 	case CTF_K_TYPEDEF:
526867d70fcSchristos 	case CTF_K_POINTER:
527867d70fcSchristos 	case CTF_K_VOLATILE:
528867d70fcSchristos 	case CTF_K_CONST:
529867d70fcSchristos 	case CTF_K_RESTRICT:
530867d70fcSchristos 	  t2p->ctt_type = tp->ctt_type;
531867d70fcSchristos 	  break;
532867d70fcSchristos 	case CTF_K_INTEGER:
533867d70fcSchristos 	case CTF_K_FLOAT:
534867d70fcSchristos 	case CTF_K_ARRAY:
535867d70fcSchristos 	case CTF_K_STRUCT:
536867d70fcSchristos 	case CTF_K_UNION:
537867d70fcSchristos 	case CTF_K_ENUM:
538867d70fcSchristos 	case CTF_K_UNKNOWN:
539867d70fcSchristos 	  if ((size_t) size <= CTF_MAX_SIZE)
540867d70fcSchristos 	    t2p->ctt_size = size;
541867d70fcSchristos 	  else
542867d70fcSchristos 	    {
543867d70fcSchristos 	      t2p->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
544867d70fcSchristos 	      t2p->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
545867d70fcSchristos 	    }
546867d70fcSchristos 	  break;
547867d70fcSchristos 	}
548867d70fcSchristos 
549867d70fcSchristos       v2size = get_ctt_size_v2 (fp, t2p, NULL, &v2increment);
550*c42dbd0eSchristos       v2bytes = get_vbytes_v2 (fp, kind, v2size, vlen);
551867d70fcSchristos 
552867d70fcSchristos       /* Catch out-of-sync get_ctt_size_*().  The count goes wrong if
553867d70fcSchristos 	 these are not identical (and having them different makes no
554867d70fcSchristos 	 sense semantically).  */
555867d70fcSchristos 
556867d70fcSchristos       assert (size == v2size);
557867d70fcSchristos 
558867d70fcSchristos       /* Now the varlen info.  */
559867d70fcSchristos 
560867d70fcSchristos       vdata = (void *) ((uintptr_t) tp + increment);
561867d70fcSchristos       v2data = (void *) ((uintptr_t) t2p + v2increment);
562867d70fcSchristos 
563867d70fcSchristos       switch (kind)
564867d70fcSchristos 	{
565867d70fcSchristos 	case CTF_K_ARRAY:
566867d70fcSchristos 	  {
567867d70fcSchristos 	    const ctf_array_v1_t *ap = (const ctf_array_v1_t *) vdata;
568867d70fcSchristos 	    ctf_array_t *a2p = (ctf_array_t *) v2data;
569867d70fcSchristos 
570867d70fcSchristos 	    a2p->cta_contents = ap->cta_contents;
571867d70fcSchristos 	    a2p->cta_index = ap->cta_index;
572867d70fcSchristos 	    a2p->cta_nelems = ap->cta_nelems;
573867d70fcSchristos 	    break;
574867d70fcSchristos 	  }
575867d70fcSchristos 	case CTF_K_STRUCT:
576867d70fcSchristos 	case CTF_K_UNION:
577867d70fcSchristos 	  {
578867d70fcSchristos 	    ctf_member_t tmp;
579867d70fcSchristos 	    const ctf_member_v1_t *m1 = (const ctf_member_v1_t *) vdata;
580867d70fcSchristos 	    const ctf_lmember_v1_t *lm1 = (const ctf_lmember_v1_t *) m1;
581867d70fcSchristos 	    ctf_member_t *m2 = (ctf_member_t *) v2data;
582867d70fcSchristos 	    ctf_lmember_t *lm2 = (ctf_lmember_t *) m2;
583867d70fcSchristos 	    unsigned long i;
584867d70fcSchristos 
585867d70fcSchristos 	    /* We walk all four pointers forward, but only reference the two
586867d70fcSchristos 	       that are valid for the given size, to avoid quadruplicating all
587867d70fcSchristos 	       the code.  */
588867d70fcSchristos 
589867d70fcSchristos 	    for (i = vlen; i != 0; i--, m1++, lm1++, m2++, lm2++)
590867d70fcSchristos 	      {
591867d70fcSchristos 		size_t offset;
592867d70fcSchristos 		if (size < CTF_LSTRUCT_THRESH_V1)
593867d70fcSchristos 		  {
594867d70fcSchristos 		    offset = m1->ctm_offset;
595867d70fcSchristos 		    tmp.ctm_name = m1->ctm_name;
596867d70fcSchristos 		    tmp.ctm_type = m1->ctm_type;
597867d70fcSchristos 		  }
598867d70fcSchristos 		else
599867d70fcSchristos 		  {
600867d70fcSchristos 		    offset = CTF_LMEM_OFFSET (lm1);
601867d70fcSchristos 		    tmp.ctm_name = lm1->ctlm_name;
602867d70fcSchristos 		    tmp.ctm_type = lm1->ctlm_type;
603867d70fcSchristos 		  }
604867d70fcSchristos 		if (size < CTF_LSTRUCT_THRESH)
605867d70fcSchristos 		  {
606867d70fcSchristos 		    m2->ctm_name = tmp.ctm_name;
607867d70fcSchristos 		    m2->ctm_type = tmp.ctm_type;
608867d70fcSchristos 		    m2->ctm_offset = offset;
609867d70fcSchristos 		  }
610867d70fcSchristos 		else
611867d70fcSchristos 		  {
612867d70fcSchristos 		    lm2->ctlm_name = tmp.ctm_name;
613867d70fcSchristos 		    lm2->ctlm_type = tmp.ctm_type;
614867d70fcSchristos 		    lm2->ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (offset);
615867d70fcSchristos 		    lm2->ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (offset);
616867d70fcSchristos 		  }
617867d70fcSchristos 	      }
618867d70fcSchristos 	    break;
619867d70fcSchristos 	  }
620867d70fcSchristos 	case CTF_K_FUNCTION:
621867d70fcSchristos 	  {
622867d70fcSchristos 	    unsigned long i;
623867d70fcSchristos 	    unsigned short *a1 = (unsigned short *) vdata;
624867d70fcSchristos 	    uint32_t *a2 = (uint32_t *) v2data;
625867d70fcSchristos 
626867d70fcSchristos 	    for (i = vlen; i != 0; i--, a1++, a2++)
627867d70fcSchristos 	      *a2 = *a1;
628867d70fcSchristos 	  }
629867d70fcSchristos 	/* FALLTHRU */
630867d70fcSchristos 	default:
631867d70fcSchristos 	  /* Catch out-of-sync get_vbytes_*().  */
632867d70fcSchristos 	  assert (vbytes == v2bytes);
633867d70fcSchristos 	  memcpy (v2data, vdata, vbytes);
634867d70fcSchristos 	}
635867d70fcSchristos     }
636867d70fcSchristos 
637867d70fcSchristos   /* Verify that the entire region was converted.  If not, we are either
638867d70fcSchristos      converting too much, or too little (leading to a buffer overrun either here
639867d70fcSchristos      or at read time, in init_types().) */
640867d70fcSchristos 
641867d70fcSchristos   assert ((size_t) t2p - (size_t) fp->ctf_buf == cth->cth_stroff);
642867d70fcSchristos 
643867d70fcSchristos   ctf_set_version (fp, cth, CTF_VERSION_1_UPGRADED_3);
644867d70fcSchristos   free (old_ctf_base);
645867d70fcSchristos 
646867d70fcSchristos   return 0;
647867d70fcSchristos }
648867d70fcSchristos 
649867d70fcSchristos /* Upgrade from any earlier version.  */
650867d70fcSchristos static int
upgrade_types(ctf_dict_t * fp,ctf_header_t * cth)651*c42dbd0eSchristos upgrade_types (ctf_dict_t *fp, ctf_header_t *cth)
652867d70fcSchristos {
653867d70fcSchristos   switch (cth->cth_version)
654867d70fcSchristos     {
655867d70fcSchristos       /* v1 requires a full pass and reformatting.  */
656867d70fcSchristos     case CTF_VERSION_1:
657867d70fcSchristos       upgrade_types_v1 (fp, cth);
658867d70fcSchristos       /* FALLTHRU */
659867d70fcSchristos       /* Already-converted v1 is just like later versions except that its
660867d70fcSchristos 	 parent/child boundary is unchanged (and much lower).  */
661867d70fcSchristos 
662867d70fcSchristos     case CTF_VERSION_1_UPGRADED_3:
663867d70fcSchristos       fp->ctf_parmax = CTF_MAX_PTYPE_V1;
664867d70fcSchristos 
665867d70fcSchristos       /* v2 is just the same as v3 except for new types and sections:
666867d70fcSchristos 	 no upgrading required. */
667867d70fcSchristos     case CTF_VERSION_2: ;
668867d70fcSchristos       /* FALLTHRU */
669867d70fcSchristos     }
670867d70fcSchristos   return 0;
671867d70fcSchristos }
672867d70fcSchristos 
673867d70fcSchristos /* Initialize the type ID translation table with the byte offset of each type,
674867d70fcSchristos    and initialize the hash tables of each named type.  Upgrade the type table to
675867d70fcSchristos    the latest supported representation in the process, if needed, and if this
676867d70fcSchristos    recension of libctf supports upgrading.  */
677867d70fcSchristos 
678867d70fcSchristos static int
init_types(ctf_dict_t * fp,ctf_header_t * cth)679*c42dbd0eSchristos init_types (ctf_dict_t *fp, ctf_header_t *cth)
680867d70fcSchristos {
681867d70fcSchristos   const ctf_type_t *tbuf;
682867d70fcSchristos   const ctf_type_t *tend;
683867d70fcSchristos 
684867d70fcSchristos   unsigned long pop[CTF_K_MAX + 1] = { 0 };
685867d70fcSchristos   const ctf_type_t *tp;
686*c42dbd0eSchristos   uint32_t id;
687867d70fcSchristos   uint32_t *xp;
688867d70fcSchristos 
689*c42dbd0eSchristos   /* We determine whether the dict is a child or a parent based on the value of
690*c42dbd0eSchristos      cth_parname.  */
691867d70fcSchristos 
692867d70fcSchristos   int child = cth->cth_parname != 0;
693867d70fcSchristos   int nlstructs = 0, nlunions = 0;
694867d70fcSchristos   int err;
695867d70fcSchristos 
696867d70fcSchristos   assert (!(fp->ctf_flags & LCTF_RDWR));
697867d70fcSchristos 
698867d70fcSchristos   if (_libctf_unlikely_ (fp->ctf_version == CTF_VERSION_1))
699867d70fcSchristos     {
700867d70fcSchristos       int err;
701867d70fcSchristos       if ((err = upgrade_types (fp, cth)) != 0)
702867d70fcSchristos 	return err;				/* Upgrade failed.  */
703867d70fcSchristos     }
704867d70fcSchristos 
705867d70fcSchristos   tbuf = (ctf_type_t *) (fp->ctf_buf + cth->cth_typeoff);
706867d70fcSchristos   tend = (ctf_type_t *) (fp->ctf_buf + cth->cth_stroff);
707867d70fcSchristos 
708867d70fcSchristos   /* We make two passes through the entire type section.  In this first
709867d70fcSchristos      pass, we count the number of each type and the total number of types.  */
710867d70fcSchristos 
711867d70fcSchristos   for (tp = tbuf; tp < tend; fp->ctf_typemax++)
712867d70fcSchristos     {
713867d70fcSchristos       unsigned short kind = LCTF_INFO_KIND (fp, tp->ctt_info);
714867d70fcSchristos       unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
715867d70fcSchristos       ssize_t size, increment, vbytes;
716867d70fcSchristos 
717867d70fcSchristos       (void) ctf_get_ctt_size (fp, tp, &size, &increment);
718867d70fcSchristos       vbytes = LCTF_VBYTES (fp, kind, size, vlen);
719867d70fcSchristos 
720867d70fcSchristos       if (vbytes < 0)
721867d70fcSchristos 	return ECTF_CORRUPT;
722867d70fcSchristos 
723867d70fcSchristos       /* For forward declarations, ctt_type is the CTF_K_* kind for the tag,
724*c42dbd0eSchristos 	 so bump that population count too.  */
725*c42dbd0eSchristos       if (kind == CTF_K_FORWARD)
726867d70fcSchristos 	pop[tp->ctt_type]++;
727*c42dbd0eSchristos 
728867d70fcSchristos       tp = (ctf_type_t *) ((uintptr_t) tp + increment + vbytes);
729867d70fcSchristos       pop[kind]++;
730867d70fcSchristos     }
731867d70fcSchristos 
732867d70fcSchristos   if (child)
733867d70fcSchristos     {
734*c42dbd0eSchristos       ctf_dprintf ("CTF dict %p is a child\n", (void *) fp);
735867d70fcSchristos       fp->ctf_flags |= LCTF_CHILD;
736867d70fcSchristos     }
737867d70fcSchristos   else
738*c42dbd0eSchristos     ctf_dprintf ("CTF dict %p is a parent\n", (void *) fp);
739867d70fcSchristos 
740867d70fcSchristos   /* Now that we've counted up the number of each type, we can allocate
741867d70fcSchristos      the hash tables, type translation table, and pointer table.  */
742867d70fcSchristos 
743867d70fcSchristos   if ((fp->ctf_structs.ctn_readonly
744867d70fcSchristos        = ctf_hash_create (pop[CTF_K_STRUCT], ctf_hash_string,
745867d70fcSchristos 			  ctf_hash_eq_string)) == NULL)
746867d70fcSchristos     return ENOMEM;
747867d70fcSchristos 
748867d70fcSchristos   if ((fp->ctf_unions.ctn_readonly
749867d70fcSchristos        = ctf_hash_create (pop[CTF_K_UNION], ctf_hash_string,
750867d70fcSchristos 			  ctf_hash_eq_string)) == NULL)
751867d70fcSchristos     return ENOMEM;
752867d70fcSchristos 
753867d70fcSchristos   if ((fp->ctf_enums.ctn_readonly
754867d70fcSchristos        = ctf_hash_create (pop[CTF_K_ENUM], ctf_hash_string,
755867d70fcSchristos 			  ctf_hash_eq_string)) == NULL)
756867d70fcSchristos     return ENOMEM;
757867d70fcSchristos 
758867d70fcSchristos   if ((fp->ctf_names.ctn_readonly
759*c42dbd0eSchristos        = ctf_hash_create (pop[CTF_K_UNKNOWN] +
760*c42dbd0eSchristos 			  pop[CTF_K_INTEGER] +
761867d70fcSchristos 			  pop[CTF_K_FLOAT] +
762867d70fcSchristos 			  pop[CTF_K_FUNCTION] +
763867d70fcSchristos 			  pop[CTF_K_TYPEDEF] +
764867d70fcSchristos 			  pop[CTF_K_POINTER] +
765867d70fcSchristos 			  pop[CTF_K_VOLATILE] +
766867d70fcSchristos 			  pop[CTF_K_CONST] +
767867d70fcSchristos 			  pop[CTF_K_RESTRICT],
768867d70fcSchristos 			  ctf_hash_string,
769867d70fcSchristos 			  ctf_hash_eq_string)) == NULL)
770867d70fcSchristos     return ENOMEM;
771867d70fcSchristos 
772867d70fcSchristos   fp->ctf_txlate = malloc (sizeof (uint32_t) * (fp->ctf_typemax + 1));
773867d70fcSchristos   fp->ctf_ptrtab_len = fp->ctf_typemax + 1;
774867d70fcSchristos   fp->ctf_ptrtab = malloc (sizeof (uint32_t) * fp->ctf_ptrtab_len);
775867d70fcSchristos 
776867d70fcSchristos   if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL)
777867d70fcSchristos     return ENOMEM;		/* Memory allocation failed.  */
778867d70fcSchristos 
779867d70fcSchristos   xp = fp->ctf_txlate;
780867d70fcSchristos   *xp++ = 0;			/* Type id 0 is used as a sentinel value.  */
781867d70fcSchristos 
782867d70fcSchristos   memset (fp->ctf_txlate, 0, sizeof (uint32_t) * (fp->ctf_typemax + 1));
783867d70fcSchristos   memset (fp->ctf_ptrtab, 0, sizeof (uint32_t) * (fp->ctf_typemax + 1));
784867d70fcSchristos 
785867d70fcSchristos   /* In the second pass through the types, we fill in each entry of the
786867d70fcSchristos      type and pointer tables and add names to the appropriate hashes.  */
787867d70fcSchristos 
788867d70fcSchristos   for (id = 1, tp = tbuf; tp < tend; xp++, id++)
789867d70fcSchristos     {
790867d70fcSchristos       unsigned short kind = LCTF_INFO_KIND (fp, tp->ctt_info);
791*c42dbd0eSchristos       unsigned short isroot = LCTF_INFO_ISROOT (fp, tp->ctt_info);
792867d70fcSchristos       unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
793867d70fcSchristos       ssize_t size, increment, vbytes;
794867d70fcSchristos 
795867d70fcSchristos       const char *name;
796867d70fcSchristos 
797867d70fcSchristos       (void) ctf_get_ctt_size (fp, tp, &size, &increment);
798867d70fcSchristos       name = ctf_strptr (fp, tp->ctt_name);
799*c42dbd0eSchristos       /* Cannot fail: shielded by call in loop above.  */
800867d70fcSchristos       vbytes = LCTF_VBYTES (fp, kind, size, vlen);
801867d70fcSchristos 
802867d70fcSchristos       switch (kind)
803867d70fcSchristos 	{
804*c42dbd0eSchristos 	case CTF_K_UNKNOWN:
805867d70fcSchristos 	case CTF_K_INTEGER:
806867d70fcSchristos 	case CTF_K_FLOAT:
807867d70fcSchristos 	  /* Names are reused by bit-fields, which are differentiated by their
808867d70fcSchristos 	     encodings, and so typically we'd record only the first instance of
809867d70fcSchristos 	     a given intrinsic.  However, we replace an existing type with a
810867d70fcSchristos 	     root-visible version so that we can be sure to find it when
811867d70fcSchristos 	     checking for conflicting definitions in ctf_add_type().  */
812867d70fcSchristos 
813867d70fcSchristos 	  if (((ctf_hash_lookup_type (fp->ctf_names.ctn_readonly,
814867d70fcSchristos 				      fp, name)) == 0)
815*c42dbd0eSchristos 	      || isroot)
816867d70fcSchristos 	    {
817867d70fcSchristos 	      err = ctf_hash_define_type (fp->ctf_names.ctn_readonly, fp,
818867d70fcSchristos 					  LCTF_INDEX_TO_TYPE (fp, id, child),
819867d70fcSchristos 					  tp->ctt_name);
820867d70fcSchristos 	      if (err != 0)
821867d70fcSchristos 		return err;
822867d70fcSchristos 	    }
823867d70fcSchristos 	  break;
824867d70fcSchristos 
825867d70fcSchristos 	  /* These kinds have no name, so do not need interning into any
826867d70fcSchristos 	     hashtables.  */
827867d70fcSchristos 	case CTF_K_ARRAY:
828867d70fcSchristos 	case CTF_K_SLICE:
829867d70fcSchristos 	  break;
830867d70fcSchristos 
831867d70fcSchristos 	case CTF_K_FUNCTION:
832*c42dbd0eSchristos 	  if (!isroot)
833*c42dbd0eSchristos 	    break;
834*c42dbd0eSchristos 
835867d70fcSchristos 	  err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
836867d70fcSchristos 				      LCTF_INDEX_TO_TYPE (fp, id, child),
837867d70fcSchristos 				      tp->ctt_name);
838867d70fcSchristos 	  if (err != 0)
839867d70fcSchristos 	    return err;
840867d70fcSchristos 	  break;
841867d70fcSchristos 
842867d70fcSchristos 	case CTF_K_STRUCT:
843*c42dbd0eSchristos 	  if (size >= CTF_LSTRUCT_THRESH)
844*c42dbd0eSchristos 	    nlstructs++;
845*c42dbd0eSchristos 
846*c42dbd0eSchristos 	  if (!isroot)
847*c42dbd0eSchristos 	    break;
848*c42dbd0eSchristos 
849867d70fcSchristos 	  err = ctf_hash_define_type (fp->ctf_structs.ctn_readonly, fp,
850867d70fcSchristos 				      LCTF_INDEX_TO_TYPE (fp, id, child),
851867d70fcSchristos 				      tp->ctt_name);
852867d70fcSchristos 
853867d70fcSchristos 	  if (err != 0)
854867d70fcSchristos 	    return err;
855867d70fcSchristos 
856867d70fcSchristos 	  break;
857867d70fcSchristos 
858867d70fcSchristos 	case CTF_K_UNION:
859*c42dbd0eSchristos 	  if (size >= CTF_LSTRUCT_THRESH)
860*c42dbd0eSchristos 	    nlunions++;
861*c42dbd0eSchristos 
862*c42dbd0eSchristos 	  if (!isroot)
863*c42dbd0eSchristos 	    break;
864*c42dbd0eSchristos 
865867d70fcSchristos 	  err = ctf_hash_define_type (fp->ctf_unions.ctn_readonly, fp,
866867d70fcSchristos 				      LCTF_INDEX_TO_TYPE (fp, id, child),
867867d70fcSchristos 				      tp->ctt_name);
868867d70fcSchristos 
869867d70fcSchristos 	  if (err != 0)
870867d70fcSchristos 	    return err;
871867d70fcSchristos 	  break;
872867d70fcSchristos 
873867d70fcSchristos 	case CTF_K_ENUM:
874*c42dbd0eSchristos 	  if (!isroot)
875*c42dbd0eSchristos 	    break;
876*c42dbd0eSchristos 
877867d70fcSchristos 	  err = ctf_hash_define_type (fp->ctf_enums.ctn_readonly, fp,
878867d70fcSchristos 				      LCTF_INDEX_TO_TYPE (fp, id, child),
879867d70fcSchristos 				      tp->ctt_name);
880867d70fcSchristos 
881867d70fcSchristos 	  if (err != 0)
882867d70fcSchristos 	    return err;
883867d70fcSchristos 	  break;
884867d70fcSchristos 
885867d70fcSchristos 	case CTF_K_TYPEDEF:
886*c42dbd0eSchristos 	  if (!isroot)
887*c42dbd0eSchristos 	    break;
888*c42dbd0eSchristos 
889867d70fcSchristos 	  err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
890867d70fcSchristos 				      LCTF_INDEX_TO_TYPE (fp, id, child),
891867d70fcSchristos 				      tp->ctt_name);
892867d70fcSchristos 	  if (err != 0)
893867d70fcSchristos 	    return err;
894867d70fcSchristos 	  break;
895867d70fcSchristos 
896867d70fcSchristos 	case CTF_K_FORWARD:
897867d70fcSchristos 	  {
898867d70fcSchristos 	    ctf_names_t *np = ctf_name_table (fp, tp->ctt_type);
899*c42dbd0eSchristos 
900*c42dbd0eSchristos 	    if (!isroot)
901*c42dbd0eSchristos 	      break;
902*c42dbd0eSchristos 
903867d70fcSchristos 	    /* Only insert forward tags into the given hash if the type or tag
904867d70fcSchristos 	       name is not already present.  */
905867d70fcSchristos 	    if (ctf_hash_lookup_type (np->ctn_readonly, fp, name) == 0)
906867d70fcSchristos 	      {
907867d70fcSchristos 		err = ctf_hash_insert_type (np->ctn_readonly, fp,
908867d70fcSchristos 					    LCTF_INDEX_TO_TYPE (fp, id, child),
909867d70fcSchristos 					    tp->ctt_name);
910867d70fcSchristos 		if (err != 0)
911867d70fcSchristos 		  return err;
912867d70fcSchristos 	      }
913867d70fcSchristos 	    break;
914867d70fcSchristos 	  }
915867d70fcSchristos 
916867d70fcSchristos 	case CTF_K_POINTER:
917*c42dbd0eSchristos 	  /* If the type referenced by the pointer is in this CTF dict, then
918*c42dbd0eSchristos 	     store the index of the pointer type in fp->ctf_ptrtab[ index of
919*c42dbd0eSchristos 	     referenced type ].  */
920867d70fcSchristos 
921867d70fcSchristos 	  if (LCTF_TYPE_ISCHILD (fp, tp->ctt_type) == child
922867d70fcSchristos 	      && LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax)
923867d70fcSchristos 	    fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = id;
924867d70fcSchristos 	 /*FALLTHRU*/
925867d70fcSchristos 
926867d70fcSchristos 	case CTF_K_VOLATILE:
927867d70fcSchristos 	case CTF_K_CONST:
928867d70fcSchristos 	case CTF_K_RESTRICT:
929*c42dbd0eSchristos 	  if (!isroot)
930*c42dbd0eSchristos 	    break;
931*c42dbd0eSchristos 
932867d70fcSchristos 	  err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
933867d70fcSchristos 				      LCTF_INDEX_TO_TYPE (fp, id, child),
934867d70fcSchristos 				      tp->ctt_name);
935867d70fcSchristos 	  if (err != 0)
936867d70fcSchristos 	    return err;
937867d70fcSchristos 	  break;
938867d70fcSchristos 	default:
939*c42dbd0eSchristos 	  ctf_err_warn (fp, 0, ECTF_CORRUPT,
940*c42dbd0eSchristos 			_("init_types(): unhandled CTF kind: %x"), kind);
941867d70fcSchristos 	  return ECTF_CORRUPT;
942867d70fcSchristos 	}
943867d70fcSchristos 
944867d70fcSchristos       *xp = (uint32_t) ((uintptr_t) tp - (uintptr_t) fp->ctf_buf);
945867d70fcSchristos       tp = (ctf_type_t *) ((uintptr_t) tp + increment + vbytes);
946867d70fcSchristos     }
947867d70fcSchristos 
948867d70fcSchristos   ctf_dprintf ("%lu total types processed\n", fp->ctf_typemax);
949867d70fcSchristos   ctf_dprintf ("%u enum names hashed\n",
950867d70fcSchristos 	       ctf_hash_size (fp->ctf_enums.ctn_readonly));
951867d70fcSchristos   ctf_dprintf ("%u struct names hashed (%d long)\n",
952867d70fcSchristos 	       ctf_hash_size (fp->ctf_structs.ctn_readonly), nlstructs);
953867d70fcSchristos   ctf_dprintf ("%u union names hashed (%d long)\n",
954867d70fcSchristos 	       ctf_hash_size (fp->ctf_unions.ctn_readonly), nlunions);
955867d70fcSchristos   ctf_dprintf ("%u base type names hashed\n",
956867d70fcSchristos 	       ctf_hash_size (fp->ctf_names.ctn_readonly));
957867d70fcSchristos 
958867d70fcSchristos   return 0;
959867d70fcSchristos }
960867d70fcSchristos 
961867d70fcSchristos /* Endianness-flipping routines.
962867d70fcSchristos 
963867d70fcSchristos    We flip everything, mindlessly, even 1-byte entities, so that future
964867d70fcSchristos    expansions do not require changes to this code.  */
965867d70fcSchristos 
966867d70fcSchristos /* Flip the endianness of the CTF header.  */
967867d70fcSchristos 
968*c42dbd0eSchristos void
ctf_flip_header(ctf_header_t * cth)969*c42dbd0eSchristos ctf_flip_header (ctf_header_t *cth)
970867d70fcSchristos {
971867d70fcSchristos   swap_thing (cth->cth_preamble.ctp_magic);
972867d70fcSchristos   swap_thing (cth->cth_preamble.ctp_version);
973867d70fcSchristos   swap_thing (cth->cth_preamble.ctp_flags);
974867d70fcSchristos   swap_thing (cth->cth_parlabel);
975867d70fcSchristos   swap_thing (cth->cth_parname);
976867d70fcSchristos   swap_thing (cth->cth_cuname);
977867d70fcSchristos   swap_thing (cth->cth_objtoff);
978867d70fcSchristos   swap_thing (cth->cth_funcoff);
979867d70fcSchristos   swap_thing (cth->cth_objtidxoff);
980867d70fcSchristos   swap_thing (cth->cth_funcidxoff);
981867d70fcSchristos   swap_thing (cth->cth_varoff);
982867d70fcSchristos   swap_thing (cth->cth_typeoff);
983867d70fcSchristos   swap_thing (cth->cth_stroff);
984867d70fcSchristos   swap_thing (cth->cth_strlen);
985867d70fcSchristos }
986867d70fcSchristos 
987867d70fcSchristos /* Flip the endianness of the label section, an array of ctf_lblent_t.  */
988867d70fcSchristos 
989867d70fcSchristos static void
flip_lbls(void * start,size_t len)990867d70fcSchristos flip_lbls (void *start, size_t len)
991867d70fcSchristos {
992867d70fcSchristos   ctf_lblent_t *lbl = start;
993867d70fcSchristos   ssize_t i;
994867d70fcSchristos 
995867d70fcSchristos   for (i = len / sizeof (struct ctf_lblent); i > 0; lbl++, i--)
996867d70fcSchristos     {
997867d70fcSchristos       swap_thing (lbl->ctl_label);
998867d70fcSchristos       swap_thing (lbl->ctl_type);
999867d70fcSchristos     }
1000867d70fcSchristos }
1001867d70fcSchristos 
1002867d70fcSchristos /* Flip the endianness of the data-object or function sections or their indexes,
1003*c42dbd0eSchristos    all arrays of uint32_t.  */
1004867d70fcSchristos 
1005867d70fcSchristos static void
flip_objts(void * start,size_t len)1006867d70fcSchristos flip_objts (void *start, size_t len)
1007867d70fcSchristos {
1008867d70fcSchristos   uint32_t *obj = start;
1009867d70fcSchristos   ssize_t i;
1010867d70fcSchristos 
1011867d70fcSchristos   for (i = len / sizeof (uint32_t); i > 0; obj++, i--)
1012867d70fcSchristos       swap_thing (*obj);
1013867d70fcSchristos }
1014867d70fcSchristos 
1015867d70fcSchristos /* Flip the endianness of the variable section, an array of ctf_varent_t.  */
1016867d70fcSchristos 
1017867d70fcSchristos static void
flip_vars(void * start,size_t len)1018867d70fcSchristos flip_vars (void *start, size_t len)
1019867d70fcSchristos {
1020867d70fcSchristos   ctf_varent_t *var = start;
1021867d70fcSchristos   ssize_t i;
1022867d70fcSchristos 
1023867d70fcSchristos   for (i = len / sizeof (struct ctf_varent); i > 0; var++, i--)
1024867d70fcSchristos     {
1025867d70fcSchristos       swap_thing (var->ctv_name);
1026867d70fcSchristos       swap_thing (var->ctv_type);
1027867d70fcSchristos     }
1028867d70fcSchristos }
1029867d70fcSchristos 
1030867d70fcSchristos /* Flip the endianness of the type section, a tagged array of ctf_type or
1031867d70fcSchristos    ctf_stype followed by variable data.  */
1032867d70fcSchristos 
1033867d70fcSchristos static int
flip_types(ctf_dict_t * fp,void * start,size_t len,int to_foreign)1034*c42dbd0eSchristos flip_types (ctf_dict_t *fp, void *start, size_t len, int to_foreign)
1035867d70fcSchristos {
1036867d70fcSchristos   ctf_type_t *t = start;
1037867d70fcSchristos 
1038867d70fcSchristos   while ((uintptr_t) t < ((uintptr_t) start) + len)
1039867d70fcSchristos     {
1040*c42dbd0eSchristos       uint32_t kind;
1041*c42dbd0eSchristos       size_t size;
1042*c42dbd0eSchristos       uint32_t vlen;
1043*c42dbd0eSchristos       size_t vbytes;
1044*c42dbd0eSchristos 
1045*c42dbd0eSchristos       if (to_foreign)
1046*c42dbd0eSchristos 	{
1047*c42dbd0eSchristos 	  kind = CTF_V2_INFO_KIND (t->ctt_info);
1048*c42dbd0eSchristos 	  size = t->ctt_size;
1049*c42dbd0eSchristos 	  vlen = CTF_V2_INFO_VLEN (t->ctt_info);
1050*c42dbd0eSchristos 	  vbytes = get_vbytes_v2 (fp, kind, size, vlen);
1051*c42dbd0eSchristos 	}
1052*c42dbd0eSchristos 
1053867d70fcSchristos       swap_thing (t->ctt_name);
1054867d70fcSchristos       swap_thing (t->ctt_info);
1055867d70fcSchristos       swap_thing (t->ctt_size);
1056867d70fcSchristos 
1057*c42dbd0eSchristos       if (!to_foreign)
1058*c42dbd0eSchristos 	{
1059*c42dbd0eSchristos 	  kind = CTF_V2_INFO_KIND (t->ctt_info);
1060*c42dbd0eSchristos 	  size = t->ctt_size;
1061*c42dbd0eSchristos 	  vlen = CTF_V2_INFO_VLEN (t->ctt_info);
1062*c42dbd0eSchristos 	  vbytes = get_vbytes_v2 (fp, kind, size, vlen);
1063*c42dbd0eSchristos 	}
1064867d70fcSchristos 
1065867d70fcSchristos       if (_libctf_unlikely_ (size == CTF_LSIZE_SENT))
1066867d70fcSchristos 	{
1067*c42dbd0eSchristos 	  if (to_foreign)
1068*c42dbd0eSchristos 	    size = CTF_TYPE_LSIZE (t);
1069*c42dbd0eSchristos 
1070867d70fcSchristos 	  swap_thing (t->ctt_lsizehi);
1071867d70fcSchristos 	  swap_thing (t->ctt_lsizelo);
1072*c42dbd0eSchristos 
1073*c42dbd0eSchristos 	  if (!to_foreign)
1074867d70fcSchristos 	    size = CTF_TYPE_LSIZE (t);
1075*c42dbd0eSchristos 
1076867d70fcSchristos 	  t = (ctf_type_t *) ((uintptr_t) t + sizeof (ctf_type_t));
1077867d70fcSchristos 	}
1078867d70fcSchristos       else
1079867d70fcSchristos 	t = (ctf_type_t *) ((uintptr_t) t + sizeof (ctf_stype_t));
1080867d70fcSchristos 
1081867d70fcSchristos       switch (kind)
1082867d70fcSchristos 	{
1083867d70fcSchristos 	case CTF_K_FORWARD:
1084867d70fcSchristos 	case CTF_K_UNKNOWN:
1085867d70fcSchristos 	case CTF_K_POINTER:
1086867d70fcSchristos 	case CTF_K_TYPEDEF:
1087867d70fcSchristos 	case CTF_K_VOLATILE:
1088867d70fcSchristos 	case CTF_K_CONST:
1089867d70fcSchristos 	case CTF_K_RESTRICT:
1090867d70fcSchristos 	  /* These types have no vlen data to swap.  */
1091867d70fcSchristos 	  assert (vbytes == 0);
1092867d70fcSchristos 	  break;
1093867d70fcSchristos 
1094867d70fcSchristos 	case CTF_K_INTEGER:
1095867d70fcSchristos 	case CTF_K_FLOAT:
1096867d70fcSchristos 	  {
1097867d70fcSchristos 	    /* These types have a single uint32_t.  */
1098867d70fcSchristos 
1099867d70fcSchristos 	    uint32_t *item = (uint32_t *) t;
1100867d70fcSchristos 
1101867d70fcSchristos 	    swap_thing (*item);
1102867d70fcSchristos 	    break;
1103867d70fcSchristos 	  }
1104867d70fcSchristos 
1105867d70fcSchristos 	case CTF_K_FUNCTION:
1106867d70fcSchristos 	  {
1107867d70fcSchristos 	    /* This type has a bunch of uint32_ts.  */
1108867d70fcSchristos 
1109867d70fcSchristos 	    uint32_t *item = (uint32_t *) t;
1110867d70fcSchristos 	    ssize_t i;
1111867d70fcSchristos 
1112867d70fcSchristos 	    for (i = vlen; i > 0; item++, i--)
1113867d70fcSchristos 	      swap_thing (*item);
1114867d70fcSchristos 	    break;
1115867d70fcSchristos 	  }
1116867d70fcSchristos 
1117867d70fcSchristos 	case CTF_K_ARRAY:
1118867d70fcSchristos 	  {
1119867d70fcSchristos 	    /* This has a single ctf_array_t.  */
1120867d70fcSchristos 
1121867d70fcSchristos 	    ctf_array_t *a = (ctf_array_t *) t;
1122867d70fcSchristos 
1123867d70fcSchristos 	    assert (vbytes == sizeof (ctf_array_t));
1124867d70fcSchristos 	    swap_thing (a->cta_contents);
1125867d70fcSchristos 	    swap_thing (a->cta_index);
1126867d70fcSchristos 	    swap_thing (a->cta_nelems);
1127867d70fcSchristos 
1128867d70fcSchristos 	    break;
1129867d70fcSchristos 	  }
1130867d70fcSchristos 
1131867d70fcSchristos 	case CTF_K_SLICE:
1132867d70fcSchristos 	  {
1133867d70fcSchristos 	    /* This has a single ctf_slice_t.  */
1134867d70fcSchristos 
1135867d70fcSchristos 	    ctf_slice_t *s = (ctf_slice_t *) t;
1136867d70fcSchristos 
1137867d70fcSchristos 	    assert (vbytes == sizeof (ctf_slice_t));
1138867d70fcSchristos 	    swap_thing (s->cts_type);
1139867d70fcSchristos 	    swap_thing (s->cts_offset);
1140867d70fcSchristos 	    swap_thing (s->cts_bits);
1141867d70fcSchristos 
1142867d70fcSchristos 	    break;
1143867d70fcSchristos 	  }
1144867d70fcSchristos 
1145867d70fcSchristos 	case CTF_K_STRUCT:
1146867d70fcSchristos 	case CTF_K_UNION:
1147867d70fcSchristos 	  {
1148867d70fcSchristos 	    /* This has an array of ctf_member or ctf_lmember, depending on
1149867d70fcSchristos 	       size.  We could consider it to be a simple array of uint32_t,
1150867d70fcSchristos 	       but for safety's sake in case these structures ever acquire
1151867d70fcSchristos 	       non-uint32_t members, do it member by member.  */
1152867d70fcSchristos 
1153867d70fcSchristos 	    if (_libctf_unlikely_ (size >= CTF_LSTRUCT_THRESH))
1154867d70fcSchristos 	      {
1155867d70fcSchristos 		ctf_lmember_t *lm = (ctf_lmember_t *) t;
1156867d70fcSchristos 		ssize_t i;
1157867d70fcSchristos 		for (i = vlen; i > 0; i--, lm++)
1158867d70fcSchristos 		  {
1159867d70fcSchristos 		    swap_thing (lm->ctlm_name);
1160867d70fcSchristos 		    swap_thing (lm->ctlm_offsethi);
1161867d70fcSchristos 		    swap_thing (lm->ctlm_type);
1162867d70fcSchristos 		    swap_thing (lm->ctlm_offsetlo);
1163867d70fcSchristos 		  }
1164867d70fcSchristos 	      }
1165867d70fcSchristos 	    else
1166867d70fcSchristos 	      {
1167867d70fcSchristos 		ctf_member_t *m = (ctf_member_t *) t;
1168867d70fcSchristos 		ssize_t i;
1169867d70fcSchristos 		for (i = vlen; i > 0; i--, m++)
1170867d70fcSchristos 		  {
1171867d70fcSchristos 		    swap_thing (m->ctm_name);
1172867d70fcSchristos 		    swap_thing (m->ctm_offset);
1173867d70fcSchristos 		    swap_thing (m->ctm_type);
1174867d70fcSchristos 		  }
1175867d70fcSchristos 	      }
1176867d70fcSchristos 	    break;
1177867d70fcSchristos 	  }
1178867d70fcSchristos 
1179867d70fcSchristos 	case CTF_K_ENUM:
1180867d70fcSchristos 	  {
1181867d70fcSchristos 	    /* This has an array of ctf_enum_t.  */
1182867d70fcSchristos 
1183867d70fcSchristos 	    ctf_enum_t *item = (ctf_enum_t *) t;
1184867d70fcSchristos 	    ssize_t i;
1185867d70fcSchristos 
1186867d70fcSchristos 	    for (i = vlen; i > 0; item++, i--)
1187867d70fcSchristos 	      {
1188867d70fcSchristos 		swap_thing (item->cte_name);
1189867d70fcSchristos 		swap_thing (item->cte_value);
1190867d70fcSchristos 	      }
1191867d70fcSchristos 	    break;
1192867d70fcSchristos 	  }
1193867d70fcSchristos 	default:
1194*c42dbd0eSchristos 	  ctf_err_warn (fp, 0, ECTF_CORRUPT,
1195*c42dbd0eSchristos 			_("unhandled CTF kind in endianness conversion: %x"),
1196867d70fcSchristos 			kind);
1197867d70fcSchristos 	  return ECTF_CORRUPT;
1198867d70fcSchristos 	}
1199867d70fcSchristos 
1200867d70fcSchristos       t = (ctf_type_t *) ((uintptr_t) t + vbytes);
1201867d70fcSchristos     }
1202867d70fcSchristos 
1203867d70fcSchristos   return 0;
1204867d70fcSchristos }
1205867d70fcSchristos 
1206867d70fcSchristos /* Flip the endianness of BUF, given the offsets in the (already endian-
1207*c42dbd0eSchristos    converted) CTH.  If TO_FOREIGN is set, flip to foreign-endianness; if not,
1208*c42dbd0eSchristos    flip away.
1209867d70fcSchristos 
1210867d70fcSchristos    All of this stuff happens before the header is fully initialized, so the
1211867d70fcSchristos    LCTF_*() macros cannot be used yet.  Since we do not try to endian-convert v1
1212867d70fcSchristos    data, this is no real loss.  */
1213867d70fcSchristos 
1214*c42dbd0eSchristos int
ctf_flip(ctf_dict_t * fp,ctf_header_t * cth,unsigned char * buf,int to_foreign)1215*c42dbd0eSchristos ctf_flip (ctf_dict_t *fp, ctf_header_t *cth, unsigned char *buf,
1216*c42dbd0eSchristos 	  int to_foreign)
1217867d70fcSchristos {
1218*c42dbd0eSchristos   ctf_dprintf("flipping endianness\n");
1219*c42dbd0eSchristos 
1220867d70fcSchristos   flip_lbls (buf + cth->cth_lbloff, cth->cth_objtoff - cth->cth_lbloff);
1221867d70fcSchristos   flip_objts (buf + cth->cth_objtoff, cth->cth_funcoff - cth->cth_objtoff);
1222867d70fcSchristos   flip_objts (buf + cth->cth_funcoff, cth->cth_objtidxoff - cth->cth_funcoff);
1223867d70fcSchristos   flip_objts (buf + cth->cth_objtidxoff, cth->cth_funcidxoff - cth->cth_objtidxoff);
1224867d70fcSchristos   flip_objts (buf + cth->cth_funcidxoff, cth->cth_varoff - cth->cth_funcidxoff);
1225867d70fcSchristos   flip_vars (buf + cth->cth_varoff, cth->cth_typeoff - cth->cth_varoff);
1226*c42dbd0eSchristos   return flip_types (fp, buf + cth->cth_typeoff,
1227*c42dbd0eSchristos 		     cth->cth_stroff - cth->cth_typeoff, to_foreign);
1228867d70fcSchristos }
1229867d70fcSchristos 
1230*c42dbd0eSchristos /* Set up the ctl hashes in a ctf_dict_t.  Called by both writable and
1231867d70fcSchristos    non-writable dictionary initialization.  */
ctf_set_ctl_hashes(ctf_dict_t * fp)1232*c42dbd0eSchristos void ctf_set_ctl_hashes (ctf_dict_t *fp)
1233867d70fcSchristos {
1234867d70fcSchristos   /* Initialize the ctf_lookup_by_name top-level dictionary.  We keep an
1235867d70fcSchristos      array of type name prefixes and the corresponding ctf_hash to use.  */
1236867d70fcSchristos   fp->ctf_lookups[0].ctl_prefix = "struct";
1237867d70fcSchristos   fp->ctf_lookups[0].ctl_len = strlen (fp->ctf_lookups[0].ctl_prefix);
1238867d70fcSchristos   fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
1239867d70fcSchristos   fp->ctf_lookups[1].ctl_prefix = "union";
1240867d70fcSchristos   fp->ctf_lookups[1].ctl_len = strlen (fp->ctf_lookups[1].ctl_prefix);
1241867d70fcSchristos   fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
1242867d70fcSchristos   fp->ctf_lookups[2].ctl_prefix = "enum";
1243867d70fcSchristos   fp->ctf_lookups[2].ctl_len = strlen (fp->ctf_lookups[2].ctl_prefix);
1244867d70fcSchristos   fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
1245867d70fcSchristos   fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;
1246867d70fcSchristos   fp->ctf_lookups[3].ctl_len = strlen (fp->ctf_lookups[3].ctl_prefix);
1247867d70fcSchristos   fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
1248867d70fcSchristos   fp->ctf_lookups[4].ctl_prefix = NULL;
1249867d70fcSchristos   fp->ctf_lookups[4].ctl_len = 0;
1250867d70fcSchristos   fp->ctf_lookups[4].ctl_hash = NULL;
1251867d70fcSchristos }
1252867d70fcSchristos 
1253867d70fcSchristos /* Open a CTF file, mocking up a suitable ctf_sect.  */
1254867d70fcSchristos 
ctf_simple_open(const char * ctfsect,size_t ctfsect_size,const char * symsect,size_t symsect_size,size_t symsect_entsize,const char * strsect,size_t strsect_size,int * errp)1255*c42dbd0eSchristos ctf_dict_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
1256867d70fcSchristos 			     const char *symsect, size_t symsect_size,
1257867d70fcSchristos 			     size_t symsect_entsize,
1258867d70fcSchristos 			     const char *strsect, size_t strsect_size,
1259867d70fcSchristos 			     int *errp)
1260867d70fcSchristos {
1261867d70fcSchristos   return ctf_simple_open_internal (ctfsect, ctfsect_size, symsect, symsect_size,
1262867d70fcSchristos 				   symsect_entsize, strsect, strsect_size, NULL,
1263867d70fcSchristos 				   0, errp);
1264867d70fcSchristos }
1265867d70fcSchristos 
1266867d70fcSchristos /* Open a CTF file, mocking up a suitable ctf_sect and overriding the external
1267867d70fcSchristos    strtab with a synthetic one.  */
1268867d70fcSchristos 
ctf_simple_open_internal(const char * ctfsect,size_t ctfsect_size,const char * symsect,size_t symsect_size,size_t symsect_entsize,const char * strsect,size_t strsect_size,ctf_dynhash_t * syn_strtab,int writable,int * errp)1269*c42dbd0eSchristos ctf_dict_t *ctf_simple_open_internal (const char *ctfsect, size_t ctfsect_size,
1270867d70fcSchristos 				      const char *symsect, size_t symsect_size,
1271867d70fcSchristos 				      size_t symsect_entsize,
1272867d70fcSchristos 				      const char *strsect, size_t strsect_size,
1273867d70fcSchristos 				      ctf_dynhash_t *syn_strtab, int writable,
1274867d70fcSchristos 				      int *errp)
1275867d70fcSchristos {
1276867d70fcSchristos   ctf_sect_t skeleton;
1277867d70fcSchristos 
1278867d70fcSchristos   ctf_sect_t ctf_sect, sym_sect, str_sect;
1279867d70fcSchristos   ctf_sect_t *ctfsectp = NULL;
1280867d70fcSchristos   ctf_sect_t *symsectp = NULL;
1281867d70fcSchristos   ctf_sect_t *strsectp = NULL;
1282867d70fcSchristos 
1283867d70fcSchristos   skeleton.cts_name = _CTF_SECTION;
1284867d70fcSchristos   skeleton.cts_entsize = 1;
1285867d70fcSchristos 
1286867d70fcSchristos   if (ctfsect)
1287867d70fcSchristos     {
1288867d70fcSchristos       memcpy (&ctf_sect, &skeleton, sizeof (struct ctf_sect));
1289867d70fcSchristos       ctf_sect.cts_data = ctfsect;
1290867d70fcSchristos       ctf_sect.cts_size = ctfsect_size;
1291867d70fcSchristos       ctfsectp = &ctf_sect;
1292867d70fcSchristos     }
1293867d70fcSchristos 
1294867d70fcSchristos   if (symsect)
1295867d70fcSchristos     {
1296867d70fcSchristos       memcpy (&sym_sect, &skeleton, sizeof (struct ctf_sect));
1297867d70fcSchristos       sym_sect.cts_data = symsect;
1298867d70fcSchristos       sym_sect.cts_size = symsect_size;
1299867d70fcSchristos       sym_sect.cts_entsize = symsect_entsize;
1300867d70fcSchristos       symsectp = &sym_sect;
1301867d70fcSchristos     }
1302867d70fcSchristos 
1303867d70fcSchristos   if (strsect)
1304867d70fcSchristos     {
1305867d70fcSchristos       memcpy (&str_sect, &skeleton, sizeof (struct ctf_sect));
1306867d70fcSchristos       str_sect.cts_data = strsect;
1307867d70fcSchristos       str_sect.cts_size = strsect_size;
1308867d70fcSchristos       strsectp = &str_sect;
1309867d70fcSchristos     }
1310867d70fcSchristos 
1311867d70fcSchristos   return ctf_bufopen_internal (ctfsectp, symsectp, strsectp, syn_strtab,
1312867d70fcSchristos 			       writable, errp);
1313867d70fcSchristos }
1314867d70fcSchristos 
1315867d70fcSchristos /* Decode the specified CTF buffer and optional symbol table, and create a new
1316*c42dbd0eSchristos    CTF dict representing the symbolic debugging information.  This code can
1317867d70fcSchristos    be used directly by the debugger, or it can be used as the engine for
1318867d70fcSchristos    ctf_fdopen() or ctf_open(), below.  */
1319867d70fcSchristos 
1320*c42dbd0eSchristos ctf_dict_t *
ctf_bufopen(const ctf_sect_t * ctfsect,const ctf_sect_t * symsect,const ctf_sect_t * strsect,int * errp)1321867d70fcSchristos ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
1322867d70fcSchristos 	     const ctf_sect_t *strsect, int *errp)
1323867d70fcSchristos {
1324867d70fcSchristos   return ctf_bufopen_internal (ctfsect, symsect, strsect, NULL, 0, errp);
1325867d70fcSchristos }
1326867d70fcSchristos 
1327867d70fcSchristos /* Like ctf_bufopen, but overriding the external strtab with a synthetic one.  */
1328867d70fcSchristos 
1329*c42dbd0eSchristos ctf_dict_t *
ctf_bufopen_internal(const ctf_sect_t * ctfsect,const ctf_sect_t * symsect,const ctf_sect_t * strsect,ctf_dynhash_t * syn_strtab,int writable,int * errp)1330867d70fcSchristos ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
1331867d70fcSchristos 		      const ctf_sect_t *strsect, ctf_dynhash_t *syn_strtab,
1332867d70fcSchristos 		      int writable, int *errp)
1333867d70fcSchristos {
1334867d70fcSchristos   const ctf_preamble_t *pp;
1335867d70fcSchristos   size_t hdrsz = sizeof (ctf_header_t);
1336867d70fcSchristos   ctf_header_t *hp;
1337*c42dbd0eSchristos   ctf_dict_t *fp;
1338867d70fcSchristos   int foreign_endian = 0;
1339867d70fcSchristos   int err;
1340867d70fcSchristos 
1341867d70fcSchristos   libctf_init_debug();
1342867d70fcSchristos 
1343867d70fcSchristos   if ((ctfsect == NULL) || ((symsect != NULL) &&
1344867d70fcSchristos 			    ((strsect == NULL) && syn_strtab == NULL)))
1345867d70fcSchristos     return (ctf_set_open_errno (errp, EINVAL));
1346867d70fcSchristos 
1347867d70fcSchristos   if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&
1348867d70fcSchristos       symsect->cts_entsize != sizeof (Elf64_Sym))
1349867d70fcSchristos     return (ctf_set_open_errno (errp, ECTF_SYMTAB));
1350867d70fcSchristos 
1351867d70fcSchristos   if (symsect != NULL && symsect->cts_data == NULL)
1352867d70fcSchristos     return (ctf_set_open_errno (errp, ECTF_SYMBAD));
1353867d70fcSchristos 
1354867d70fcSchristos   if (strsect != NULL && strsect->cts_data == NULL)
1355867d70fcSchristos     return (ctf_set_open_errno (errp, ECTF_STRBAD));
1356867d70fcSchristos 
1357867d70fcSchristos   if (ctfsect->cts_size < sizeof (ctf_preamble_t))
1358867d70fcSchristos     return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));
1359867d70fcSchristos 
1360867d70fcSchristos   pp = (const ctf_preamble_t *) ctfsect->cts_data;
1361867d70fcSchristos 
1362867d70fcSchristos   ctf_dprintf ("ctf_bufopen: magic=0x%x version=%u\n",
1363867d70fcSchristos 	       pp->ctp_magic, pp->ctp_version);
1364867d70fcSchristos 
1365867d70fcSchristos   /* Validate each part of the CTF header.
1366867d70fcSchristos 
1367867d70fcSchristos      First, we validate the preamble (common to all versions).  At that point,
1368867d70fcSchristos      we know the endianness and specific header version, and can validate the
1369867d70fcSchristos      version-specific parts including section offsets and alignments.
1370867d70fcSchristos 
1371867d70fcSchristos      We specifically do not support foreign-endian old versions.  */
1372867d70fcSchristos 
1373867d70fcSchristos   if (_libctf_unlikely_ (pp->ctp_magic != CTF_MAGIC))
1374867d70fcSchristos     {
1375867d70fcSchristos       if (pp->ctp_magic == bswap_16 (CTF_MAGIC))
1376867d70fcSchristos 	{
1377867d70fcSchristos 	  if (pp->ctp_version != CTF_VERSION_3)
1378867d70fcSchristos 	    return (ctf_set_open_errno (errp, ECTF_CTFVERS));
1379867d70fcSchristos 	  foreign_endian = 1;
1380867d70fcSchristos 	}
1381867d70fcSchristos       else
1382867d70fcSchristos 	return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));
1383867d70fcSchristos     }
1384867d70fcSchristos 
1385867d70fcSchristos   if (_libctf_unlikely_ ((pp->ctp_version < CTF_VERSION_1)
1386867d70fcSchristos 			 || (pp->ctp_version > CTF_VERSION_3)))
1387867d70fcSchristos     return (ctf_set_open_errno (errp, ECTF_CTFVERS));
1388867d70fcSchristos 
1389867d70fcSchristos   if ((symsect != NULL) && (pp->ctp_version < CTF_VERSION_2))
1390867d70fcSchristos     {
1391867d70fcSchristos       /* The symtab can contain function entries which contain embedded ctf
1392867d70fcSchristos 	 info.  We do not support dynamically upgrading such entries (none
1393867d70fcSchristos 	 should exist in any case, since dwarf2ctf does not create them).  */
1394867d70fcSchristos 
1395*c42dbd0eSchristos       ctf_err_warn (NULL, 0, ECTF_NOTSUP, _("ctf_bufopen: CTF version %d "
1396*c42dbd0eSchristos 					    "symsect not supported"),
1397*c42dbd0eSchristos 		    pp->ctp_version);
1398867d70fcSchristos       return (ctf_set_open_errno (errp, ECTF_NOTSUP));
1399867d70fcSchristos     }
1400867d70fcSchristos 
1401867d70fcSchristos   if (pp->ctp_version < CTF_VERSION_3)
1402867d70fcSchristos     hdrsz = sizeof (ctf_header_v2_t);
1403867d70fcSchristos 
1404*c42dbd0eSchristos   if (_libctf_unlikely_ (pp->ctp_flags > CTF_F_MAX))
1405*c42dbd0eSchristos     {
1406*c42dbd0eSchristos       ctf_err_warn (NULL, 0, ECTF_FLAGS, _("ctf_bufopen: invalid header "
1407*c42dbd0eSchristos 					   "flags: %x"),
1408*c42dbd0eSchristos 		    (unsigned int) pp->ctp_flags);
1409*c42dbd0eSchristos       return (ctf_set_open_errno (errp, ECTF_FLAGS));
1410*c42dbd0eSchristos     }
1411*c42dbd0eSchristos 
1412867d70fcSchristos   if (ctfsect->cts_size < hdrsz)
1413867d70fcSchristos     return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));
1414867d70fcSchristos 
1415*c42dbd0eSchristos   if ((fp = malloc (sizeof (ctf_dict_t))) == NULL)
1416867d70fcSchristos     return (ctf_set_open_errno (errp, ENOMEM));
1417867d70fcSchristos 
1418*c42dbd0eSchristos   memset (fp, 0, sizeof (ctf_dict_t));
1419867d70fcSchristos 
1420867d70fcSchristos   if (writable)
1421867d70fcSchristos     fp->ctf_flags |= LCTF_RDWR;
1422867d70fcSchristos 
1423867d70fcSchristos   if ((fp->ctf_header = malloc (sizeof (struct ctf_header))) == NULL)
1424867d70fcSchristos     {
1425867d70fcSchristos       free (fp);
1426867d70fcSchristos       return (ctf_set_open_errno (errp, ENOMEM));
1427867d70fcSchristos     }
1428867d70fcSchristos   hp = fp->ctf_header;
1429867d70fcSchristos   memcpy (hp, ctfsect->cts_data, hdrsz);
1430867d70fcSchristos   if (pp->ctp_version < CTF_VERSION_3)
1431867d70fcSchristos     upgrade_header (hp);
1432867d70fcSchristos 
1433867d70fcSchristos   if (foreign_endian)
1434*c42dbd0eSchristos     ctf_flip_header (hp);
1435867d70fcSchristos   fp->ctf_openflags = hp->cth_flags;
1436867d70fcSchristos   fp->ctf_size = hp->cth_stroff + hp->cth_strlen;
1437867d70fcSchristos 
1438867d70fcSchristos   ctf_dprintf ("ctf_bufopen: uncompressed size=%lu\n",
1439867d70fcSchristos 	       (unsigned long) fp->ctf_size);
1440867d70fcSchristos 
1441867d70fcSchristos   if (hp->cth_lbloff > fp->ctf_size || hp->cth_objtoff > fp->ctf_size
1442867d70fcSchristos       || hp->cth_funcoff > fp->ctf_size || hp->cth_objtidxoff > fp->ctf_size
1443867d70fcSchristos       || hp->cth_funcidxoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
1444867d70fcSchristos       || hp->cth_stroff > fp->ctf_size)
1445*c42dbd0eSchristos     {
1446*c42dbd0eSchristos       ctf_err_warn (NULL, 0, ECTF_CORRUPT, _("header offset exceeds CTF size"));
1447867d70fcSchristos       return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1448*c42dbd0eSchristos     }
1449867d70fcSchristos 
1450867d70fcSchristos   if (hp->cth_lbloff > hp->cth_objtoff
1451867d70fcSchristos       || hp->cth_objtoff > hp->cth_funcoff
1452867d70fcSchristos       || hp->cth_funcoff > hp->cth_typeoff
1453867d70fcSchristos       || hp->cth_funcoff > hp->cth_objtidxoff
1454867d70fcSchristos       || hp->cth_objtidxoff > hp->cth_funcidxoff
1455867d70fcSchristos       || hp->cth_funcidxoff > hp->cth_varoff
1456867d70fcSchristos       || hp->cth_varoff > hp->cth_typeoff || hp->cth_typeoff > hp->cth_stroff)
1457*c42dbd0eSchristos     {
1458*c42dbd0eSchristos       ctf_err_warn (NULL, 0, ECTF_CORRUPT, _("overlapping CTF sections"));
1459867d70fcSchristos       return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1460*c42dbd0eSchristos     }
1461867d70fcSchristos 
1462867d70fcSchristos   if ((hp->cth_lbloff & 3) || (hp->cth_objtoff & 2)
1463867d70fcSchristos       || (hp->cth_funcoff & 2) || (hp->cth_objtidxoff & 2)
1464867d70fcSchristos       || (hp->cth_funcidxoff & 2) || (hp->cth_varoff & 3)
1465867d70fcSchristos       || (hp->cth_typeoff & 3))
1466*c42dbd0eSchristos     {
1467*c42dbd0eSchristos       ctf_err_warn (NULL, 0, ECTF_CORRUPT,
1468*c42dbd0eSchristos 		    _("CTF sections not properly aligned"));
1469867d70fcSchristos       return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1470*c42dbd0eSchristos     }
1471*c42dbd0eSchristos 
1472*c42dbd0eSchristos   /* This invariant will be lifted in v4, but for now it is true.  */
1473*c42dbd0eSchristos 
1474*c42dbd0eSchristos   if ((hp->cth_funcidxoff - hp->cth_objtidxoff != 0) &&
1475*c42dbd0eSchristos       (hp->cth_funcidxoff - hp->cth_objtidxoff
1476*c42dbd0eSchristos        != hp->cth_funcoff - hp->cth_objtoff))
1477*c42dbd0eSchristos     {
1478*c42dbd0eSchristos       ctf_err_warn (NULL, 0, ECTF_CORRUPT,
1479*c42dbd0eSchristos 		    _("Object index section is neither empty nor the "
1480*c42dbd0eSchristos 		      "same length as the object section: %u versus %u "
1481*c42dbd0eSchristos 		      "bytes"), hp->cth_funcoff - hp->cth_objtoff,
1482*c42dbd0eSchristos 		    hp->cth_funcidxoff - hp->cth_objtidxoff);
1483*c42dbd0eSchristos       return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1484*c42dbd0eSchristos     }
1485*c42dbd0eSchristos 
1486*c42dbd0eSchristos   if ((hp->cth_varoff - hp->cth_funcidxoff != 0) &&
1487*c42dbd0eSchristos       (hp->cth_varoff - hp->cth_funcidxoff
1488*c42dbd0eSchristos        != hp->cth_objtidxoff - hp->cth_funcoff) &&
1489*c42dbd0eSchristos       (hp->cth_flags & CTF_F_NEWFUNCINFO))
1490*c42dbd0eSchristos     {
1491*c42dbd0eSchristos       ctf_err_warn (NULL, 0, ECTF_CORRUPT,
1492*c42dbd0eSchristos 		    _("Function index section is neither empty nor the "
1493*c42dbd0eSchristos 		      "same length as the function section: %u versus %u "
1494*c42dbd0eSchristos 		      "bytes"), hp->cth_objtidxoff - hp->cth_funcoff,
1495*c42dbd0eSchristos 		    hp->cth_varoff - hp->cth_funcidxoff);
1496*c42dbd0eSchristos       return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1497*c42dbd0eSchristos     }
1498867d70fcSchristos 
1499867d70fcSchristos   /* Once everything is determined to be valid, attempt to decompress the CTF
1500867d70fcSchristos      data buffer if it is compressed, or copy it into new storage if it is not
1501867d70fcSchristos      compressed but needs endian-flipping.  Otherwise we just put the data
1502867d70fcSchristos      section's buffer pointer into ctf_buf, below.  */
1503867d70fcSchristos 
1504867d70fcSchristos   /* Note: if this is a v1 buffer, it will be reallocated and expanded by
1505867d70fcSchristos      init_types().  */
1506867d70fcSchristos 
1507867d70fcSchristos   if (hp->cth_flags & CTF_F_COMPRESS)
1508867d70fcSchristos     {
1509867d70fcSchristos       size_t srclen;
1510867d70fcSchristos       uLongf dstlen;
1511867d70fcSchristos       const void *src;
1512867d70fcSchristos       int rc = Z_OK;
1513867d70fcSchristos 
1514867d70fcSchristos       /* We are allocating this ourselves, so we can drop the ctf header
1515867d70fcSchristos 	 copy in favour of ctf->ctf_header.  */
1516867d70fcSchristos 
1517867d70fcSchristos       if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL)
1518867d70fcSchristos 	{
1519867d70fcSchristos 	  err = ECTF_ZALLOC;
1520867d70fcSchristos 	  goto bad;
1521867d70fcSchristos 	}
1522867d70fcSchristos       fp->ctf_dynbase = fp->ctf_base;
1523867d70fcSchristos       hp->cth_flags &= ~CTF_F_COMPRESS;
1524867d70fcSchristos 
1525867d70fcSchristos       src = (unsigned char *) ctfsect->cts_data + hdrsz;
1526867d70fcSchristos       srclen = ctfsect->cts_size - hdrsz;
1527867d70fcSchristos       dstlen = fp->ctf_size;
1528867d70fcSchristos       fp->ctf_buf = fp->ctf_base;
1529867d70fcSchristos 
1530867d70fcSchristos       if ((rc = uncompress (fp->ctf_base, &dstlen, src, srclen)) != Z_OK)
1531867d70fcSchristos 	{
1532*c42dbd0eSchristos 	  ctf_err_warn (NULL, 0, ECTF_DECOMPRESS, _("zlib inflate err: %s"),
1533*c42dbd0eSchristos 			zError (rc));
1534867d70fcSchristos 	  err = ECTF_DECOMPRESS;
1535867d70fcSchristos 	  goto bad;
1536867d70fcSchristos 	}
1537867d70fcSchristos 
1538867d70fcSchristos       if ((size_t) dstlen != fp->ctf_size)
1539867d70fcSchristos 	{
1540*c42dbd0eSchristos 	  ctf_err_warn (NULL, 0, ECTF_CORRUPT,
1541*c42dbd0eSchristos 			_("zlib inflate short: got %lu of %lu bytes"),
1542*c42dbd0eSchristos 			(unsigned long) dstlen, (unsigned long) fp->ctf_size);
1543867d70fcSchristos 	  err = ECTF_CORRUPT;
1544867d70fcSchristos 	  goto bad;
1545867d70fcSchristos 	}
1546867d70fcSchristos     }
1547*c42dbd0eSchristos   else
1548*c42dbd0eSchristos     {
1549*c42dbd0eSchristos       if (_libctf_unlikely_ (ctfsect->cts_size < hdrsz + fp->ctf_size))
1550*c42dbd0eSchristos 	{
1551*c42dbd0eSchristos 	  ctf_err_warn (NULL, 0, ECTF_CORRUPT,
1552*c42dbd0eSchristos 			_("%lu byte long CTF dictionary overruns %lu byte long CTF section"),
1553*c42dbd0eSchristos 			(unsigned long) ctfsect->cts_size,
1554*c42dbd0eSchristos 			(unsigned long) (hdrsz + fp->ctf_size));
1555*c42dbd0eSchristos 	  err = ECTF_CORRUPT;
1556*c42dbd0eSchristos 	  goto bad;
1557*c42dbd0eSchristos 	}
1558*c42dbd0eSchristos 
1559*c42dbd0eSchristos       if (foreign_endian)
1560867d70fcSchristos 	{
1561867d70fcSchristos 	  if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL)
1562867d70fcSchristos 	    {
1563867d70fcSchristos 	      err = ECTF_ZALLOC;
1564867d70fcSchristos 	      goto bad;
1565867d70fcSchristos 	    }
1566867d70fcSchristos 	  fp->ctf_dynbase = fp->ctf_base;
1567867d70fcSchristos 	  memcpy (fp->ctf_base, ((unsigned char *) ctfsect->cts_data) + hdrsz,
1568867d70fcSchristos 		  fp->ctf_size);
1569867d70fcSchristos 	  fp->ctf_buf = fp->ctf_base;
1570867d70fcSchristos 	}
1571867d70fcSchristos       else
1572867d70fcSchristos 	{
1573*c42dbd0eSchristos 	  /* We are just using the section passed in -- but its header may
1574*c42dbd0eSchristos 	     be an old version.  Point ctf_buf past the old header, and
1575*c42dbd0eSchristos 	     never touch it again.  */
1576867d70fcSchristos 	  fp->ctf_base = (unsigned char *) ctfsect->cts_data;
1577867d70fcSchristos 	  fp->ctf_dynbase = NULL;
1578867d70fcSchristos 	  fp->ctf_buf = fp->ctf_base + hdrsz;
1579867d70fcSchristos 	}
1580*c42dbd0eSchristos     }
1581867d70fcSchristos 
1582867d70fcSchristos   /* Once we have uncompressed and validated the CTF data buffer, we can
1583*c42dbd0eSchristos      proceed with initializing the ctf_dict_t we allocated above.
1584867d70fcSchristos 
1585867d70fcSchristos      Nothing that depends on buf or base should be set directly in this function
1586867d70fcSchristos      before the init_types() call, because it may be reallocated during
1587867d70fcSchristos      transparent upgrade if this recension of libctf is so configured: see
1588867d70fcSchristos      ctf_set_base().  */
1589867d70fcSchristos 
1590867d70fcSchristos   ctf_set_version (fp, hp, hp->cth_version);
1591*c42dbd0eSchristos   if (ctf_str_create_atoms (fp) < 0)
1592*c42dbd0eSchristos     {
1593*c42dbd0eSchristos       err = ENOMEM;
1594*c42dbd0eSchristos       goto bad;
1595*c42dbd0eSchristos     }
1596*c42dbd0eSchristos 
1597867d70fcSchristos   fp->ctf_parmax = CTF_MAX_PTYPE;
1598867d70fcSchristos   memcpy (&fp->ctf_data, ctfsect, sizeof (ctf_sect_t));
1599867d70fcSchristos 
1600867d70fcSchristos   if (symsect != NULL)
1601867d70fcSchristos     {
1602867d70fcSchristos       memcpy (&fp->ctf_symtab, symsect, sizeof (ctf_sect_t));
1603867d70fcSchristos       memcpy (&fp->ctf_strtab, strsect, sizeof (ctf_sect_t));
1604867d70fcSchristos     }
1605867d70fcSchristos 
1606867d70fcSchristos   if (fp->ctf_data.cts_name != NULL)
1607867d70fcSchristos     if ((fp->ctf_data.cts_name = strdup (fp->ctf_data.cts_name)) == NULL)
1608867d70fcSchristos       {
1609867d70fcSchristos 	err = ENOMEM;
1610867d70fcSchristos 	goto bad;
1611867d70fcSchristos       }
1612867d70fcSchristos   if (fp->ctf_symtab.cts_name != NULL)
1613867d70fcSchristos     if ((fp->ctf_symtab.cts_name = strdup (fp->ctf_symtab.cts_name)) == NULL)
1614867d70fcSchristos       {
1615867d70fcSchristos 	err = ENOMEM;
1616867d70fcSchristos 	goto bad;
1617867d70fcSchristos       }
1618867d70fcSchristos   if (fp->ctf_strtab.cts_name != NULL)
1619867d70fcSchristos     if ((fp->ctf_strtab.cts_name = strdup (fp->ctf_strtab.cts_name)) == NULL)
1620867d70fcSchristos       {
1621867d70fcSchristos 	err = ENOMEM;
1622867d70fcSchristos 	goto bad;
1623867d70fcSchristos       }
1624867d70fcSchristos 
1625867d70fcSchristos   if (fp->ctf_data.cts_name == NULL)
1626867d70fcSchristos     fp->ctf_data.cts_name = _CTF_NULLSTR;
1627867d70fcSchristos   if (fp->ctf_symtab.cts_name == NULL)
1628867d70fcSchristos     fp->ctf_symtab.cts_name = _CTF_NULLSTR;
1629867d70fcSchristos   if (fp->ctf_strtab.cts_name == NULL)
1630867d70fcSchristos     fp->ctf_strtab.cts_name = _CTF_NULLSTR;
1631867d70fcSchristos 
1632867d70fcSchristos   if (strsect != NULL)
1633867d70fcSchristos     {
1634867d70fcSchristos       fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;
1635867d70fcSchristos       fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;
1636867d70fcSchristos     }
1637867d70fcSchristos   fp->ctf_syn_ext_strtab = syn_strtab;
1638867d70fcSchristos 
1639867d70fcSchristos   if (foreign_endian &&
1640*c42dbd0eSchristos       (err = ctf_flip (fp, hp, fp->ctf_buf, 0)) != 0)
1641867d70fcSchristos     {
1642*c42dbd0eSchristos       /* We can be certain that ctf_flip() will have endian-flipped everything
1643867d70fcSchristos 	 other than the types table when we return.  In particular the header
1644867d70fcSchristos 	 is fine, so set it, to allow freeing to use the usual code path.  */
1645867d70fcSchristos 
1646867d70fcSchristos       ctf_set_base (fp, hp, fp->ctf_base);
1647867d70fcSchristos       goto bad;
1648867d70fcSchristos     }
1649867d70fcSchristos 
1650867d70fcSchristos   ctf_set_base (fp, hp, fp->ctf_base);
1651867d70fcSchristos 
1652*c42dbd0eSchristos   /* No need to do anything else for dynamic dicts: they do not support symbol
1653*c42dbd0eSchristos      lookups, and the type table is maintained in the dthashes.  */
1654867d70fcSchristos   if (fp->ctf_flags & LCTF_RDWR)
1655867d70fcSchristos     {
1656867d70fcSchristos       fp->ctf_refcnt = 1;
1657867d70fcSchristos       return fp;
1658867d70fcSchristos     }
1659867d70fcSchristos 
1660867d70fcSchristos   if ((err = init_types (fp, hp)) != 0)
1661867d70fcSchristos     goto bad;
1662867d70fcSchristos 
1663*c42dbd0eSchristos   /* Allocate and initialize the symtab translation table, pointed to by
1664*c42dbd0eSchristos      ctf_sxlate, and the corresponding index sections.  This table may be too
1665*c42dbd0eSchristos      large for the actual size of the object and function info sections: if so,
1666*c42dbd0eSchristos      ctf_nsyms will be adjusted and the excess will never be used.  It's
1667*c42dbd0eSchristos      possible to do indexed symbol lookups even without a symbol table, so check
1668*c42dbd0eSchristos      even in that case.  Initially, we assume the symtab is native-endian: if it
1669*c42dbd0eSchristos      isn't, the caller will inform us later by calling ctf_symsect_endianness.  */
1670*c42dbd0eSchristos #ifdef WORDS_BIGENDIAN
1671*c42dbd0eSchristos   fp->ctf_symsect_little_endian = 0;
1672*c42dbd0eSchristos #else
1673*c42dbd0eSchristos   fp->ctf_symsect_little_endian = 1;
1674*c42dbd0eSchristos #endif
1675867d70fcSchristos 
1676867d70fcSchristos   if (symsect != NULL)
1677867d70fcSchristos     {
1678867d70fcSchristos       fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize;
1679867d70fcSchristos       fp->ctf_sxlate = malloc (fp->ctf_nsyms * sizeof (uint32_t));
1680867d70fcSchristos 
1681867d70fcSchristos       if (fp->ctf_sxlate == NULL)
1682867d70fcSchristos 	{
1683867d70fcSchristos 	  err = ENOMEM;
1684867d70fcSchristos 	  goto bad;
1685867d70fcSchristos 	}
1686867d70fcSchristos     }
1687867d70fcSchristos 
1688*c42dbd0eSchristos   if ((err = init_symtab (fp, hp, symsect)) != 0)
1689*c42dbd0eSchristos     goto bad;
1690*c42dbd0eSchristos 
1691867d70fcSchristos   ctf_set_ctl_hashes (fp);
1692867d70fcSchristos 
1693867d70fcSchristos   if (symsect != NULL)
1694867d70fcSchristos     {
1695867d70fcSchristos       if (symsect->cts_entsize == sizeof (Elf64_Sym))
1696867d70fcSchristos 	(void) ctf_setmodel (fp, CTF_MODEL_LP64);
1697867d70fcSchristos       else
1698867d70fcSchristos 	(void) ctf_setmodel (fp, CTF_MODEL_ILP32);
1699867d70fcSchristos     }
1700867d70fcSchristos   else
1701867d70fcSchristos     (void) ctf_setmodel (fp, CTF_MODEL_NATIVE);
1702867d70fcSchristos 
1703867d70fcSchristos   fp->ctf_refcnt = 1;
1704867d70fcSchristos   return fp;
1705867d70fcSchristos 
1706867d70fcSchristos bad:
1707867d70fcSchristos   ctf_set_open_errno (errp, err);
1708*c42dbd0eSchristos   ctf_err_warn_to_open (fp);
1709*c42dbd0eSchristos   ctf_dict_close (fp);
1710867d70fcSchristos   return NULL;
1711867d70fcSchristos }
1712867d70fcSchristos 
1713*c42dbd0eSchristos /* Bump the refcount on the specified CTF dict, to allow export of ctf_dict_t's
1714*c42dbd0eSchristos    from iterators that open and close the ctf_dict_t around the loop.  (This
1715*c42dbd0eSchristos    does not extend their lifetime beyond that of the ctf_archive_t in which they
1716*c42dbd0eSchristos    are contained.)  */
1717867d70fcSchristos 
1718867d70fcSchristos void
ctf_ref(ctf_dict_t * fp)1719*c42dbd0eSchristos ctf_ref (ctf_dict_t *fp)
1720*c42dbd0eSchristos {
1721*c42dbd0eSchristos   fp->ctf_refcnt++;
1722*c42dbd0eSchristos }
1723*c42dbd0eSchristos 
1724*c42dbd0eSchristos /* Close the specified CTF dict and free associated data structures.  Note that
1725*c42dbd0eSchristos    ctf_dict_close() is a reference counted operation: if the specified file is
1726*c42dbd0eSchristos    the parent of other active dict, its reference count will be greater than one
1727*c42dbd0eSchristos    and it will be freed later when no active children exist.  */
1728*c42dbd0eSchristos 
1729*c42dbd0eSchristos void
ctf_dict_close(ctf_dict_t * fp)1730*c42dbd0eSchristos ctf_dict_close (ctf_dict_t *fp)
1731867d70fcSchristos {
1732867d70fcSchristos   ctf_dtdef_t *dtd, *ntd;
1733867d70fcSchristos   ctf_dvdef_t *dvd, *nvd;
1734*c42dbd0eSchristos   ctf_in_flight_dynsym_t *did, *nid;
1735*c42dbd0eSchristos   ctf_err_warning_t *err, *nerr;
1736867d70fcSchristos 
1737867d70fcSchristos   if (fp == NULL)
1738*c42dbd0eSchristos     return;		   /* Allow ctf_dict_close(NULL) to simplify caller code.  */
1739867d70fcSchristos 
1740*c42dbd0eSchristos   ctf_dprintf ("ctf_dict_close(%p) refcnt=%u\n", (void *) fp, fp->ctf_refcnt);
1741867d70fcSchristos 
1742867d70fcSchristos   if (fp->ctf_refcnt > 1)
1743867d70fcSchristos     {
1744867d70fcSchristos       fp->ctf_refcnt--;
1745867d70fcSchristos       return;
1746867d70fcSchristos     }
1747867d70fcSchristos 
1748*c42dbd0eSchristos   /* It is possible to recurse back in here, notably if dicts in the
1749*c42dbd0eSchristos      ctf_link_inputs or ctf_link_outputs cite this dict as a parent without
1750*c42dbd0eSchristos      using ctf_import_unref.  Do nothing in that case.  */
1751*c42dbd0eSchristos   if (fp->ctf_refcnt == 0)
1752*c42dbd0eSchristos     return;
1753*c42dbd0eSchristos 
1754*c42dbd0eSchristos   fp->ctf_refcnt--;
1755867d70fcSchristos   free (fp->ctf_dyncuname);
1756867d70fcSchristos   free (fp->ctf_dynparname);
1757*c42dbd0eSchristos   if (fp->ctf_parent && !fp->ctf_parent_unreffed)
1758*c42dbd0eSchristos     ctf_dict_close (fp->ctf_parent);
1759867d70fcSchristos 
1760867d70fcSchristos   for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
1761867d70fcSchristos     {
1762867d70fcSchristos       ntd = ctf_list_next (dtd);
1763867d70fcSchristos       ctf_dtd_delete (fp, dtd);
1764867d70fcSchristos     }
1765867d70fcSchristos   ctf_dynhash_destroy (fp->ctf_dthash);
1766867d70fcSchristos   if (fp->ctf_flags & LCTF_RDWR)
1767867d70fcSchristos     {
1768867d70fcSchristos       ctf_dynhash_destroy (fp->ctf_structs.ctn_writable);
1769867d70fcSchristos       ctf_dynhash_destroy (fp->ctf_unions.ctn_writable);
1770867d70fcSchristos       ctf_dynhash_destroy (fp->ctf_enums.ctn_writable);
1771867d70fcSchristos       ctf_dynhash_destroy (fp->ctf_names.ctn_writable);
1772867d70fcSchristos     }
1773867d70fcSchristos   else
1774867d70fcSchristos     {
1775867d70fcSchristos       ctf_hash_destroy (fp->ctf_structs.ctn_readonly);
1776867d70fcSchristos       ctf_hash_destroy (fp->ctf_unions.ctn_readonly);
1777867d70fcSchristos       ctf_hash_destroy (fp->ctf_enums.ctn_readonly);
1778867d70fcSchristos       ctf_hash_destroy (fp->ctf_names.ctn_readonly);
1779867d70fcSchristos     }
1780867d70fcSchristos 
1781867d70fcSchristos   for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
1782867d70fcSchristos     {
1783867d70fcSchristos       nvd = ctf_list_next (dvd);
1784867d70fcSchristos       ctf_dvd_delete (fp, dvd);
1785867d70fcSchristos     }
1786867d70fcSchristos   ctf_dynhash_destroy (fp->ctf_dvhash);
1787*c42dbd0eSchristos 
1788*c42dbd0eSchristos   ctf_dynhash_destroy (fp->ctf_symhash);
1789*c42dbd0eSchristos   free (fp->ctf_funcidx_sxlate);
1790*c42dbd0eSchristos   free (fp->ctf_objtidx_sxlate);
1791*c42dbd0eSchristos   ctf_dynhash_destroy (fp->ctf_objthash);
1792*c42dbd0eSchristos   ctf_dynhash_destroy (fp->ctf_funchash);
1793*c42dbd0eSchristos   free (fp->ctf_dynsymidx);
1794*c42dbd0eSchristos   ctf_dynhash_destroy (fp->ctf_dynsyms);
1795*c42dbd0eSchristos   for (did = ctf_list_next (&fp->ctf_in_flight_dynsyms); did != NULL; did = nid)
1796*c42dbd0eSchristos     {
1797*c42dbd0eSchristos       nid = ctf_list_next (did);
1798*c42dbd0eSchristos       ctf_list_delete (&fp->ctf_in_flight_dynsyms, did);
1799*c42dbd0eSchristos       free (did);
1800*c42dbd0eSchristos     }
1801*c42dbd0eSchristos 
1802867d70fcSchristos   ctf_str_free_atoms (fp);
1803867d70fcSchristos   free (fp->ctf_tmp_typeslice);
1804867d70fcSchristos 
1805867d70fcSchristos   if (fp->ctf_data.cts_name != _CTF_NULLSTR)
1806867d70fcSchristos     free ((char *) fp->ctf_data.cts_name);
1807867d70fcSchristos 
1808867d70fcSchristos   if (fp->ctf_symtab.cts_name != _CTF_NULLSTR)
1809867d70fcSchristos     free ((char *) fp->ctf_symtab.cts_name);
1810867d70fcSchristos 
1811867d70fcSchristos   if (fp->ctf_strtab.cts_name != _CTF_NULLSTR)
1812867d70fcSchristos     free ((char *) fp->ctf_strtab.cts_name);
1813867d70fcSchristos   else if (fp->ctf_data_mmapped)
1814867d70fcSchristos     ctf_munmap (fp->ctf_data_mmapped, fp->ctf_data_mmapped_len);
1815867d70fcSchristos 
1816867d70fcSchristos   free (fp->ctf_dynbase);
1817867d70fcSchristos 
1818867d70fcSchristos   ctf_dynhash_destroy (fp->ctf_syn_ext_strtab);
1819867d70fcSchristos   ctf_dynhash_destroy (fp->ctf_link_inputs);
1820867d70fcSchristos   ctf_dynhash_destroy (fp->ctf_link_outputs);
1821867d70fcSchristos   ctf_dynhash_destroy (fp->ctf_link_type_mapping);
1822*c42dbd0eSchristos   ctf_dynhash_destroy (fp->ctf_link_in_cu_mapping);
1823*c42dbd0eSchristos   ctf_dynhash_destroy (fp->ctf_link_out_cu_mapping);
1824867d70fcSchristos   ctf_dynhash_destroy (fp->ctf_add_processing);
1825*c42dbd0eSchristos   ctf_dedup_fini (fp, NULL, 0);
1826*c42dbd0eSchristos   ctf_dynset_destroy (fp->ctf_dedup_atoms_alloc);
1827*c42dbd0eSchristos 
1828*c42dbd0eSchristos   for (err = ctf_list_next (&fp->ctf_errs_warnings); err != NULL; err = nerr)
1829*c42dbd0eSchristos     {
1830*c42dbd0eSchristos       nerr = ctf_list_next (err);
1831*c42dbd0eSchristos       ctf_list_delete (&fp->ctf_errs_warnings, err);
1832*c42dbd0eSchristos       free (err->cew_text);
1833*c42dbd0eSchristos       free (err);
1834*c42dbd0eSchristos     }
1835867d70fcSchristos 
1836867d70fcSchristos   free (fp->ctf_sxlate);
1837867d70fcSchristos   free (fp->ctf_txlate);
1838867d70fcSchristos   free (fp->ctf_ptrtab);
1839*c42dbd0eSchristos   free (fp->ctf_pptrtab);
1840867d70fcSchristos 
1841867d70fcSchristos   free (fp->ctf_header);
1842867d70fcSchristos   free (fp);
1843867d70fcSchristos }
1844867d70fcSchristos 
1845*c42dbd0eSchristos /* Backward compatibility.  */
1846*c42dbd0eSchristos void
ctf_file_close(ctf_file_t * fp)1847*c42dbd0eSchristos ctf_file_close (ctf_file_t *fp)
1848*c42dbd0eSchristos {
1849*c42dbd0eSchristos   ctf_dict_close (fp);
1850*c42dbd0eSchristos }
1851*c42dbd0eSchristos 
1852867d70fcSchristos /* The converse of ctf_open().  ctf_open() disguises whatever it opens as an
1853867d70fcSchristos    archive, so closing one is just like closing an archive.  */
1854867d70fcSchristos void
ctf_close(ctf_archive_t * arc)1855867d70fcSchristos ctf_close (ctf_archive_t *arc)
1856867d70fcSchristos {
1857867d70fcSchristos   ctf_arc_close (arc);
1858867d70fcSchristos }
1859867d70fcSchristos 
1860*c42dbd0eSchristos /* Get the CTF archive from which this ctf_dict_t is derived.  */
1861867d70fcSchristos ctf_archive_t *
ctf_get_arc(const ctf_dict_t * fp)1862*c42dbd0eSchristos ctf_get_arc (const ctf_dict_t *fp)
1863867d70fcSchristos {
1864867d70fcSchristos   return fp->ctf_archive;
1865867d70fcSchristos }
1866867d70fcSchristos 
1867867d70fcSchristos /* Return the ctfsect out of the core ctf_impl.  Useful for freeing the
1868*c42dbd0eSchristos    ctfsect's data * after ctf_dict_close(), which is why we return the actual
1869867d70fcSchristos    structure, not a pointer to it, since that is likely to become a pointer to
1870867d70fcSchristos    freed data before the return value is used under the expected use case of
1871*c42dbd0eSchristos    ctf_getsect()/ ctf_dict_close()/free().  */
1872867d70fcSchristos ctf_sect_t
ctf_getdatasect(const ctf_dict_t * fp)1873*c42dbd0eSchristos ctf_getdatasect (const ctf_dict_t *fp)
1874867d70fcSchristos {
1875867d70fcSchristos   return fp->ctf_data;
1876867d70fcSchristos }
1877867d70fcSchristos 
1878*c42dbd0eSchristos ctf_sect_t
ctf_getsymsect(const ctf_dict_t * fp)1879*c42dbd0eSchristos ctf_getsymsect (const ctf_dict_t *fp)
1880*c42dbd0eSchristos {
1881*c42dbd0eSchristos   return fp->ctf_symtab;
1882*c42dbd0eSchristos }
1883*c42dbd0eSchristos 
1884*c42dbd0eSchristos ctf_sect_t
ctf_getstrsect(const ctf_dict_t * fp)1885*c42dbd0eSchristos ctf_getstrsect (const ctf_dict_t *fp)
1886*c42dbd0eSchristos {
1887*c42dbd0eSchristos   return fp->ctf_strtab;
1888*c42dbd0eSchristos }
1889*c42dbd0eSchristos 
1890*c42dbd0eSchristos /* Set the endianness of the symbol table attached to FP.  */
1891*c42dbd0eSchristos void
ctf_symsect_endianness(ctf_dict_t * fp,int little_endian)1892*c42dbd0eSchristos ctf_symsect_endianness (ctf_dict_t *fp, int little_endian)
1893*c42dbd0eSchristos {
1894*c42dbd0eSchristos   int old_endianness = fp->ctf_symsect_little_endian;
1895*c42dbd0eSchristos 
1896*c42dbd0eSchristos   fp->ctf_symsect_little_endian = !!little_endian;
1897*c42dbd0eSchristos 
1898*c42dbd0eSchristos   /* If we already have a symtab translation table, we need to repopulate it if
1899*c42dbd0eSchristos      our idea of the endianness has changed.  */
1900*c42dbd0eSchristos 
1901*c42dbd0eSchristos   if (old_endianness != fp->ctf_symsect_little_endian
1902*c42dbd0eSchristos       && fp->ctf_sxlate != NULL && fp->ctf_symtab.cts_data != NULL)
1903*c42dbd0eSchristos     assert (init_symtab (fp, fp->ctf_header, &fp->ctf_symtab) == 0);
1904*c42dbd0eSchristos }
1905*c42dbd0eSchristos 
1906*c42dbd0eSchristos /* Return the CTF handle for the parent CTF dict, if one exists.  Otherwise
1907*c42dbd0eSchristos    return NULL to indicate this dict has no imported parent.  */
1908*c42dbd0eSchristos ctf_dict_t *
ctf_parent_dict(ctf_dict_t * fp)1909*c42dbd0eSchristos ctf_parent_dict (ctf_dict_t *fp)
1910867d70fcSchristos {
1911867d70fcSchristos   return fp->ctf_parent;
1912867d70fcSchristos }
1913867d70fcSchristos 
1914*c42dbd0eSchristos /* Backward compatibility.  */
1915*c42dbd0eSchristos ctf_dict_t *
ctf_parent_file(ctf_dict_t * fp)1916*c42dbd0eSchristos ctf_parent_file (ctf_dict_t *fp)
1917*c42dbd0eSchristos {
1918*c42dbd0eSchristos   return ctf_parent_dict (fp);
1919*c42dbd0eSchristos }
1920*c42dbd0eSchristos 
1921*c42dbd0eSchristos /* Return the name of the parent CTF dict, if one exists, or NULL otherwise.  */
1922867d70fcSchristos const char *
ctf_parent_name(ctf_dict_t * fp)1923*c42dbd0eSchristos ctf_parent_name (ctf_dict_t *fp)
1924867d70fcSchristos {
1925867d70fcSchristos   return fp->ctf_parname;
1926867d70fcSchristos }
1927867d70fcSchristos 
1928867d70fcSchristos /* Set the parent name.  It is an error to call this routine without calling
1929867d70fcSchristos    ctf_import() at some point.  */
1930867d70fcSchristos int
ctf_parent_name_set(ctf_dict_t * fp,const char * name)1931*c42dbd0eSchristos ctf_parent_name_set (ctf_dict_t *fp, const char *name)
1932867d70fcSchristos {
1933867d70fcSchristos   if (fp->ctf_dynparname != NULL)
1934867d70fcSchristos     free (fp->ctf_dynparname);
1935867d70fcSchristos 
1936867d70fcSchristos   if ((fp->ctf_dynparname = strdup (name)) == NULL)
1937867d70fcSchristos     return (ctf_set_errno (fp, ENOMEM));
1938867d70fcSchristos   fp->ctf_parname = fp->ctf_dynparname;
1939867d70fcSchristos   return 0;
1940867d70fcSchristos }
1941867d70fcSchristos 
1942867d70fcSchristos /* Return the name of the compilation unit this CTF file applies to.  Usually
1943*c42dbd0eSchristos    non-NULL only for non-parent dicts.  */
1944867d70fcSchristos const char *
ctf_cuname(ctf_dict_t * fp)1945*c42dbd0eSchristos ctf_cuname (ctf_dict_t *fp)
1946867d70fcSchristos {
1947867d70fcSchristos   return fp->ctf_cuname;
1948867d70fcSchristos }
1949867d70fcSchristos 
1950867d70fcSchristos /* Set the compilation unit name.  */
1951867d70fcSchristos int
ctf_cuname_set(ctf_dict_t * fp,const char * name)1952*c42dbd0eSchristos ctf_cuname_set (ctf_dict_t *fp, const char *name)
1953867d70fcSchristos {
1954867d70fcSchristos   if (fp->ctf_dyncuname != NULL)
1955867d70fcSchristos     free (fp->ctf_dyncuname);
1956867d70fcSchristos 
1957867d70fcSchristos   if ((fp->ctf_dyncuname = strdup (name)) == NULL)
1958867d70fcSchristos     return (ctf_set_errno (fp, ENOMEM));
1959867d70fcSchristos   fp->ctf_cuname = fp->ctf_dyncuname;
1960867d70fcSchristos   return 0;
1961867d70fcSchristos }
1962867d70fcSchristos 
1963*c42dbd0eSchristos /* Import the types from the specified parent dict by storing a pointer to it in
1964*c42dbd0eSchristos    ctf_parent and incrementing its reference count.  Only one parent is allowed:
1965*c42dbd0eSchristos    if a parent already exists, it is replaced by the new parent.  The pptrtab
1966*c42dbd0eSchristos    is wiped, and will be refreshed by the next ctf_lookup_by_name call.  */
1967867d70fcSchristos int
ctf_import(ctf_dict_t * fp,ctf_dict_t * pfp)1968*c42dbd0eSchristos ctf_import (ctf_dict_t *fp, ctf_dict_t *pfp)
1969867d70fcSchristos {
1970867d70fcSchristos   if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))
1971867d70fcSchristos     return (ctf_set_errno (fp, EINVAL));
1972867d70fcSchristos 
1973867d70fcSchristos   if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)
1974867d70fcSchristos     return (ctf_set_errno (fp, ECTF_DMODEL));
1975867d70fcSchristos 
1976*c42dbd0eSchristos   if (fp->ctf_parent && !fp->ctf_parent_unreffed)
1977*c42dbd0eSchristos     ctf_dict_close (fp->ctf_parent);
1978867d70fcSchristos   fp->ctf_parent = NULL;
1979*c42dbd0eSchristos 
1980*c42dbd0eSchristos   free (fp->ctf_pptrtab);
1981*c42dbd0eSchristos   fp->ctf_pptrtab = NULL;
1982*c42dbd0eSchristos   fp->ctf_pptrtab_len = 0;
1983*c42dbd0eSchristos   fp->ctf_pptrtab_typemax = 0;
1984867d70fcSchristos 
1985867d70fcSchristos   if (pfp != NULL)
1986867d70fcSchristos     {
1987867d70fcSchristos       int err;
1988867d70fcSchristos 
1989867d70fcSchristos       if (fp->ctf_parname == NULL)
1990867d70fcSchristos 	if ((err = ctf_parent_name_set (fp, "PARENT")) < 0)
1991867d70fcSchristos 	  return err;
1992867d70fcSchristos 
1993867d70fcSchristos       fp->ctf_flags |= LCTF_CHILD;
1994867d70fcSchristos       pfp->ctf_refcnt++;
1995*c42dbd0eSchristos       fp->ctf_parent_unreffed = 0;
1996867d70fcSchristos     }
1997867d70fcSchristos 
1998867d70fcSchristos   fp->ctf_parent = pfp;
1999867d70fcSchristos   return 0;
2000867d70fcSchristos }
2001867d70fcSchristos 
2002*c42dbd0eSchristos /* Like ctf_import, but does not increment the refcount on the imported parent
2003*c42dbd0eSchristos    or close it at any point: as a result it can go away at any time and the
2004*c42dbd0eSchristos    caller must do all freeing itself.  Used internally to avoid refcount
2005*c42dbd0eSchristos    loops.  */
2006867d70fcSchristos int
ctf_import_unref(ctf_dict_t * fp,ctf_dict_t * pfp)2007*c42dbd0eSchristos ctf_import_unref (ctf_dict_t *fp, ctf_dict_t *pfp)
2008*c42dbd0eSchristos {
2009*c42dbd0eSchristos   if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))
2010*c42dbd0eSchristos     return (ctf_set_errno (fp, EINVAL));
2011*c42dbd0eSchristos 
2012*c42dbd0eSchristos   if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)
2013*c42dbd0eSchristos     return (ctf_set_errno (fp, ECTF_DMODEL));
2014*c42dbd0eSchristos 
2015*c42dbd0eSchristos   if (fp->ctf_parent && !fp->ctf_parent_unreffed)
2016*c42dbd0eSchristos     ctf_dict_close (fp->ctf_parent);
2017*c42dbd0eSchristos   fp->ctf_parent = NULL;
2018*c42dbd0eSchristos 
2019*c42dbd0eSchristos   free (fp->ctf_pptrtab);
2020*c42dbd0eSchristos   fp->ctf_pptrtab = NULL;
2021*c42dbd0eSchristos   fp->ctf_pptrtab_len = 0;
2022*c42dbd0eSchristos   fp->ctf_pptrtab_typemax = 0;
2023*c42dbd0eSchristos   if (pfp != NULL)
2024*c42dbd0eSchristos     {
2025*c42dbd0eSchristos       int err;
2026*c42dbd0eSchristos 
2027*c42dbd0eSchristos       if (fp->ctf_parname == NULL)
2028*c42dbd0eSchristos 	if ((err = ctf_parent_name_set (fp, "PARENT")) < 0)
2029*c42dbd0eSchristos 	  return err;
2030*c42dbd0eSchristos 
2031*c42dbd0eSchristos       fp->ctf_flags |= LCTF_CHILD;
2032*c42dbd0eSchristos       fp->ctf_parent_unreffed = 1;
2033*c42dbd0eSchristos     }
2034*c42dbd0eSchristos 
2035*c42dbd0eSchristos   fp->ctf_parent = pfp;
2036*c42dbd0eSchristos   return 0;
2037*c42dbd0eSchristos }
2038*c42dbd0eSchristos 
2039*c42dbd0eSchristos /* Set the data model constant for the CTF dict.  */
2040*c42dbd0eSchristos int
ctf_setmodel(ctf_dict_t * fp,int model)2041*c42dbd0eSchristos ctf_setmodel (ctf_dict_t *fp, int model)
2042867d70fcSchristos {
2043867d70fcSchristos   const ctf_dmodel_t *dp;
2044867d70fcSchristos 
2045867d70fcSchristos   for (dp = _libctf_models; dp->ctd_name != NULL; dp++)
2046867d70fcSchristos     {
2047867d70fcSchristos       if (dp->ctd_code == model)
2048867d70fcSchristos 	{
2049867d70fcSchristos 	  fp->ctf_dmodel = dp;
2050867d70fcSchristos 	  return 0;
2051867d70fcSchristos 	}
2052867d70fcSchristos     }
2053867d70fcSchristos 
2054867d70fcSchristos   return (ctf_set_errno (fp, EINVAL));
2055867d70fcSchristos }
2056867d70fcSchristos 
2057*c42dbd0eSchristos /* Return the data model constant for the CTF dict.  */
2058867d70fcSchristos int
ctf_getmodel(ctf_dict_t * fp)2059*c42dbd0eSchristos ctf_getmodel (ctf_dict_t *fp)
2060867d70fcSchristos {
2061867d70fcSchristos   return fp->ctf_dmodel->ctd_code;
2062867d70fcSchristos }
2063867d70fcSchristos 
2064*c42dbd0eSchristos /* The caller can hang an arbitrary pointer off each ctf_dict_t using this
2065867d70fcSchristos    function.  */
2066867d70fcSchristos void
ctf_setspecific(ctf_dict_t * fp,void * data)2067*c42dbd0eSchristos ctf_setspecific (ctf_dict_t *fp, void *data)
2068867d70fcSchristos {
2069867d70fcSchristos   fp->ctf_specific = data;
2070867d70fcSchristos }
2071867d70fcSchristos 
2072867d70fcSchristos /* Retrieve the arbitrary pointer again.  */
2073867d70fcSchristos void *
ctf_getspecific(ctf_dict_t * fp)2074*c42dbd0eSchristos ctf_getspecific (ctf_dict_t *fp)
2075867d70fcSchristos {
2076867d70fcSchristos   return fp->ctf_specific;
2077867d70fcSchristos }
2078