ctf-open.c revision 1.1.1.1.2.2 1 1.1.1.1.2.2 martin /* Opening CTF files.
2 1.1.1.1.2.2 martin Copyright (C) 2019-2020 Free Software Foundation, Inc.
3 1.1.1.1.2.2 martin
4 1.1.1.1.2.2 martin This file is part of libctf.
5 1.1.1.1.2.2 martin
6 1.1.1.1.2.2 martin libctf is free software; you can redistribute it and/or modify it under
7 1.1.1.1.2.2 martin the terms of the GNU General Public License as published by the Free
8 1.1.1.1.2.2 martin Software Foundation; either version 3, or (at your option) any later
9 1.1.1.1.2.2 martin version.
10 1.1.1.1.2.2 martin
11 1.1.1.1.2.2 martin This program is distributed in the hope that it will be useful, but
12 1.1.1.1.2.2 martin WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1.1.1.2.2 martin MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 1.1.1.1.2.2 martin See the GNU General Public License for more details.
15 1.1.1.1.2.2 martin
16 1.1.1.1.2.2 martin You should have received a copy of the GNU General Public License
17 1.1.1.1.2.2 martin along with this program; see the file COPYING. If not see
18 1.1.1.1.2.2 martin <http://www.gnu.org/licenses/>. */
19 1.1.1.1.2.2 martin
20 1.1.1.1.2.2 martin #include <ctf-impl.h>
21 1.1.1.1.2.2 martin #include <stddef.h>
22 1.1.1.1.2.2 martin #include <string.h>
23 1.1.1.1.2.2 martin #include <sys/types.h>
24 1.1.1.1.2.2 martin #include <elf.h>
25 1.1.1.1.2.2 martin #include <assert.h>
26 1.1.1.1.2.2 martin #include "swap.h"
27 1.1.1.1.2.2 martin #include <bfd.h>
28 1.1.1.1.2.2 martin #include <zlib.h>
29 1.1.1.1.2.2 martin
30 1.1.1.1.2.2 martin #include "elf-bfd.h"
31 1.1.1.1.2.2 martin
32 1.1.1.1.2.2 martin static const ctf_dmodel_t _libctf_models[] = {
33 1.1.1.1.2.2 martin {"ILP32", CTF_MODEL_ILP32, 4, 1, 2, 4, 4},
34 1.1.1.1.2.2 martin {"LP64", CTF_MODEL_LP64, 8, 1, 2, 4, 8},
35 1.1.1.1.2.2 martin {NULL, 0, 0, 0, 0, 0, 0}
36 1.1.1.1.2.2 martin };
37 1.1.1.1.2.2 martin
38 1.1.1.1.2.2 martin const char _CTF_SECTION[] = ".ctf";
39 1.1.1.1.2.2 martin const char _CTF_NULLSTR[] = "";
40 1.1.1.1.2.2 martin
41 1.1.1.1.2.2 martin /* Version-sensitive accessors. */
42 1.1.1.1.2.2 martin
43 1.1.1.1.2.2 martin static uint32_t
44 1.1.1.1.2.2 martin get_kind_v1 (uint32_t info)
45 1.1.1.1.2.2 martin {
46 1.1.1.1.2.2 martin return (CTF_V1_INFO_KIND (info));
47 1.1.1.1.2.2 martin }
48 1.1.1.1.2.2 martin
49 1.1.1.1.2.2 martin static uint32_t
50 1.1.1.1.2.2 martin get_root_v1 (uint32_t info)
51 1.1.1.1.2.2 martin {
52 1.1.1.1.2.2 martin return (CTF_V1_INFO_ISROOT (info));
53 1.1.1.1.2.2 martin }
54 1.1.1.1.2.2 martin
55 1.1.1.1.2.2 martin static uint32_t
56 1.1.1.1.2.2 martin get_vlen_v1 (uint32_t info)
57 1.1.1.1.2.2 martin {
58 1.1.1.1.2.2 martin return (CTF_V1_INFO_VLEN (info));
59 1.1.1.1.2.2 martin }
60 1.1.1.1.2.2 martin
61 1.1.1.1.2.2 martin static uint32_t
62 1.1.1.1.2.2 martin get_kind_v2 (uint32_t info)
63 1.1.1.1.2.2 martin {
64 1.1.1.1.2.2 martin return (CTF_V2_INFO_KIND (info));
65 1.1.1.1.2.2 martin }
66 1.1.1.1.2.2 martin
67 1.1.1.1.2.2 martin static uint32_t
68 1.1.1.1.2.2 martin get_root_v2 (uint32_t info)
69 1.1.1.1.2.2 martin {
70 1.1.1.1.2.2 martin return (CTF_V2_INFO_ISROOT (info));
71 1.1.1.1.2.2 martin }
72 1.1.1.1.2.2 martin
73 1.1.1.1.2.2 martin static uint32_t
74 1.1.1.1.2.2 martin get_vlen_v2 (uint32_t info)
75 1.1.1.1.2.2 martin {
76 1.1.1.1.2.2 martin return (CTF_V2_INFO_VLEN (info));
77 1.1.1.1.2.2 martin }
78 1.1.1.1.2.2 martin
79 1.1.1.1.2.2 martin static inline ssize_t
80 1.1.1.1.2.2 martin get_ctt_size_common (const ctf_file_t *fp _libctf_unused_,
81 1.1.1.1.2.2 martin const ctf_type_t *tp _libctf_unused_,
82 1.1.1.1.2.2 martin ssize_t *sizep, ssize_t *incrementp, size_t lsize,
83 1.1.1.1.2.2 martin size_t csize, size_t ctf_type_size,
84 1.1.1.1.2.2 martin size_t ctf_stype_size, size_t ctf_lsize_sent)
85 1.1.1.1.2.2 martin {
86 1.1.1.1.2.2 martin ssize_t size, increment;
87 1.1.1.1.2.2 martin
88 1.1.1.1.2.2 martin if (csize == ctf_lsize_sent)
89 1.1.1.1.2.2 martin {
90 1.1.1.1.2.2 martin size = lsize;
91 1.1.1.1.2.2 martin increment = ctf_type_size;
92 1.1.1.1.2.2 martin }
93 1.1.1.1.2.2 martin else
94 1.1.1.1.2.2 martin {
95 1.1.1.1.2.2 martin size = csize;
96 1.1.1.1.2.2 martin increment = ctf_stype_size;
97 1.1.1.1.2.2 martin }
98 1.1.1.1.2.2 martin
99 1.1.1.1.2.2 martin if (sizep)
100 1.1.1.1.2.2 martin *sizep = size;
101 1.1.1.1.2.2 martin if (incrementp)
102 1.1.1.1.2.2 martin *incrementp = increment;
103 1.1.1.1.2.2 martin
104 1.1.1.1.2.2 martin return size;
105 1.1.1.1.2.2 martin }
106 1.1.1.1.2.2 martin
107 1.1.1.1.2.2 martin static ssize_t
108 1.1.1.1.2.2 martin get_ctt_size_v1 (const ctf_file_t *fp, const ctf_type_t *tp,
109 1.1.1.1.2.2 martin ssize_t *sizep, ssize_t *incrementp)
110 1.1.1.1.2.2 martin {
111 1.1.1.1.2.2 martin ctf_type_v1_t *t1p = (ctf_type_v1_t *) tp;
112 1.1.1.1.2.2 martin
113 1.1.1.1.2.2 martin return (get_ctt_size_common (fp, tp, sizep, incrementp,
114 1.1.1.1.2.2 martin CTF_TYPE_LSIZE (t1p), t1p->ctt_size,
115 1.1.1.1.2.2 martin sizeof (ctf_type_v1_t), sizeof (ctf_stype_v1_t),
116 1.1.1.1.2.2 martin CTF_LSIZE_SENT_V1));
117 1.1.1.1.2.2 martin }
118 1.1.1.1.2.2 martin
119 1.1.1.1.2.2 martin /* Return the size that a v1 will be once it is converted to v2. */
120 1.1.1.1.2.2 martin
121 1.1.1.1.2.2 martin static ssize_t
122 1.1.1.1.2.2 martin get_ctt_size_v2_unconverted (const ctf_file_t *fp, const ctf_type_t *tp,
123 1.1.1.1.2.2 martin ssize_t *sizep, ssize_t *incrementp)
124 1.1.1.1.2.2 martin {
125 1.1.1.1.2.2 martin ctf_type_v1_t *t1p = (ctf_type_v1_t *) tp;
126 1.1.1.1.2.2 martin
127 1.1.1.1.2.2 martin return (get_ctt_size_common (fp, tp, sizep, incrementp,
128 1.1.1.1.2.2 martin CTF_TYPE_LSIZE (t1p), t1p->ctt_size,
129 1.1.1.1.2.2 martin sizeof (ctf_type_t), sizeof (ctf_stype_t),
130 1.1.1.1.2.2 martin CTF_LSIZE_SENT));
131 1.1.1.1.2.2 martin }
132 1.1.1.1.2.2 martin
133 1.1.1.1.2.2 martin static ssize_t
134 1.1.1.1.2.2 martin get_ctt_size_v2 (const ctf_file_t *fp, const ctf_type_t *tp,
135 1.1.1.1.2.2 martin ssize_t *sizep, ssize_t *incrementp)
136 1.1.1.1.2.2 martin {
137 1.1.1.1.2.2 martin return (get_ctt_size_common (fp, tp, sizep, incrementp,
138 1.1.1.1.2.2 martin CTF_TYPE_LSIZE (tp), tp->ctt_size,
139 1.1.1.1.2.2 martin sizeof (ctf_type_t), sizeof (ctf_stype_t),
140 1.1.1.1.2.2 martin CTF_LSIZE_SENT));
141 1.1.1.1.2.2 martin }
142 1.1.1.1.2.2 martin
143 1.1.1.1.2.2 martin static ssize_t
144 1.1.1.1.2.2 martin get_vbytes_common (unsigned short kind, ssize_t size _libctf_unused_,
145 1.1.1.1.2.2 martin size_t vlen)
146 1.1.1.1.2.2 martin {
147 1.1.1.1.2.2 martin switch (kind)
148 1.1.1.1.2.2 martin {
149 1.1.1.1.2.2 martin case CTF_K_INTEGER:
150 1.1.1.1.2.2 martin case CTF_K_FLOAT:
151 1.1.1.1.2.2 martin return (sizeof (uint32_t));
152 1.1.1.1.2.2 martin case CTF_K_SLICE:
153 1.1.1.1.2.2 martin return (sizeof (ctf_slice_t));
154 1.1.1.1.2.2 martin case CTF_K_ENUM:
155 1.1.1.1.2.2 martin return (sizeof (ctf_enum_t) * vlen);
156 1.1.1.1.2.2 martin case CTF_K_FORWARD:
157 1.1.1.1.2.2 martin case CTF_K_UNKNOWN:
158 1.1.1.1.2.2 martin case CTF_K_POINTER:
159 1.1.1.1.2.2 martin case CTF_K_TYPEDEF:
160 1.1.1.1.2.2 martin case CTF_K_VOLATILE:
161 1.1.1.1.2.2 martin case CTF_K_CONST:
162 1.1.1.1.2.2 martin case CTF_K_RESTRICT:
163 1.1.1.1.2.2 martin return 0;
164 1.1.1.1.2.2 martin default:
165 1.1.1.1.2.2 martin ctf_dprintf ("detected invalid CTF kind -- %x\n", kind);
166 1.1.1.1.2.2 martin return ECTF_CORRUPT;
167 1.1.1.1.2.2 martin }
168 1.1.1.1.2.2 martin }
169 1.1.1.1.2.2 martin
170 1.1.1.1.2.2 martin static ssize_t
171 1.1.1.1.2.2 martin get_vbytes_v1 (unsigned short kind, ssize_t size, size_t vlen)
172 1.1.1.1.2.2 martin {
173 1.1.1.1.2.2 martin switch (kind)
174 1.1.1.1.2.2 martin {
175 1.1.1.1.2.2 martin case CTF_K_ARRAY:
176 1.1.1.1.2.2 martin return (sizeof (ctf_array_v1_t));
177 1.1.1.1.2.2 martin case CTF_K_FUNCTION:
178 1.1.1.1.2.2 martin return (sizeof (unsigned short) * (vlen + (vlen & 1)));
179 1.1.1.1.2.2 martin case CTF_K_STRUCT:
180 1.1.1.1.2.2 martin case CTF_K_UNION:
181 1.1.1.1.2.2 martin if (size < CTF_LSTRUCT_THRESH_V1)
182 1.1.1.1.2.2 martin return (sizeof (ctf_member_v1_t) * vlen);
183 1.1.1.1.2.2 martin else
184 1.1.1.1.2.2 martin return (sizeof (ctf_lmember_v1_t) * vlen);
185 1.1.1.1.2.2 martin }
186 1.1.1.1.2.2 martin
187 1.1.1.1.2.2 martin return (get_vbytes_common (kind, size, vlen));
188 1.1.1.1.2.2 martin }
189 1.1.1.1.2.2 martin
190 1.1.1.1.2.2 martin static ssize_t
191 1.1.1.1.2.2 martin get_vbytes_v2 (unsigned short kind, ssize_t size, size_t vlen)
192 1.1.1.1.2.2 martin {
193 1.1.1.1.2.2 martin switch (kind)
194 1.1.1.1.2.2 martin {
195 1.1.1.1.2.2 martin case CTF_K_ARRAY:
196 1.1.1.1.2.2 martin return (sizeof (ctf_array_t));
197 1.1.1.1.2.2 martin case CTF_K_FUNCTION:
198 1.1.1.1.2.2 martin return (sizeof (uint32_t) * (vlen + (vlen & 1)));
199 1.1.1.1.2.2 martin case CTF_K_STRUCT:
200 1.1.1.1.2.2 martin case CTF_K_UNION:
201 1.1.1.1.2.2 martin if (size < CTF_LSTRUCT_THRESH)
202 1.1.1.1.2.2 martin return (sizeof (ctf_member_t) * vlen);
203 1.1.1.1.2.2 martin else
204 1.1.1.1.2.2 martin return (sizeof (ctf_lmember_t) * vlen);
205 1.1.1.1.2.2 martin }
206 1.1.1.1.2.2 martin
207 1.1.1.1.2.2 martin return (get_vbytes_common (kind, size, vlen));
208 1.1.1.1.2.2 martin }
209 1.1.1.1.2.2 martin
210 1.1.1.1.2.2 martin static const ctf_fileops_t ctf_fileops[] = {
211 1.1.1.1.2.2 martin {NULL, NULL, NULL, NULL, NULL},
212 1.1.1.1.2.2 martin /* CTF_VERSION_1 */
213 1.1.1.1.2.2 martin {get_kind_v1, get_root_v1, get_vlen_v1, get_ctt_size_v1, get_vbytes_v1},
214 1.1.1.1.2.2 martin /* CTF_VERSION_1_UPGRADED_3 */
215 1.1.1.1.2.2 martin {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
216 1.1.1.1.2.2 martin /* CTF_VERSION_2 */
217 1.1.1.1.2.2 martin {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
218 1.1.1.1.2.2 martin /* CTF_VERSION_3, identical to 2: only new type kinds */
219 1.1.1.1.2.2 martin {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
220 1.1.1.1.2.2 martin };
221 1.1.1.1.2.2 martin
222 1.1.1.1.2.2 martin /* Initialize the symtab translation table by filling each entry with the
223 1.1.1.1.2.2 martin offset of the CTF type or function data corresponding to each STT_FUNC or
224 1.1.1.1.2.2 martin STT_OBJECT entry in the symbol table. */
225 1.1.1.1.2.2 martin
226 1.1.1.1.2.2 martin static int
227 1.1.1.1.2.2 martin init_symtab (ctf_file_t *fp, const ctf_header_t *hp,
228 1.1.1.1.2.2 martin const ctf_sect_t *sp, const ctf_sect_t *strp)
229 1.1.1.1.2.2 martin {
230 1.1.1.1.2.2 martin const unsigned char *symp = sp->cts_data;
231 1.1.1.1.2.2 martin uint32_t *xp = fp->ctf_sxlate;
232 1.1.1.1.2.2 martin uint32_t *xend = xp + fp->ctf_nsyms;
233 1.1.1.1.2.2 martin
234 1.1.1.1.2.2 martin uint32_t objtoff = hp->cth_objtoff;
235 1.1.1.1.2.2 martin uint32_t funcoff = hp->cth_funcoff;
236 1.1.1.1.2.2 martin
237 1.1.1.1.2.2 martin uint32_t info, vlen;
238 1.1.1.1.2.2 martin Elf64_Sym sym, *gsp;
239 1.1.1.1.2.2 martin const char *name;
240 1.1.1.1.2.2 martin
241 1.1.1.1.2.2 martin /* The CTF data object and function type sections are ordered to match
242 1.1.1.1.2.2 martin the relative order of the respective symbol types in the symtab.
243 1.1.1.1.2.2 martin If no type information is available for a symbol table entry, a
244 1.1.1.1.2.2 martin pad is inserted in the CTF section. As a further optimization,
245 1.1.1.1.2.2 martin anonymous or undefined symbols are omitted from the CTF data. */
246 1.1.1.1.2.2 martin
247 1.1.1.1.2.2 martin for (; xp < xend; xp++, symp += sp->cts_entsize)
248 1.1.1.1.2.2 martin {
249 1.1.1.1.2.2 martin if (sp->cts_entsize == sizeof (Elf32_Sym))
250 1.1.1.1.2.2 martin gsp = ctf_sym_to_elf64 ((Elf32_Sym *) (uintptr_t) symp, &sym);
251 1.1.1.1.2.2 martin else
252 1.1.1.1.2.2 martin gsp = (Elf64_Sym *) (uintptr_t) symp;
253 1.1.1.1.2.2 martin
254 1.1.1.1.2.2 martin if (gsp->st_name < strp->cts_size)
255 1.1.1.1.2.2 martin name = (const char *) strp->cts_data + gsp->st_name;
256 1.1.1.1.2.2 martin else
257 1.1.1.1.2.2 martin name = _CTF_NULLSTR;
258 1.1.1.1.2.2 martin
259 1.1.1.1.2.2 martin if (gsp->st_name == 0 || gsp->st_shndx == SHN_UNDEF
260 1.1.1.1.2.2 martin || strcmp (name, "_START_") == 0 || strcmp (name, "_END_") == 0)
261 1.1.1.1.2.2 martin {
262 1.1.1.1.2.2 martin *xp = -1u;
263 1.1.1.1.2.2 martin continue;
264 1.1.1.1.2.2 martin }
265 1.1.1.1.2.2 martin
266 1.1.1.1.2.2 martin switch (ELF64_ST_TYPE (gsp->st_info))
267 1.1.1.1.2.2 martin {
268 1.1.1.1.2.2 martin case STT_OBJECT:
269 1.1.1.1.2.2 martin if (objtoff >= hp->cth_funcoff
270 1.1.1.1.2.2 martin || (gsp->st_shndx == SHN_EXTABS && gsp->st_value == 0))
271 1.1.1.1.2.2 martin {
272 1.1.1.1.2.2 martin *xp = -1u;
273 1.1.1.1.2.2 martin break;
274 1.1.1.1.2.2 martin }
275 1.1.1.1.2.2 martin
276 1.1.1.1.2.2 martin *xp = objtoff;
277 1.1.1.1.2.2 martin objtoff += sizeof (uint32_t);
278 1.1.1.1.2.2 martin break;
279 1.1.1.1.2.2 martin
280 1.1.1.1.2.2 martin case STT_FUNC:
281 1.1.1.1.2.2 martin if (funcoff >= hp->cth_objtidxoff)
282 1.1.1.1.2.2 martin {
283 1.1.1.1.2.2 martin *xp = -1u;
284 1.1.1.1.2.2 martin break;
285 1.1.1.1.2.2 martin }
286 1.1.1.1.2.2 martin
287 1.1.1.1.2.2 martin *xp = funcoff;
288 1.1.1.1.2.2 martin
289 1.1.1.1.2.2 martin info = *(uint32_t *) ((uintptr_t) fp->ctf_buf + funcoff);
290 1.1.1.1.2.2 martin vlen = LCTF_INFO_VLEN (fp, info);
291 1.1.1.1.2.2 martin
292 1.1.1.1.2.2 martin /* If we encounter a zero pad at the end, just skip it. Otherwise
293 1.1.1.1.2.2 martin skip over the function and its return type (+2) and the argument
294 1.1.1.1.2.2 martin list (vlen).
295 1.1.1.1.2.2 martin */
296 1.1.1.1.2.2 martin if (LCTF_INFO_KIND (fp, info) == CTF_K_UNKNOWN && vlen == 0)
297 1.1.1.1.2.2 martin funcoff += sizeof (uint32_t); /* Skip pad. */
298 1.1.1.1.2.2 martin else
299 1.1.1.1.2.2 martin funcoff += sizeof (uint32_t) * (vlen + 2);
300 1.1.1.1.2.2 martin break;
301 1.1.1.1.2.2 martin
302 1.1.1.1.2.2 martin default:
303 1.1.1.1.2.2 martin *xp = -1u;
304 1.1.1.1.2.2 martin break;
305 1.1.1.1.2.2 martin }
306 1.1.1.1.2.2 martin }
307 1.1.1.1.2.2 martin
308 1.1.1.1.2.2 martin ctf_dprintf ("loaded %lu symtab entries\n", fp->ctf_nsyms);
309 1.1.1.1.2.2 martin return 0;
310 1.1.1.1.2.2 martin }
311 1.1.1.1.2.2 martin
312 1.1.1.1.2.2 martin /* Reset the CTF base pointer and derive the buf pointer from it, initializing
313 1.1.1.1.2.2 martin everything in the ctf_file that depends on the base or buf pointers.
314 1.1.1.1.2.2 martin
315 1.1.1.1.2.2 martin The original gap between the buf and base pointers, if any -- the original,
316 1.1.1.1.2.2 martin unconverted CTF header -- is kept, but its contents are not specified and are
317 1.1.1.1.2.2 martin never used. */
318 1.1.1.1.2.2 martin
319 1.1.1.1.2.2 martin static void
320 1.1.1.1.2.2 martin ctf_set_base (ctf_file_t *fp, const ctf_header_t *hp, unsigned char *base)
321 1.1.1.1.2.2 martin {
322 1.1.1.1.2.2 martin fp->ctf_buf = base + (fp->ctf_buf - fp->ctf_base);
323 1.1.1.1.2.2 martin fp->ctf_base = base;
324 1.1.1.1.2.2 martin fp->ctf_vars = (ctf_varent_t *) ((const char *) fp->ctf_buf +
325 1.1.1.1.2.2 martin hp->cth_varoff);
326 1.1.1.1.2.2 martin fp->ctf_nvars = (hp->cth_typeoff - hp->cth_varoff) / sizeof (ctf_varent_t);
327 1.1.1.1.2.2 martin
328 1.1.1.1.2.2 martin fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *) fp->ctf_buf
329 1.1.1.1.2.2 martin + hp->cth_stroff;
330 1.1.1.1.2.2 martin fp->ctf_str[CTF_STRTAB_0].cts_len = hp->cth_strlen;
331 1.1.1.1.2.2 martin
332 1.1.1.1.2.2 martin /* If we have a parent container name and label, store the relocated
333 1.1.1.1.2.2 martin string pointers in the CTF container for easy access later. */
334 1.1.1.1.2.2 martin
335 1.1.1.1.2.2 martin /* Note: before conversion, these will be set to values that will be
336 1.1.1.1.2.2 martin immediately invalidated by the conversion process, but the conversion
337 1.1.1.1.2.2 martin process will call ctf_set_base() again to fix things up. */
338 1.1.1.1.2.2 martin
339 1.1.1.1.2.2 martin if (hp->cth_parlabel != 0)
340 1.1.1.1.2.2 martin fp->ctf_parlabel = ctf_strptr (fp, hp->cth_parlabel);
341 1.1.1.1.2.2 martin if (hp->cth_parname != 0)
342 1.1.1.1.2.2 martin fp->ctf_parname = ctf_strptr (fp, hp->cth_parname);
343 1.1.1.1.2.2 martin if (hp->cth_cuname != 0)
344 1.1.1.1.2.2 martin fp->ctf_cuname = ctf_strptr (fp, hp->cth_cuname);
345 1.1.1.1.2.2 martin
346 1.1.1.1.2.2 martin if (fp->ctf_cuname)
347 1.1.1.1.2.2 martin ctf_dprintf ("ctf_set_base: CU name %s\n", fp->ctf_cuname);
348 1.1.1.1.2.2 martin if (fp->ctf_parname)
349 1.1.1.1.2.2 martin ctf_dprintf ("ctf_set_base: parent name %s (label %s)\n",
350 1.1.1.1.2.2 martin fp->ctf_parname,
351 1.1.1.1.2.2 martin fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>");
352 1.1.1.1.2.2 martin }
353 1.1.1.1.2.2 martin
354 1.1.1.1.2.2 martin /* Set the version of the CTF file. */
355 1.1.1.1.2.2 martin
356 1.1.1.1.2.2 martin /* When this is reset, LCTF_* changes behaviour, but there is no guarantee that
357 1.1.1.1.2.2 martin the variable data list associated with each type has been upgraded: the
358 1.1.1.1.2.2 martin caller must ensure this has been done in advance. */
359 1.1.1.1.2.2 martin
360 1.1.1.1.2.2 martin static void
361 1.1.1.1.2.2 martin ctf_set_version (ctf_file_t *fp, ctf_header_t *cth, int ctf_version)
362 1.1.1.1.2.2 martin {
363 1.1.1.1.2.2 martin fp->ctf_version = ctf_version;
364 1.1.1.1.2.2 martin cth->cth_version = ctf_version;
365 1.1.1.1.2.2 martin fp->ctf_fileops = &ctf_fileops[ctf_version];
366 1.1.1.1.2.2 martin }
367 1.1.1.1.2.2 martin
368 1.1.1.1.2.2 martin
369 1.1.1.1.2.2 martin /* Upgrade the header to CTF_VERSION_3. The upgrade is done in-place. */
370 1.1.1.1.2.2 martin static void
371 1.1.1.1.2.2 martin upgrade_header (ctf_header_t *hp)
372 1.1.1.1.2.2 martin {
373 1.1.1.1.2.2 martin ctf_header_v2_t *oldhp = (ctf_header_v2_t *) hp;
374 1.1.1.1.2.2 martin
375 1.1.1.1.2.2 martin hp->cth_strlen = oldhp->cth_strlen;
376 1.1.1.1.2.2 martin hp->cth_stroff = oldhp->cth_stroff;
377 1.1.1.1.2.2 martin hp->cth_typeoff = oldhp->cth_typeoff;
378 1.1.1.1.2.2 martin hp->cth_varoff = oldhp->cth_varoff;
379 1.1.1.1.2.2 martin hp->cth_funcidxoff = hp->cth_varoff; /* No index sections. */
380 1.1.1.1.2.2 martin hp->cth_objtidxoff = hp->cth_funcidxoff;
381 1.1.1.1.2.2 martin hp->cth_funcoff = oldhp->cth_funcoff;
382 1.1.1.1.2.2 martin hp->cth_objtoff = oldhp->cth_objtoff;
383 1.1.1.1.2.2 martin hp->cth_lbloff = oldhp->cth_lbloff;
384 1.1.1.1.2.2 martin hp->cth_cuname = 0; /* No CU name. */
385 1.1.1.1.2.2 martin }
386 1.1.1.1.2.2 martin
387 1.1.1.1.2.2 martin /* Upgrade the type table to CTF_VERSION_3 (really CTF_VERSION_1_UPGRADED_3)
388 1.1.1.1.2.2 martin from CTF_VERSION_1.
389 1.1.1.1.2.2 martin
390 1.1.1.1.2.2 martin The upgrade is not done in-place: the ctf_base is moved. ctf_strptr() must
391 1.1.1.1.2.2 martin not be called before reallocation is complete.
392 1.1.1.1.2.2 martin
393 1.1.1.1.2.2 martin Sections not checked here due to nonexistence or nonpopulated state in older
394 1.1.1.1.2.2 martin formats: objtidx, funcidx.
395 1.1.1.1.2.2 martin
396 1.1.1.1.2.2 martin Type kinds not checked here due to nonexistence in older formats:
397 1.1.1.1.2.2 martin CTF_K_SLICE. */
398 1.1.1.1.2.2 martin static int
399 1.1.1.1.2.2 martin upgrade_types_v1 (ctf_file_t *fp, ctf_header_t *cth)
400 1.1.1.1.2.2 martin {
401 1.1.1.1.2.2 martin const ctf_type_v1_t *tbuf;
402 1.1.1.1.2.2 martin const ctf_type_v1_t *tend;
403 1.1.1.1.2.2 martin unsigned char *ctf_base, *old_ctf_base = (unsigned char *) fp->ctf_dynbase;
404 1.1.1.1.2.2 martin ctf_type_t *t2buf;
405 1.1.1.1.2.2 martin
406 1.1.1.1.2.2 martin ssize_t increase = 0, size, increment, v2increment, vbytes, v2bytes;
407 1.1.1.1.2.2 martin const ctf_type_v1_t *tp;
408 1.1.1.1.2.2 martin ctf_type_t *t2p;
409 1.1.1.1.2.2 martin
410 1.1.1.1.2.2 martin tbuf = (ctf_type_v1_t *) (fp->ctf_buf + cth->cth_typeoff);
411 1.1.1.1.2.2 martin tend = (ctf_type_v1_t *) (fp->ctf_buf + cth->cth_stroff);
412 1.1.1.1.2.2 martin
413 1.1.1.1.2.2 martin /* Much like init_types(), this is a two-pass process.
414 1.1.1.1.2.2 martin
415 1.1.1.1.2.2 martin First, figure out the new type-section size needed. (It is possible,
416 1.1.1.1.2.2 martin in theory, for it to be less than the old size, but this is very
417 1.1.1.1.2.2 martin unlikely. It cannot be so small that cth_typeoff ends up of negative
418 1.1.1.1.2.2 martin size. We validate this with an assertion below.)
419 1.1.1.1.2.2 martin
420 1.1.1.1.2.2 martin We must cater not only for changes in vlen and types sizes but also
421 1.1.1.1.2.2 martin for changes in 'increment', which happen because v2 places some types
422 1.1.1.1.2.2 martin into ctf_stype_t where v1 would be forced to use the larger non-stype. */
423 1.1.1.1.2.2 martin
424 1.1.1.1.2.2 martin for (tp = tbuf; tp < tend;
425 1.1.1.1.2.2 martin tp = (ctf_type_v1_t *) ((uintptr_t) tp + increment + vbytes))
426 1.1.1.1.2.2 martin {
427 1.1.1.1.2.2 martin unsigned short kind = CTF_V1_INFO_KIND (tp->ctt_info);
428 1.1.1.1.2.2 martin unsigned long vlen = CTF_V1_INFO_VLEN (tp->ctt_info);
429 1.1.1.1.2.2 martin
430 1.1.1.1.2.2 martin size = get_ctt_size_v1 (fp, (const ctf_type_t *) tp, NULL, &increment);
431 1.1.1.1.2.2 martin vbytes = get_vbytes_v1 (kind, size, vlen);
432 1.1.1.1.2.2 martin
433 1.1.1.1.2.2 martin get_ctt_size_v2_unconverted (fp, (const ctf_type_t *) tp, NULL,
434 1.1.1.1.2.2 martin &v2increment);
435 1.1.1.1.2.2 martin v2bytes = get_vbytes_v2 (kind, size, vlen);
436 1.1.1.1.2.2 martin
437 1.1.1.1.2.2 martin if ((vbytes < 0) || (size < 0))
438 1.1.1.1.2.2 martin return ECTF_CORRUPT;
439 1.1.1.1.2.2 martin
440 1.1.1.1.2.2 martin increase += v2increment - increment; /* May be negative. */
441 1.1.1.1.2.2 martin increase += v2bytes - vbytes;
442 1.1.1.1.2.2 martin }
443 1.1.1.1.2.2 martin
444 1.1.1.1.2.2 martin /* Allocate enough room for the new buffer, then copy everything but the type
445 1.1.1.1.2.2 martin section into place, and reset the base accordingly. Leave the version
446 1.1.1.1.2.2 martin number unchanged, so that LCTF_INFO_* still works on the
447 1.1.1.1.2.2 martin as-yet-untranslated type info. */
448 1.1.1.1.2.2 martin
449 1.1.1.1.2.2 martin if ((ctf_base = malloc (fp->ctf_size + increase)) == NULL)
450 1.1.1.1.2.2 martin return ECTF_ZALLOC;
451 1.1.1.1.2.2 martin
452 1.1.1.1.2.2 martin /* Start at ctf_buf, not ctf_base, to squeeze out the original header: we
453 1.1.1.1.2.2 martin never use it and it is unconverted. */
454 1.1.1.1.2.2 martin
455 1.1.1.1.2.2 martin memcpy (ctf_base, fp->ctf_buf, cth->cth_typeoff);
456 1.1.1.1.2.2 martin memcpy (ctf_base + cth->cth_stroff + increase,
457 1.1.1.1.2.2 martin fp->ctf_buf + cth->cth_stroff, cth->cth_strlen);
458 1.1.1.1.2.2 martin
459 1.1.1.1.2.2 martin memset (ctf_base + cth->cth_typeoff, 0, cth->cth_stroff - cth->cth_typeoff
460 1.1.1.1.2.2 martin + increase);
461 1.1.1.1.2.2 martin
462 1.1.1.1.2.2 martin cth->cth_stroff += increase;
463 1.1.1.1.2.2 martin fp->ctf_size += increase;
464 1.1.1.1.2.2 martin assert (cth->cth_stroff >= cth->cth_typeoff);
465 1.1.1.1.2.2 martin fp->ctf_base = ctf_base;
466 1.1.1.1.2.2 martin fp->ctf_buf = ctf_base;
467 1.1.1.1.2.2 martin fp->ctf_dynbase = ctf_base;
468 1.1.1.1.2.2 martin ctf_set_base (fp, cth, ctf_base);
469 1.1.1.1.2.2 martin
470 1.1.1.1.2.2 martin t2buf = (ctf_type_t *) (fp->ctf_buf + cth->cth_typeoff);
471 1.1.1.1.2.2 martin
472 1.1.1.1.2.2 martin /* Iterate through all the types again, upgrading them.
473 1.1.1.1.2.2 martin
474 1.1.1.1.2.2 martin Everything that hasn't changed can just be outright memcpy()ed.
475 1.1.1.1.2.2 martin Things that have changed need field-by-field consideration. */
476 1.1.1.1.2.2 martin
477 1.1.1.1.2.2 martin for (tp = tbuf, t2p = t2buf; tp < tend;
478 1.1.1.1.2.2 martin tp = (ctf_type_v1_t *) ((uintptr_t) tp + increment + vbytes),
479 1.1.1.1.2.2 martin t2p = (ctf_type_t *) ((uintptr_t) t2p + v2increment + v2bytes))
480 1.1.1.1.2.2 martin {
481 1.1.1.1.2.2 martin unsigned short kind = CTF_V1_INFO_KIND (tp->ctt_info);
482 1.1.1.1.2.2 martin int isroot = CTF_V1_INFO_ISROOT (tp->ctt_info);
483 1.1.1.1.2.2 martin unsigned long vlen = CTF_V1_INFO_VLEN (tp->ctt_info);
484 1.1.1.1.2.2 martin ssize_t v2size;
485 1.1.1.1.2.2 martin void *vdata, *v2data;
486 1.1.1.1.2.2 martin
487 1.1.1.1.2.2 martin size = get_ctt_size_v1 (fp, (const ctf_type_t *) tp, NULL, &increment);
488 1.1.1.1.2.2 martin vbytes = get_vbytes_v1 (kind, size, vlen);
489 1.1.1.1.2.2 martin
490 1.1.1.1.2.2 martin t2p->ctt_name = tp->ctt_name;
491 1.1.1.1.2.2 martin t2p->ctt_info = CTF_TYPE_INFO (kind, isroot, vlen);
492 1.1.1.1.2.2 martin
493 1.1.1.1.2.2 martin switch (kind)
494 1.1.1.1.2.2 martin {
495 1.1.1.1.2.2 martin case CTF_K_FUNCTION:
496 1.1.1.1.2.2 martin case CTF_K_FORWARD:
497 1.1.1.1.2.2 martin case CTF_K_TYPEDEF:
498 1.1.1.1.2.2 martin case CTF_K_POINTER:
499 1.1.1.1.2.2 martin case CTF_K_VOLATILE:
500 1.1.1.1.2.2 martin case CTF_K_CONST:
501 1.1.1.1.2.2 martin case CTF_K_RESTRICT:
502 1.1.1.1.2.2 martin t2p->ctt_type = tp->ctt_type;
503 1.1.1.1.2.2 martin break;
504 1.1.1.1.2.2 martin case CTF_K_INTEGER:
505 1.1.1.1.2.2 martin case CTF_K_FLOAT:
506 1.1.1.1.2.2 martin case CTF_K_ARRAY:
507 1.1.1.1.2.2 martin case CTF_K_STRUCT:
508 1.1.1.1.2.2 martin case CTF_K_UNION:
509 1.1.1.1.2.2 martin case CTF_K_ENUM:
510 1.1.1.1.2.2 martin case CTF_K_UNKNOWN:
511 1.1.1.1.2.2 martin if ((size_t) size <= CTF_MAX_SIZE)
512 1.1.1.1.2.2 martin t2p->ctt_size = size;
513 1.1.1.1.2.2 martin else
514 1.1.1.1.2.2 martin {
515 1.1.1.1.2.2 martin t2p->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
516 1.1.1.1.2.2 martin t2p->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
517 1.1.1.1.2.2 martin }
518 1.1.1.1.2.2 martin break;
519 1.1.1.1.2.2 martin }
520 1.1.1.1.2.2 martin
521 1.1.1.1.2.2 martin v2size = get_ctt_size_v2 (fp, t2p, NULL, &v2increment);
522 1.1.1.1.2.2 martin v2bytes = get_vbytes_v2 (kind, v2size, vlen);
523 1.1.1.1.2.2 martin
524 1.1.1.1.2.2 martin /* Catch out-of-sync get_ctt_size_*(). The count goes wrong if
525 1.1.1.1.2.2 martin these are not identical (and having them different makes no
526 1.1.1.1.2.2 martin sense semantically). */
527 1.1.1.1.2.2 martin
528 1.1.1.1.2.2 martin assert (size == v2size);
529 1.1.1.1.2.2 martin
530 1.1.1.1.2.2 martin /* Now the varlen info. */
531 1.1.1.1.2.2 martin
532 1.1.1.1.2.2 martin vdata = (void *) ((uintptr_t) tp + increment);
533 1.1.1.1.2.2 martin v2data = (void *) ((uintptr_t) t2p + v2increment);
534 1.1.1.1.2.2 martin
535 1.1.1.1.2.2 martin switch (kind)
536 1.1.1.1.2.2 martin {
537 1.1.1.1.2.2 martin case CTF_K_ARRAY:
538 1.1.1.1.2.2 martin {
539 1.1.1.1.2.2 martin const ctf_array_v1_t *ap = (const ctf_array_v1_t *) vdata;
540 1.1.1.1.2.2 martin ctf_array_t *a2p = (ctf_array_t *) v2data;
541 1.1.1.1.2.2 martin
542 1.1.1.1.2.2 martin a2p->cta_contents = ap->cta_contents;
543 1.1.1.1.2.2 martin a2p->cta_index = ap->cta_index;
544 1.1.1.1.2.2 martin a2p->cta_nelems = ap->cta_nelems;
545 1.1.1.1.2.2 martin break;
546 1.1.1.1.2.2 martin }
547 1.1.1.1.2.2 martin case CTF_K_STRUCT:
548 1.1.1.1.2.2 martin case CTF_K_UNION:
549 1.1.1.1.2.2 martin {
550 1.1.1.1.2.2 martin ctf_member_t tmp;
551 1.1.1.1.2.2 martin const ctf_member_v1_t *m1 = (const ctf_member_v1_t *) vdata;
552 1.1.1.1.2.2 martin const ctf_lmember_v1_t *lm1 = (const ctf_lmember_v1_t *) m1;
553 1.1.1.1.2.2 martin ctf_member_t *m2 = (ctf_member_t *) v2data;
554 1.1.1.1.2.2 martin ctf_lmember_t *lm2 = (ctf_lmember_t *) m2;
555 1.1.1.1.2.2 martin unsigned long i;
556 1.1.1.1.2.2 martin
557 1.1.1.1.2.2 martin /* We walk all four pointers forward, but only reference the two
558 1.1.1.1.2.2 martin that are valid for the given size, to avoid quadruplicating all
559 1.1.1.1.2.2 martin the code. */
560 1.1.1.1.2.2 martin
561 1.1.1.1.2.2 martin for (i = vlen; i != 0; i--, m1++, lm1++, m2++, lm2++)
562 1.1.1.1.2.2 martin {
563 1.1.1.1.2.2 martin size_t offset;
564 1.1.1.1.2.2 martin if (size < CTF_LSTRUCT_THRESH_V1)
565 1.1.1.1.2.2 martin {
566 1.1.1.1.2.2 martin offset = m1->ctm_offset;
567 1.1.1.1.2.2 martin tmp.ctm_name = m1->ctm_name;
568 1.1.1.1.2.2 martin tmp.ctm_type = m1->ctm_type;
569 1.1.1.1.2.2 martin }
570 1.1.1.1.2.2 martin else
571 1.1.1.1.2.2 martin {
572 1.1.1.1.2.2 martin offset = CTF_LMEM_OFFSET (lm1);
573 1.1.1.1.2.2 martin tmp.ctm_name = lm1->ctlm_name;
574 1.1.1.1.2.2 martin tmp.ctm_type = lm1->ctlm_type;
575 1.1.1.1.2.2 martin }
576 1.1.1.1.2.2 martin if (size < CTF_LSTRUCT_THRESH)
577 1.1.1.1.2.2 martin {
578 1.1.1.1.2.2 martin m2->ctm_name = tmp.ctm_name;
579 1.1.1.1.2.2 martin m2->ctm_type = tmp.ctm_type;
580 1.1.1.1.2.2 martin m2->ctm_offset = offset;
581 1.1.1.1.2.2 martin }
582 1.1.1.1.2.2 martin else
583 1.1.1.1.2.2 martin {
584 1.1.1.1.2.2 martin lm2->ctlm_name = tmp.ctm_name;
585 1.1.1.1.2.2 martin lm2->ctlm_type = tmp.ctm_type;
586 1.1.1.1.2.2 martin lm2->ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (offset);
587 1.1.1.1.2.2 martin lm2->ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (offset);
588 1.1.1.1.2.2 martin }
589 1.1.1.1.2.2 martin }
590 1.1.1.1.2.2 martin break;
591 1.1.1.1.2.2 martin }
592 1.1.1.1.2.2 martin case CTF_K_FUNCTION:
593 1.1.1.1.2.2 martin {
594 1.1.1.1.2.2 martin unsigned long i;
595 1.1.1.1.2.2 martin unsigned short *a1 = (unsigned short *) vdata;
596 1.1.1.1.2.2 martin uint32_t *a2 = (uint32_t *) v2data;
597 1.1.1.1.2.2 martin
598 1.1.1.1.2.2 martin for (i = vlen; i != 0; i--, a1++, a2++)
599 1.1.1.1.2.2 martin *a2 = *a1;
600 1.1.1.1.2.2 martin }
601 1.1.1.1.2.2 martin /* FALLTHRU */
602 1.1.1.1.2.2 martin default:
603 1.1.1.1.2.2 martin /* Catch out-of-sync get_vbytes_*(). */
604 1.1.1.1.2.2 martin assert (vbytes == v2bytes);
605 1.1.1.1.2.2 martin memcpy (v2data, vdata, vbytes);
606 1.1.1.1.2.2 martin }
607 1.1.1.1.2.2 martin }
608 1.1.1.1.2.2 martin
609 1.1.1.1.2.2 martin /* Verify that the entire region was converted. If not, we are either
610 1.1.1.1.2.2 martin converting too much, or too little (leading to a buffer overrun either here
611 1.1.1.1.2.2 martin or at read time, in init_types().) */
612 1.1.1.1.2.2 martin
613 1.1.1.1.2.2 martin assert ((size_t) t2p - (size_t) fp->ctf_buf == cth->cth_stroff);
614 1.1.1.1.2.2 martin
615 1.1.1.1.2.2 martin ctf_set_version (fp, cth, CTF_VERSION_1_UPGRADED_3);
616 1.1.1.1.2.2 martin free (old_ctf_base);
617 1.1.1.1.2.2 martin
618 1.1.1.1.2.2 martin return 0;
619 1.1.1.1.2.2 martin }
620 1.1.1.1.2.2 martin
621 1.1.1.1.2.2 martin /* Upgrade from any earlier version. */
622 1.1.1.1.2.2 martin static int
623 1.1.1.1.2.2 martin upgrade_types (ctf_file_t *fp, ctf_header_t *cth)
624 1.1.1.1.2.2 martin {
625 1.1.1.1.2.2 martin switch (cth->cth_version)
626 1.1.1.1.2.2 martin {
627 1.1.1.1.2.2 martin /* v1 requires a full pass and reformatting. */
628 1.1.1.1.2.2 martin case CTF_VERSION_1:
629 1.1.1.1.2.2 martin upgrade_types_v1 (fp, cth);
630 1.1.1.1.2.2 martin /* FALLTHRU */
631 1.1.1.1.2.2 martin /* Already-converted v1 is just like later versions except that its
632 1.1.1.1.2.2 martin parent/child boundary is unchanged (and much lower). */
633 1.1.1.1.2.2 martin
634 1.1.1.1.2.2 martin case CTF_VERSION_1_UPGRADED_3:
635 1.1.1.1.2.2 martin fp->ctf_parmax = CTF_MAX_PTYPE_V1;
636 1.1.1.1.2.2 martin
637 1.1.1.1.2.2 martin /* v2 is just the same as v3 except for new types and sections:
638 1.1.1.1.2.2 martin no upgrading required. */
639 1.1.1.1.2.2 martin case CTF_VERSION_2: ;
640 1.1.1.1.2.2 martin /* FALLTHRU */
641 1.1.1.1.2.2 martin }
642 1.1.1.1.2.2 martin return 0;
643 1.1.1.1.2.2 martin }
644 1.1.1.1.2.2 martin
645 1.1.1.1.2.2 martin /* Initialize the type ID translation table with the byte offset of each type,
646 1.1.1.1.2.2 martin and initialize the hash tables of each named type. Upgrade the type table to
647 1.1.1.1.2.2 martin the latest supported representation in the process, if needed, and if this
648 1.1.1.1.2.2 martin recension of libctf supports upgrading. */
649 1.1.1.1.2.2 martin
650 1.1.1.1.2.2 martin static int
651 1.1.1.1.2.2 martin init_types (ctf_file_t *fp, ctf_header_t *cth)
652 1.1.1.1.2.2 martin {
653 1.1.1.1.2.2 martin const ctf_type_t *tbuf;
654 1.1.1.1.2.2 martin const ctf_type_t *tend;
655 1.1.1.1.2.2 martin
656 1.1.1.1.2.2 martin unsigned long pop[CTF_K_MAX + 1] = { 0 };
657 1.1.1.1.2.2 martin const ctf_type_t *tp;
658 1.1.1.1.2.2 martin uint32_t id, dst;
659 1.1.1.1.2.2 martin uint32_t *xp;
660 1.1.1.1.2.2 martin
661 1.1.1.1.2.2 martin /* We determine whether the container is a child or a parent based on
662 1.1.1.1.2.2 martin the value of cth_parname. */
663 1.1.1.1.2.2 martin
664 1.1.1.1.2.2 martin int child = cth->cth_parname != 0;
665 1.1.1.1.2.2 martin int nlstructs = 0, nlunions = 0;
666 1.1.1.1.2.2 martin int err;
667 1.1.1.1.2.2 martin
668 1.1.1.1.2.2 martin assert (!(fp->ctf_flags & LCTF_RDWR));
669 1.1.1.1.2.2 martin
670 1.1.1.1.2.2 martin if (_libctf_unlikely_ (fp->ctf_version == CTF_VERSION_1))
671 1.1.1.1.2.2 martin {
672 1.1.1.1.2.2 martin int err;
673 1.1.1.1.2.2 martin if ((err = upgrade_types (fp, cth)) != 0)
674 1.1.1.1.2.2 martin return err; /* Upgrade failed. */
675 1.1.1.1.2.2 martin }
676 1.1.1.1.2.2 martin
677 1.1.1.1.2.2 martin tbuf = (ctf_type_t *) (fp->ctf_buf + cth->cth_typeoff);
678 1.1.1.1.2.2 martin tend = (ctf_type_t *) (fp->ctf_buf + cth->cth_stroff);
679 1.1.1.1.2.2 martin
680 1.1.1.1.2.2 martin /* We make two passes through the entire type section. In this first
681 1.1.1.1.2.2 martin pass, we count the number of each type and the total number of types. */
682 1.1.1.1.2.2 martin
683 1.1.1.1.2.2 martin for (tp = tbuf; tp < tend; fp->ctf_typemax++)
684 1.1.1.1.2.2 martin {
685 1.1.1.1.2.2 martin unsigned short kind = LCTF_INFO_KIND (fp, tp->ctt_info);
686 1.1.1.1.2.2 martin unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
687 1.1.1.1.2.2 martin ssize_t size, increment, vbytes;
688 1.1.1.1.2.2 martin
689 1.1.1.1.2.2 martin (void) ctf_get_ctt_size (fp, tp, &size, &increment);
690 1.1.1.1.2.2 martin vbytes = LCTF_VBYTES (fp, kind, size, vlen);
691 1.1.1.1.2.2 martin
692 1.1.1.1.2.2 martin if (vbytes < 0)
693 1.1.1.1.2.2 martin return ECTF_CORRUPT;
694 1.1.1.1.2.2 martin
695 1.1.1.1.2.2 martin if (kind == CTF_K_FORWARD)
696 1.1.1.1.2.2 martin {
697 1.1.1.1.2.2 martin /* For forward declarations, ctt_type is the CTF_K_* kind for the tag,
698 1.1.1.1.2.2 martin so bump that population count too. If ctt_type is unknown, treat
699 1.1.1.1.2.2 martin the tag as a struct. */
700 1.1.1.1.2.2 martin
701 1.1.1.1.2.2 martin if (tp->ctt_type == CTF_K_UNKNOWN || tp->ctt_type >= CTF_K_MAX)
702 1.1.1.1.2.2 martin pop[CTF_K_STRUCT]++;
703 1.1.1.1.2.2 martin else
704 1.1.1.1.2.2 martin pop[tp->ctt_type]++;
705 1.1.1.1.2.2 martin }
706 1.1.1.1.2.2 martin tp = (ctf_type_t *) ((uintptr_t) tp + increment + vbytes);
707 1.1.1.1.2.2 martin pop[kind]++;
708 1.1.1.1.2.2 martin }
709 1.1.1.1.2.2 martin
710 1.1.1.1.2.2 martin if (child)
711 1.1.1.1.2.2 martin {
712 1.1.1.1.2.2 martin ctf_dprintf ("CTF container %p is a child\n", (void *) fp);
713 1.1.1.1.2.2 martin fp->ctf_flags |= LCTF_CHILD;
714 1.1.1.1.2.2 martin }
715 1.1.1.1.2.2 martin else
716 1.1.1.1.2.2 martin ctf_dprintf ("CTF container %p is a parent\n", (void *) fp);
717 1.1.1.1.2.2 martin
718 1.1.1.1.2.2 martin /* Now that we've counted up the number of each type, we can allocate
719 1.1.1.1.2.2 martin the hash tables, type translation table, and pointer table. */
720 1.1.1.1.2.2 martin
721 1.1.1.1.2.2 martin if ((fp->ctf_structs.ctn_readonly
722 1.1.1.1.2.2 martin = ctf_hash_create (pop[CTF_K_STRUCT], ctf_hash_string,
723 1.1.1.1.2.2 martin ctf_hash_eq_string)) == NULL)
724 1.1.1.1.2.2 martin return ENOMEM;
725 1.1.1.1.2.2 martin
726 1.1.1.1.2.2 martin if ((fp->ctf_unions.ctn_readonly
727 1.1.1.1.2.2 martin = ctf_hash_create (pop[CTF_K_UNION], ctf_hash_string,
728 1.1.1.1.2.2 martin ctf_hash_eq_string)) == NULL)
729 1.1.1.1.2.2 martin return ENOMEM;
730 1.1.1.1.2.2 martin
731 1.1.1.1.2.2 martin if ((fp->ctf_enums.ctn_readonly
732 1.1.1.1.2.2 martin = ctf_hash_create (pop[CTF_K_ENUM], ctf_hash_string,
733 1.1.1.1.2.2 martin ctf_hash_eq_string)) == NULL)
734 1.1.1.1.2.2 martin return ENOMEM;
735 1.1.1.1.2.2 martin
736 1.1.1.1.2.2 martin if ((fp->ctf_names.ctn_readonly
737 1.1.1.1.2.2 martin = ctf_hash_create (pop[CTF_K_INTEGER] +
738 1.1.1.1.2.2 martin pop[CTF_K_FLOAT] +
739 1.1.1.1.2.2 martin pop[CTF_K_FUNCTION] +
740 1.1.1.1.2.2 martin pop[CTF_K_TYPEDEF] +
741 1.1.1.1.2.2 martin pop[CTF_K_POINTER] +
742 1.1.1.1.2.2 martin pop[CTF_K_VOLATILE] +
743 1.1.1.1.2.2 martin pop[CTF_K_CONST] +
744 1.1.1.1.2.2 martin pop[CTF_K_RESTRICT],
745 1.1.1.1.2.2 martin ctf_hash_string,
746 1.1.1.1.2.2 martin ctf_hash_eq_string)) == NULL)
747 1.1.1.1.2.2 martin return ENOMEM;
748 1.1.1.1.2.2 martin
749 1.1.1.1.2.2 martin fp->ctf_txlate = malloc (sizeof (uint32_t) * (fp->ctf_typemax + 1));
750 1.1.1.1.2.2 martin fp->ctf_ptrtab_len = fp->ctf_typemax + 1;
751 1.1.1.1.2.2 martin fp->ctf_ptrtab = malloc (sizeof (uint32_t) * fp->ctf_ptrtab_len);
752 1.1.1.1.2.2 martin
753 1.1.1.1.2.2 martin if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL)
754 1.1.1.1.2.2 martin return ENOMEM; /* Memory allocation failed. */
755 1.1.1.1.2.2 martin
756 1.1.1.1.2.2 martin xp = fp->ctf_txlate;
757 1.1.1.1.2.2 martin *xp++ = 0; /* Type id 0 is used as a sentinel value. */
758 1.1.1.1.2.2 martin
759 1.1.1.1.2.2 martin memset (fp->ctf_txlate, 0, sizeof (uint32_t) * (fp->ctf_typemax + 1));
760 1.1.1.1.2.2 martin memset (fp->ctf_ptrtab, 0, sizeof (uint32_t) * (fp->ctf_typemax + 1));
761 1.1.1.1.2.2 martin
762 1.1.1.1.2.2 martin /* In the second pass through the types, we fill in each entry of the
763 1.1.1.1.2.2 martin type and pointer tables and add names to the appropriate hashes. */
764 1.1.1.1.2.2 martin
765 1.1.1.1.2.2 martin for (id = 1, tp = tbuf; tp < tend; xp++, id++)
766 1.1.1.1.2.2 martin {
767 1.1.1.1.2.2 martin unsigned short kind = LCTF_INFO_KIND (fp, tp->ctt_info);
768 1.1.1.1.2.2 martin unsigned short flag = LCTF_INFO_ISROOT (fp, tp->ctt_info);
769 1.1.1.1.2.2 martin unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
770 1.1.1.1.2.2 martin ssize_t size, increment, vbytes;
771 1.1.1.1.2.2 martin
772 1.1.1.1.2.2 martin const char *name;
773 1.1.1.1.2.2 martin
774 1.1.1.1.2.2 martin (void) ctf_get_ctt_size (fp, tp, &size, &increment);
775 1.1.1.1.2.2 martin name = ctf_strptr (fp, tp->ctt_name);
776 1.1.1.1.2.2 martin vbytes = LCTF_VBYTES (fp, kind, size, vlen);
777 1.1.1.1.2.2 martin
778 1.1.1.1.2.2 martin switch (kind)
779 1.1.1.1.2.2 martin {
780 1.1.1.1.2.2 martin case CTF_K_INTEGER:
781 1.1.1.1.2.2 martin case CTF_K_FLOAT:
782 1.1.1.1.2.2 martin /* Names are reused by bit-fields, which are differentiated by their
783 1.1.1.1.2.2 martin encodings, and so typically we'd record only the first instance of
784 1.1.1.1.2.2 martin a given intrinsic. However, we replace an existing type with a
785 1.1.1.1.2.2 martin root-visible version so that we can be sure to find it when
786 1.1.1.1.2.2 martin checking for conflicting definitions in ctf_add_type(). */
787 1.1.1.1.2.2 martin
788 1.1.1.1.2.2 martin if (((ctf_hash_lookup_type (fp->ctf_names.ctn_readonly,
789 1.1.1.1.2.2 martin fp, name)) == 0)
790 1.1.1.1.2.2 martin || (flag & CTF_ADD_ROOT))
791 1.1.1.1.2.2 martin {
792 1.1.1.1.2.2 martin err = ctf_hash_define_type (fp->ctf_names.ctn_readonly, fp,
793 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
794 1.1.1.1.2.2 martin tp->ctt_name);
795 1.1.1.1.2.2 martin if (err != 0)
796 1.1.1.1.2.2 martin return err;
797 1.1.1.1.2.2 martin }
798 1.1.1.1.2.2 martin break;
799 1.1.1.1.2.2 martin
800 1.1.1.1.2.2 martin /* These kinds have no name, so do not need interning into any
801 1.1.1.1.2.2 martin hashtables. */
802 1.1.1.1.2.2 martin case CTF_K_ARRAY:
803 1.1.1.1.2.2 martin case CTF_K_SLICE:
804 1.1.1.1.2.2 martin break;
805 1.1.1.1.2.2 martin
806 1.1.1.1.2.2 martin case CTF_K_FUNCTION:
807 1.1.1.1.2.2 martin err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
808 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
809 1.1.1.1.2.2 martin tp->ctt_name);
810 1.1.1.1.2.2 martin if (err != 0)
811 1.1.1.1.2.2 martin return err;
812 1.1.1.1.2.2 martin break;
813 1.1.1.1.2.2 martin
814 1.1.1.1.2.2 martin case CTF_K_STRUCT:
815 1.1.1.1.2.2 martin err = ctf_hash_define_type (fp->ctf_structs.ctn_readonly, fp,
816 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
817 1.1.1.1.2.2 martin tp->ctt_name);
818 1.1.1.1.2.2 martin
819 1.1.1.1.2.2 martin if (err != 0)
820 1.1.1.1.2.2 martin return err;
821 1.1.1.1.2.2 martin
822 1.1.1.1.2.2 martin if (size >= CTF_LSTRUCT_THRESH)
823 1.1.1.1.2.2 martin nlstructs++;
824 1.1.1.1.2.2 martin break;
825 1.1.1.1.2.2 martin
826 1.1.1.1.2.2 martin case CTF_K_UNION:
827 1.1.1.1.2.2 martin err = ctf_hash_define_type (fp->ctf_unions.ctn_readonly, fp,
828 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
829 1.1.1.1.2.2 martin tp->ctt_name);
830 1.1.1.1.2.2 martin
831 1.1.1.1.2.2 martin if (err != 0)
832 1.1.1.1.2.2 martin return err;
833 1.1.1.1.2.2 martin
834 1.1.1.1.2.2 martin if (size >= CTF_LSTRUCT_THRESH)
835 1.1.1.1.2.2 martin nlunions++;
836 1.1.1.1.2.2 martin break;
837 1.1.1.1.2.2 martin
838 1.1.1.1.2.2 martin case CTF_K_ENUM:
839 1.1.1.1.2.2 martin err = ctf_hash_define_type (fp->ctf_enums.ctn_readonly, fp,
840 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
841 1.1.1.1.2.2 martin tp->ctt_name);
842 1.1.1.1.2.2 martin
843 1.1.1.1.2.2 martin if (err != 0)
844 1.1.1.1.2.2 martin return err;
845 1.1.1.1.2.2 martin break;
846 1.1.1.1.2.2 martin
847 1.1.1.1.2.2 martin case CTF_K_TYPEDEF:
848 1.1.1.1.2.2 martin err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
849 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
850 1.1.1.1.2.2 martin tp->ctt_name);
851 1.1.1.1.2.2 martin if (err != 0)
852 1.1.1.1.2.2 martin return err;
853 1.1.1.1.2.2 martin break;
854 1.1.1.1.2.2 martin
855 1.1.1.1.2.2 martin case CTF_K_FORWARD:
856 1.1.1.1.2.2 martin {
857 1.1.1.1.2.2 martin ctf_names_t *np = ctf_name_table (fp, tp->ctt_type);
858 1.1.1.1.2.2 martin /* Only insert forward tags into the given hash if the type or tag
859 1.1.1.1.2.2 martin name is not already present. */
860 1.1.1.1.2.2 martin if (ctf_hash_lookup_type (np->ctn_readonly, fp, name) == 0)
861 1.1.1.1.2.2 martin {
862 1.1.1.1.2.2 martin err = ctf_hash_insert_type (np->ctn_readonly, fp,
863 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
864 1.1.1.1.2.2 martin tp->ctt_name);
865 1.1.1.1.2.2 martin if (err != 0)
866 1.1.1.1.2.2 martin return err;
867 1.1.1.1.2.2 martin }
868 1.1.1.1.2.2 martin break;
869 1.1.1.1.2.2 martin }
870 1.1.1.1.2.2 martin
871 1.1.1.1.2.2 martin case CTF_K_POINTER:
872 1.1.1.1.2.2 martin /* If the type referenced by the pointer is in this CTF container,
873 1.1.1.1.2.2 martin then store the index of the pointer type in
874 1.1.1.1.2.2 martin fp->ctf_ptrtab[ index of referenced type ]. */
875 1.1.1.1.2.2 martin
876 1.1.1.1.2.2 martin if (LCTF_TYPE_ISCHILD (fp, tp->ctt_type) == child
877 1.1.1.1.2.2 martin && LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax)
878 1.1.1.1.2.2 martin fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = id;
879 1.1.1.1.2.2 martin /*FALLTHRU*/
880 1.1.1.1.2.2 martin
881 1.1.1.1.2.2 martin case CTF_K_VOLATILE:
882 1.1.1.1.2.2 martin case CTF_K_CONST:
883 1.1.1.1.2.2 martin case CTF_K_RESTRICT:
884 1.1.1.1.2.2 martin err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
885 1.1.1.1.2.2 martin LCTF_INDEX_TO_TYPE (fp, id, child),
886 1.1.1.1.2.2 martin tp->ctt_name);
887 1.1.1.1.2.2 martin if (err != 0)
888 1.1.1.1.2.2 martin return err;
889 1.1.1.1.2.2 martin break;
890 1.1.1.1.2.2 martin default:
891 1.1.1.1.2.2 martin ctf_dprintf ("unhandled CTF kind in endianness conversion -- %x\n",
892 1.1.1.1.2.2 martin kind);
893 1.1.1.1.2.2 martin return ECTF_CORRUPT;
894 1.1.1.1.2.2 martin }
895 1.1.1.1.2.2 martin
896 1.1.1.1.2.2 martin *xp = (uint32_t) ((uintptr_t) tp - (uintptr_t) fp->ctf_buf);
897 1.1.1.1.2.2 martin tp = (ctf_type_t *) ((uintptr_t) tp + increment + vbytes);
898 1.1.1.1.2.2 martin }
899 1.1.1.1.2.2 martin
900 1.1.1.1.2.2 martin ctf_dprintf ("%lu total types processed\n", fp->ctf_typemax);
901 1.1.1.1.2.2 martin ctf_dprintf ("%u enum names hashed\n",
902 1.1.1.1.2.2 martin ctf_hash_size (fp->ctf_enums.ctn_readonly));
903 1.1.1.1.2.2 martin ctf_dprintf ("%u struct names hashed (%d long)\n",
904 1.1.1.1.2.2 martin ctf_hash_size (fp->ctf_structs.ctn_readonly), nlstructs);
905 1.1.1.1.2.2 martin ctf_dprintf ("%u union names hashed (%d long)\n",
906 1.1.1.1.2.2 martin ctf_hash_size (fp->ctf_unions.ctn_readonly), nlunions);
907 1.1.1.1.2.2 martin ctf_dprintf ("%u base type names hashed\n",
908 1.1.1.1.2.2 martin ctf_hash_size (fp->ctf_names.ctn_readonly));
909 1.1.1.1.2.2 martin
910 1.1.1.1.2.2 martin /* Make an additional pass through the pointer table to find pointers that
911 1.1.1.1.2.2 martin point to anonymous typedef nodes. If we find one, modify the pointer table
912 1.1.1.1.2.2 martin so that the pointer is also known to point to the node that is referenced
913 1.1.1.1.2.2 martin by the anonymous typedef node. */
914 1.1.1.1.2.2 martin
915 1.1.1.1.2.2 martin for (id = 1; id <= fp->ctf_typemax; id++)
916 1.1.1.1.2.2 martin {
917 1.1.1.1.2.2 martin if ((dst = fp->ctf_ptrtab[id]) != 0)
918 1.1.1.1.2.2 martin {
919 1.1.1.1.2.2 martin tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
920 1.1.1.1.2.2 martin
921 1.1.1.1.2.2 martin if (LCTF_INFO_KIND (fp, tp->ctt_info) == CTF_K_TYPEDEF
922 1.1.1.1.2.2 martin && strcmp (ctf_strptr (fp, tp->ctt_name), "") == 0
923 1.1.1.1.2.2 martin && LCTF_TYPE_ISCHILD (fp, tp->ctt_type) == child
924 1.1.1.1.2.2 martin && LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax)
925 1.1.1.1.2.2 martin fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = dst;
926 1.1.1.1.2.2 martin }
927 1.1.1.1.2.2 martin }
928 1.1.1.1.2.2 martin
929 1.1.1.1.2.2 martin return 0;
930 1.1.1.1.2.2 martin }
931 1.1.1.1.2.2 martin
932 1.1.1.1.2.2 martin /* Endianness-flipping routines.
933 1.1.1.1.2.2 martin
934 1.1.1.1.2.2 martin We flip everything, mindlessly, even 1-byte entities, so that future
935 1.1.1.1.2.2 martin expansions do not require changes to this code. */
936 1.1.1.1.2.2 martin
937 1.1.1.1.2.2 martin /* < C11? define away static assertions. */
938 1.1.1.1.2.2 martin
939 1.1.1.1.2.2 martin #if !defined (__STDC_VERSION__) || __STDC_VERSION__ < 201112L
940 1.1.1.1.2.2 martin #define _Static_assert(cond, err)
941 1.1.1.1.2.2 martin #endif
942 1.1.1.1.2.2 martin
943 1.1.1.1.2.2 martin /* Swap the endianness of something. */
944 1.1.1.1.2.2 martin
945 1.1.1.1.2.2 martin #define swap_thing(x) \
946 1.1.1.1.2.2 martin do { \
947 1.1.1.1.2.2 martin _Static_assert (sizeof (x) == 1 || (sizeof (x) % 2 == 0 \
948 1.1.1.1.2.2 martin && sizeof (x) <= 8), \
949 1.1.1.1.2.2 martin "Invalid size, update endianness code"); \
950 1.1.1.1.2.2 martin switch (sizeof (x)) { \
951 1.1.1.1.2.2 martin case 2: x = bswap_16 (x); break; \
952 1.1.1.1.2.2 martin case 4: x = bswap_32 (x); break; \
953 1.1.1.1.2.2 martin case 8: x = bswap_64 (x); break; \
954 1.1.1.1.2.2 martin case 1: /* Nothing needs doing */ \
955 1.1.1.1.2.2 martin break; \
956 1.1.1.1.2.2 martin } \
957 1.1.1.1.2.2 martin } while (0);
958 1.1.1.1.2.2 martin
959 1.1.1.1.2.2 martin /* Flip the endianness of the CTF header. */
960 1.1.1.1.2.2 martin
961 1.1.1.1.2.2 martin static void
962 1.1.1.1.2.2 martin flip_header (ctf_header_t *cth)
963 1.1.1.1.2.2 martin {
964 1.1.1.1.2.2 martin swap_thing (cth->cth_preamble.ctp_magic);
965 1.1.1.1.2.2 martin swap_thing (cth->cth_preamble.ctp_version);
966 1.1.1.1.2.2 martin swap_thing (cth->cth_preamble.ctp_flags);
967 1.1.1.1.2.2 martin swap_thing (cth->cth_parlabel);
968 1.1.1.1.2.2 martin swap_thing (cth->cth_parname);
969 1.1.1.1.2.2 martin swap_thing (cth->cth_cuname);
970 1.1.1.1.2.2 martin swap_thing (cth->cth_objtoff);
971 1.1.1.1.2.2 martin swap_thing (cth->cth_funcoff);
972 1.1.1.1.2.2 martin swap_thing (cth->cth_objtidxoff);
973 1.1.1.1.2.2 martin swap_thing (cth->cth_funcidxoff);
974 1.1.1.1.2.2 martin swap_thing (cth->cth_varoff);
975 1.1.1.1.2.2 martin swap_thing (cth->cth_typeoff);
976 1.1.1.1.2.2 martin swap_thing (cth->cth_stroff);
977 1.1.1.1.2.2 martin swap_thing (cth->cth_strlen);
978 1.1.1.1.2.2 martin }
979 1.1.1.1.2.2 martin
980 1.1.1.1.2.2 martin /* Flip the endianness of the label section, an array of ctf_lblent_t. */
981 1.1.1.1.2.2 martin
982 1.1.1.1.2.2 martin static void
983 1.1.1.1.2.2 martin flip_lbls (void *start, size_t len)
984 1.1.1.1.2.2 martin {
985 1.1.1.1.2.2 martin ctf_lblent_t *lbl = start;
986 1.1.1.1.2.2 martin ssize_t i;
987 1.1.1.1.2.2 martin
988 1.1.1.1.2.2 martin for (i = len / sizeof (struct ctf_lblent); i > 0; lbl++, i--)
989 1.1.1.1.2.2 martin {
990 1.1.1.1.2.2 martin swap_thing (lbl->ctl_label);
991 1.1.1.1.2.2 martin swap_thing (lbl->ctl_type);
992 1.1.1.1.2.2 martin }
993 1.1.1.1.2.2 martin }
994 1.1.1.1.2.2 martin
995 1.1.1.1.2.2 martin /* Flip the endianness of the data-object or function sections or their indexes,
996 1.1.1.1.2.2 martin all arrays of uint32_t. (The function section has more internal structure,
997 1.1.1.1.2.2 martin but that structure is an array of uint32_t, so can be treated as one big
998 1.1.1.1.2.2 martin array for byte-swapping.) */
999 1.1.1.1.2.2 martin
1000 1.1.1.1.2.2 martin static void
1001 1.1.1.1.2.2 martin flip_objts (void *start, size_t len)
1002 1.1.1.1.2.2 martin {
1003 1.1.1.1.2.2 martin uint32_t *obj = start;
1004 1.1.1.1.2.2 martin ssize_t i;
1005 1.1.1.1.2.2 martin
1006 1.1.1.1.2.2 martin for (i = len / sizeof (uint32_t); i > 0; obj++, i--)
1007 1.1.1.1.2.2 martin swap_thing (*obj);
1008 1.1.1.1.2.2 martin }
1009 1.1.1.1.2.2 martin
1010 1.1.1.1.2.2 martin /* Flip the endianness of the variable section, an array of ctf_varent_t. */
1011 1.1.1.1.2.2 martin
1012 1.1.1.1.2.2 martin static void
1013 1.1.1.1.2.2 martin flip_vars (void *start, size_t len)
1014 1.1.1.1.2.2 martin {
1015 1.1.1.1.2.2 martin ctf_varent_t *var = start;
1016 1.1.1.1.2.2 martin ssize_t i;
1017 1.1.1.1.2.2 martin
1018 1.1.1.1.2.2 martin for (i = len / sizeof (struct ctf_varent); i > 0; var++, i--)
1019 1.1.1.1.2.2 martin {
1020 1.1.1.1.2.2 martin swap_thing (var->ctv_name);
1021 1.1.1.1.2.2 martin swap_thing (var->ctv_type);
1022 1.1.1.1.2.2 martin }
1023 1.1.1.1.2.2 martin }
1024 1.1.1.1.2.2 martin
1025 1.1.1.1.2.2 martin /* Flip the endianness of the type section, a tagged array of ctf_type or
1026 1.1.1.1.2.2 martin ctf_stype followed by variable data. */
1027 1.1.1.1.2.2 martin
1028 1.1.1.1.2.2 martin static int
1029 1.1.1.1.2.2 martin flip_types (void *start, size_t len)
1030 1.1.1.1.2.2 martin {
1031 1.1.1.1.2.2 martin ctf_type_t *t = start;
1032 1.1.1.1.2.2 martin
1033 1.1.1.1.2.2 martin while ((uintptr_t) t < ((uintptr_t) start) + len)
1034 1.1.1.1.2.2 martin {
1035 1.1.1.1.2.2 martin swap_thing (t->ctt_name);
1036 1.1.1.1.2.2 martin swap_thing (t->ctt_info);
1037 1.1.1.1.2.2 martin swap_thing (t->ctt_size);
1038 1.1.1.1.2.2 martin
1039 1.1.1.1.2.2 martin uint32_t kind = CTF_V2_INFO_KIND (t->ctt_info);
1040 1.1.1.1.2.2 martin size_t size = t->ctt_size;
1041 1.1.1.1.2.2 martin uint32_t vlen = CTF_V2_INFO_VLEN (t->ctt_info);
1042 1.1.1.1.2.2 martin size_t vbytes = get_vbytes_v2 (kind, size, vlen);
1043 1.1.1.1.2.2 martin
1044 1.1.1.1.2.2 martin if (_libctf_unlikely_ (size == CTF_LSIZE_SENT))
1045 1.1.1.1.2.2 martin {
1046 1.1.1.1.2.2 martin swap_thing (t->ctt_lsizehi);
1047 1.1.1.1.2.2 martin swap_thing (t->ctt_lsizelo);
1048 1.1.1.1.2.2 martin size = CTF_TYPE_LSIZE (t);
1049 1.1.1.1.2.2 martin t = (ctf_type_t *) ((uintptr_t) t + sizeof (ctf_type_t));
1050 1.1.1.1.2.2 martin }
1051 1.1.1.1.2.2 martin else
1052 1.1.1.1.2.2 martin t = (ctf_type_t *) ((uintptr_t) t + sizeof (ctf_stype_t));
1053 1.1.1.1.2.2 martin
1054 1.1.1.1.2.2 martin switch (kind)
1055 1.1.1.1.2.2 martin {
1056 1.1.1.1.2.2 martin case CTF_K_FORWARD:
1057 1.1.1.1.2.2 martin case CTF_K_UNKNOWN:
1058 1.1.1.1.2.2 martin case CTF_K_POINTER:
1059 1.1.1.1.2.2 martin case CTF_K_TYPEDEF:
1060 1.1.1.1.2.2 martin case CTF_K_VOLATILE:
1061 1.1.1.1.2.2 martin case CTF_K_CONST:
1062 1.1.1.1.2.2 martin case CTF_K_RESTRICT:
1063 1.1.1.1.2.2 martin /* These types have no vlen data to swap. */
1064 1.1.1.1.2.2 martin assert (vbytes == 0);
1065 1.1.1.1.2.2 martin break;
1066 1.1.1.1.2.2 martin
1067 1.1.1.1.2.2 martin case CTF_K_INTEGER:
1068 1.1.1.1.2.2 martin case CTF_K_FLOAT:
1069 1.1.1.1.2.2 martin {
1070 1.1.1.1.2.2 martin /* These types have a single uint32_t. */
1071 1.1.1.1.2.2 martin
1072 1.1.1.1.2.2 martin uint32_t *item = (uint32_t *) t;
1073 1.1.1.1.2.2 martin
1074 1.1.1.1.2.2 martin swap_thing (*item);
1075 1.1.1.1.2.2 martin break;
1076 1.1.1.1.2.2 martin }
1077 1.1.1.1.2.2 martin
1078 1.1.1.1.2.2 martin case CTF_K_FUNCTION:
1079 1.1.1.1.2.2 martin {
1080 1.1.1.1.2.2 martin /* This type has a bunch of uint32_ts. */
1081 1.1.1.1.2.2 martin
1082 1.1.1.1.2.2 martin uint32_t *item = (uint32_t *) t;
1083 1.1.1.1.2.2 martin ssize_t i;
1084 1.1.1.1.2.2 martin
1085 1.1.1.1.2.2 martin for (i = vlen; i > 0; item++, i--)
1086 1.1.1.1.2.2 martin swap_thing (*item);
1087 1.1.1.1.2.2 martin break;
1088 1.1.1.1.2.2 martin }
1089 1.1.1.1.2.2 martin
1090 1.1.1.1.2.2 martin case CTF_K_ARRAY:
1091 1.1.1.1.2.2 martin {
1092 1.1.1.1.2.2 martin /* This has a single ctf_array_t. */
1093 1.1.1.1.2.2 martin
1094 1.1.1.1.2.2 martin ctf_array_t *a = (ctf_array_t *) t;
1095 1.1.1.1.2.2 martin
1096 1.1.1.1.2.2 martin assert (vbytes == sizeof (ctf_array_t));
1097 1.1.1.1.2.2 martin swap_thing (a->cta_contents);
1098 1.1.1.1.2.2 martin swap_thing (a->cta_index);
1099 1.1.1.1.2.2 martin swap_thing (a->cta_nelems);
1100 1.1.1.1.2.2 martin
1101 1.1.1.1.2.2 martin break;
1102 1.1.1.1.2.2 martin }
1103 1.1.1.1.2.2 martin
1104 1.1.1.1.2.2 martin case CTF_K_SLICE:
1105 1.1.1.1.2.2 martin {
1106 1.1.1.1.2.2 martin /* This has a single ctf_slice_t. */
1107 1.1.1.1.2.2 martin
1108 1.1.1.1.2.2 martin ctf_slice_t *s = (ctf_slice_t *) t;
1109 1.1.1.1.2.2 martin
1110 1.1.1.1.2.2 martin assert (vbytes == sizeof (ctf_slice_t));
1111 1.1.1.1.2.2 martin swap_thing (s->cts_type);
1112 1.1.1.1.2.2 martin swap_thing (s->cts_offset);
1113 1.1.1.1.2.2 martin swap_thing (s->cts_bits);
1114 1.1.1.1.2.2 martin
1115 1.1.1.1.2.2 martin break;
1116 1.1.1.1.2.2 martin }
1117 1.1.1.1.2.2 martin
1118 1.1.1.1.2.2 martin case CTF_K_STRUCT:
1119 1.1.1.1.2.2 martin case CTF_K_UNION:
1120 1.1.1.1.2.2 martin {
1121 1.1.1.1.2.2 martin /* This has an array of ctf_member or ctf_lmember, depending on
1122 1.1.1.1.2.2 martin size. We could consider it to be a simple array of uint32_t,
1123 1.1.1.1.2.2 martin but for safety's sake in case these structures ever acquire
1124 1.1.1.1.2.2 martin non-uint32_t members, do it member by member. */
1125 1.1.1.1.2.2 martin
1126 1.1.1.1.2.2 martin if (_libctf_unlikely_ (size >= CTF_LSTRUCT_THRESH))
1127 1.1.1.1.2.2 martin {
1128 1.1.1.1.2.2 martin ctf_lmember_t *lm = (ctf_lmember_t *) t;
1129 1.1.1.1.2.2 martin ssize_t i;
1130 1.1.1.1.2.2 martin for (i = vlen; i > 0; i--, lm++)
1131 1.1.1.1.2.2 martin {
1132 1.1.1.1.2.2 martin swap_thing (lm->ctlm_name);
1133 1.1.1.1.2.2 martin swap_thing (lm->ctlm_offsethi);
1134 1.1.1.1.2.2 martin swap_thing (lm->ctlm_type);
1135 1.1.1.1.2.2 martin swap_thing (lm->ctlm_offsetlo);
1136 1.1.1.1.2.2 martin }
1137 1.1.1.1.2.2 martin }
1138 1.1.1.1.2.2 martin else
1139 1.1.1.1.2.2 martin {
1140 1.1.1.1.2.2 martin ctf_member_t *m = (ctf_member_t *) t;
1141 1.1.1.1.2.2 martin ssize_t i;
1142 1.1.1.1.2.2 martin for (i = vlen; i > 0; i--, m++)
1143 1.1.1.1.2.2 martin {
1144 1.1.1.1.2.2 martin swap_thing (m->ctm_name);
1145 1.1.1.1.2.2 martin swap_thing (m->ctm_offset);
1146 1.1.1.1.2.2 martin swap_thing (m->ctm_type);
1147 1.1.1.1.2.2 martin }
1148 1.1.1.1.2.2 martin }
1149 1.1.1.1.2.2 martin break;
1150 1.1.1.1.2.2 martin }
1151 1.1.1.1.2.2 martin
1152 1.1.1.1.2.2 martin case CTF_K_ENUM:
1153 1.1.1.1.2.2 martin {
1154 1.1.1.1.2.2 martin /* This has an array of ctf_enum_t. */
1155 1.1.1.1.2.2 martin
1156 1.1.1.1.2.2 martin ctf_enum_t *item = (ctf_enum_t *) t;
1157 1.1.1.1.2.2 martin ssize_t i;
1158 1.1.1.1.2.2 martin
1159 1.1.1.1.2.2 martin for (i = vlen; i > 0; item++, i--)
1160 1.1.1.1.2.2 martin {
1161 1.1.1.1.2.2 martin swap_thing (item->cte_name);
1162 1.1.1.1.2.2 martin swap_thing (item->cte_value);
1163 1.1.1.1.2.2 martin }
1164 1.1.1.1.2.2 martin break;
1165 1.1.1.1.2.2 martin }
1166 1.1.1.1.2.2 martin default:
1167 1.1.1.1.2.2 martin ctf_dprintf ("unhandled CTF kind in endianness conversion -- %x\n",
1168 1.1.1.1.2.2 martin kind);
1169 1.1.1.1.2.2 martin return ECTF_CORRUPT;
1170 1.1.1.1.2.2 martin }
1171 1.1.1.1.2.2 martin
1172 1.1.1.1.2.2 martin t = (ctf_type_t *) ((uintptr_t) t + vbytes);
1173 1.1.1.1.2.2 martin }
1174 1.1.1.1.2.2 martin
1175 1.1.1.1.2.2 martin return 0;
1176 1.1.1.1.2.2 martin }
1177 1.1.1.1.2.2 martin
1178 1.1.1.1.2.2 martin /* Flip the endianness of BUF, given the offsets in the (already endian-
1179 1.1.1.1.2.2 martin converted) CTH.
1180 1.1.1.1.2.2 martin
1181 1.1.1.1.2.2 martin All of this stuff happens before the header is fully initialized, so the
1182 1.1.1.1.2.2 martin LCTF_*() macros cannot be used yet. Since we do not try to endian-convert v1
1183 1.1.1.1.2.2 martin data, this is no real loss. */
1184 1.1.1.1.2.2 martin
1185 1.1.1.1.2.2 martin static int
1186 1.1.1.1.2.2 martin flip_ctf (ctf_header_t *cth, unsigned char *buf)
1187 1.1.1.1.2.2 martin {
1188 1.1.1.1.2.2 martin flip_lbls (buf + cth->cth_lbloff, cth->cth_objtoff - cth->cth_lbloff);
1189 1.1.1.1.2.2 martin flip_objts (buf + cth->cth_objtoff, cth->cth_funcoff - cth->cth_objtoff);
1190 1.1.1.1.2.2 martin flip_objts (buf + cth->cth_funcoff, cth->cth_objtidxoff - cth->cth_funcoff);
1191 1.1.1.1.2.2 martin flip_objts (buf + cth->cth_objtidxoff, cth->cth_funcidxoff - cth->cth_objtidxoff);
1192 1.1.1.1.2.2 martin flip_objts (buf + cth->cth_funcidxoff, cth->cth_varoff - cth->cth_funcidxoff);
1193 1.1.1.1.2.2 martin flip_vars (buf + cth->cth_varoff, cth->cth_typeoff - cth->cth_varoff);
1194 1.1.1.1.2.2 martin return flip_types (buf + cth->cth_typeoff, cth->cth_stroff - cth->cth_typeoff);
1195 1.1.1.1.2.2 martin }
1196 1.1.1.1.2.2 martin
1197 1.1.1.1.2.2 martin /* Set up the ctl hashes in a ctf_file_t. Called by both writable and
1198 1.1.1.1.2.2 martin non-writable dictionary initialization. */
1199 1.1.1.1.2.2 martin void ctf_set_ctl_hashes (ctf_file_t *fp)
1200 1.1.1.1.2.2 martin {
1201 1.1.1.1.2.2 martin /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
1202 1.1.1.1.2.2 martin array of type name prefixes and the corresponding ctf_hash to use. */
1203 1.1.1.1.2.2 martin fp->ctf_lookups[0].ctl_prefix = "struct";
1204 1.1.1.1.2.2 martin fp->ctf_lookups[0].ctl_len = strlen (fp->ctf_lookups[0].ctl_prefix);
1205 1.1.1.1.2.2 martin fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
1206 1.1.1.1.2.2 martin fp->ctf_lookups[1].ctl_prefix = "union";
1207 1.1.1.1.2.2 martin fp->ctf_lookups[1].ctl_len = strlen (fp->ctf_lookups[1].ctl_prefix);
1208 1.1.1.1.2.2 martin fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
1209 1.1.1.1.2.2 martin fp->ctf_lookups[2].ctl_prefix = "enum";
1210 1.1.1.1.2.2 martin fp->ctf_lookups[2].ctl_len = strlen (fp->ctf_lookups[2].ctl_prefix);
1211 1.1.1.1.2.2 martin fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
1212 1.1.1.1.2.2 martin fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;
1213 1.1.1.1.2.2 martin fp->ctf_lookups[3].ctl_len = strlen (fp->ctf_lookups[3].ctl_prefix);
1214 1.1.1.1.2.2 martin fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
1215 1.1.1.1.2.2 martin fp->ctf_lookups[4].ctl_prefix = NULL;
1216 1.1.1.1.2.2 martin fp->ctf_lookups[4].ctl_len = 0;
1217 1.1.1.1.2.2 martin fp->ctf_lookups[4].ctl_hash = NULL;
1218 1.1.1.1.2.2 martin }
1219 1.1.1.1.2.2 martin
1220 1.1.1.1.2.2 martin /* Open a CTF file, mocking up a suitable ctf_sect. */
1221 1.1.1.1.2.2 martin
1222 1.1.1.1.2.2 martin ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
1223 1.1.1.1.2.2 martin const char *symsect, size_t symsect_size,
1224 1.1.1.1.2.2 martin size_t symsect_entsize,
1225 1.1.1.1.2.2 martin const char *strsect, size_t strsect_size,
1226 1.1.1.1.2.2 martin int *errp)
1227 1.1.1.1.2.2 martin {
1228 1.1.1.1.2.2 martin return ctf_simple_open_internal (ctfsect, ctfsect_size, symsect, symsect_size,
1229 1.1.1.1.2.2 martin symsect_entsize, strsect, strsect_size, NULL,
1230 1.1.1.1.2.2 martin 0, errp);
1231 1.1.1.1.2.2 martin }
1232 1.1.1.1.2.2 martin
1233 1.1.1.1.2.2 martin /* Open a CTF file, mocking up a suitable ctf_sect and overriding the external
1234 1.1.1.1.2.2 martin strtab with a synthetic one. */
1235 1.1.1.1.2.2 martin
1236 1.1.1.1.2.2 martin ctf_file_t *ctf_simple_open_internal (const char *ctfsect, size_t ctfsect_size,
1237 1.1.1.1.2.2 martin const char *symsect, size_t symsect_size,
1238 1.1.1.1.2.2 martin size_t symsect_entsize,
1239 1.1.1.1.2.2 martin const char *strsect, size_t strsect_size,
1240 1.1.1.1.2.2 martin ctf_dynhash_t *syn_strtab, int writable,
1241 1.1.1.1.2.2 martin int *errp)
1242 1.1.1.1.2.2 martin {
1243 1.1.1.1.2.2 martin ctf_sect_t skeleton;
1244 1.1.1.1.2.2 martin
1245 1.1.1.1.2.2 martin ctf_sect_t ctf_sect, sym_sect, str_sect;
1246 1.1.1.1.2.2 martin ctf_sect_t *ctfsectp = NULL;
1247 1.1.1.1.2.2 martin ctf_sect_t *symsectp = NULL;
1248 1.1.1.1.2.2 martin ctf_sect_t *strsectp = NULL;
1249 1.1.1.1.2.2 martin
1250 1.1.1.1.2.2 martin skeleton.cts_name = _CTF_SECTION;
1251 1.1.1.1.2.2 martin skeleton.cts_entsize = 1;
1252 1.1.1.1.2.2 martin
1253 1.1.1.1.2.2 martin if (ctfsect)
1254 1.1.1.1.2.2 martin {
1255 1.1.1.1.2.2 martin memcpy (&ctf_sect, &skeleton, sizeof (struct ctf_sect));
1256 1.1.1.1.2.2 martin ctf_sect.cts_data = ctfsect;
1257 1.1.1.1.2.2 martin ctf_sect.cts_size = ctfsect_size;
1258 1.1.1.1.2.2 martin ctfsectp = &ctf_sect;
1259 1.1.1.1.2.2 martin }
1260 1.1.1.1.2.2 martin
1261 1.1.1.1.2.2 martin if (symsect)
1262 1.1.1.1.2.2 martin {
1263 1.1.1.1.2.2 martin memcpy (&sym_sect, &skeleton, sizeof (struct ctf_sect));
1264 1.1.1.1.2.2 martin sym_sect.cts_data = symsect;
1265 1.1.1.1.2.2 martin sym_sect.cts_size = symsect_size;
1266 1.1.1.1.2.2 martin sym_sect.cts_entsize = symsect_entsize;
1267 1.1.1.1.2.2 martin symsectp = &sym_sect;
1268 1.1.1.1.2.2 martin }
1269 1.1.1.1.2.2 martin
1270 1.1.1.1.2.2 martin if (strsect)
1271 1.1.1.1.2.2 martin {
1272 1.1.1.1.2.2 martin memcpy (&str_sect, &skeleton, sizeof (struct ctf_sect));
1273 1.1.1.1.2.2 martin str_sect.cts_data = strsect;
1274 1.1.1.1.2.2 martin str_sect.cts_size = strsect_size;
1275 1.1.1.1.2.2 martin strsectp = &str_sect;
1276 1.1.1.1.2.2 martin }
1277 1.1.1.1.2.2 martin
1278 1.1.1.1.2.2 martin return ctf_bufopen_internal (ctfsectp, symsectp, strsectp, syn_strtab,
1279 1.1.1.1.2.2 martin writable, errp);
1280 1.1.1.1.2.2 martin }
1281 1.1.1.1.2.2 martin
1282 1.1.1.1.2.2 martin /* Decode the specified CTF buffer and optional symbol table, and create a new
1283 1.1.1.1.2.2 martin CTF container representing the symbolic debugging information. This code can
1284 1.1.1.1.2.2 martin be used directly by the debugger, or it can be used as the engine for
1285 1.1.1.1.2.2 martin ctf_fdopen() or ctf_open(), below. */
1286 1.1.1.1.2.2 martin
1287 1.1.1.1.2.2 martin ctf_file_t *
1288 1.1.1.1.2.2 martin ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
1289 1.1.1.1.2.2 martin const ctf_sect_t *strsect, int *errp)
1290 1.1.1.1.2.2 martin {
1291 1.1.1.1.2.2 martin return ctf_bufopen_internal (ctfsect, symsect, strsect, NULL, 0, errp);
1292 1.1.1.1.2.2 martin }
1293 1.1.1.1.2.2 martin
1294 1.1.1.1.2.2 martin /* Like ctf_bufopen, but overriding the external strtab with a synthetic one. */
1295 1.1.1.1.2.2 martin
1296 1.1.1.1.2.2 martin ctf_file_t *
1297 1.1.1.1.2.2 martin ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
1298 1.1.1.1.2.2 martin const ctf_sect_t *strsect, ctf_dynhash_t *syn_strtab,
1299 1.1.1.1.2.2 martin int writable, int *errp)
1300 1.1.1.1.2.2 martin {
1301 1.1.1.1.2.2 martin const ctf_preamble_t *pp;
1302 1.1.1.1.2.2 martin size_t hdrsz = sizeof (ctf_header_t);
1303 1.1.1.1.2.2 martin ctf_header_t *hp;
1304 1.1.1.1.2.2 martin ctf_file_t *fp;
1305 1.1.1.1.2.2 martin int foreign_endian = 0;
1306 1.1.1.1.2.2 martin int err;
1307 1.1.1.1.2.2 martin
1308 1.1.1.1.2.2 martin libctf_init_debug();
1309 1.1.1.1.2.2 martin
1310 1.1.1.1.2.2 martin if ((ctfsect == NULL) || ((symsect != NULL) &&
1311 1.1.1.1.2.2 martin ((strsect == NULL) && syn_strtab == NULL)))
1312 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, EINVAL));
1313 1.1.1.1.2.2 martin
1314 1.1.1.1.2.2 martin if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&
1315 1.1.1.1.2.2 martin symsect->cts_entsize != sizeof (Elf64_Sym))
1316 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_SYMTAB));
1317 1.1.1.1.2.2 martin
1318 1.1.1.1.2.2 martin if (symsect != NULL && symsect->cts_data == NULL)
1319 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_SYMBAD));
1320 1.1.1.1.2.2 martin
1321 1.1.1.1.2.2 martin if (strsect != NULL && strsect->cts_data == NULL)
1322 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_STRBAD));
1323 1.1.1.1.2.2 martin
1324 1.1.1.1.2.2 martin if (ctfsect->cts_size < sizeof (ctf_preamble_t))
1325 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));
1326 1.1.1.1.2.2 martin
1327 1.1.1.1.2.2 martin pp = (const ctf_preamble_t *) ctfsect->cts_data;
1328 1.1.1.1.2.2 martin
1329 1.1.1.1.2.2 martin ctf_dprintf ("ctf_bufopen: magic=0x%x version=%u\n",
1330 1.1.1.1.2.2 martin pp->ctp_magic, pp->ctp_version);
1331 1.1.1.1.2.2 martin
1332 1.1.1.1.2.2 martin /* Validate each part of the CTF header.
1333 1.1.1.1.2.2 martin
1334 1.1.1.1.2.2 martin First, we validate the preamble (common to all versions). At that point,
1335 1.1.1.1.2.2 martin we know the endianness and specific header version, and can validate the
1336 1.1.1.1.2.2 martin version-specific parts including section offsets and alignments.
1337 1.1.1.1.2.2 martin
1338 1.1.1.1.2.2 martin We specifically do not support foreign-endian old versions. */
1339 1.1.1.1.2.2 martin
1340 1.1.1.1.2.2 martin if (_libctf_unlikely_ (pp->ctp_magic != CTF_MAGIC))
1341 1.1.1.1.2.2 martin {
1342 1.1.1.1.2.2 martin if (pp->ctp_magic == bswap_16 (CTF_MAGIC))
1343 1.1.1.1.2.2 martin {
1344 1.1.1.1.2.2 martin if (pp->ctp_version != CTF_VERSION_3)
1345 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_CTFVERS));
1346 1.1.1.1.2.2 martin foreign_endian = 1;
1347 1.1.1.1.2.2 martin }
1348 1.1.1.1.2.2 martin else
1349 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));
1350 1.1.1.1.2.2 martin }
1351 1.1.1.1.2.2 martin
1352 1.1.1.1.2.2 martin if (_libctf_unlikely_ ((pp->ctp_version < CTF_VERSION_1)
1353 1.1.1.1.2.2 martin || (pp->ctp_version > CTF_VERSION_3)))
1354 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_CTFVERS));
1355 1.1.1.1.2.2 martin
1356 1.1.1.1.2.2 martin if ((symsect != NULL) && (pp->ctp_version < CTF_VERSION_2))
1357 1.1.1.1.2.2 martin {
1358 1.1.1.1.2.2 martin /* The symtab can contain function entries which contain embedded ctf
1359 1.1.1.1.2.2 martin info. We do not support dynamically upgrading such entries (none
1360 1.1.1.1.2.2 martin should exist in any case, since dwarf2ctf does not create them). */
1361 1.1.1.1.2.2 martin
1362 1.1.1.1.2.2 martin ctf_dprintf ("ctf_bufopen: CTF version %d symsect not "
1363 1.1.1.1.2.2 martin "supported\n", pp->ctp_version);
1364 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_NOTSUP));
1365 1.1.1.1.2.2 martin }
1366 1.1.1.1.2.2 martin
1367 1.1.1.1.2.2 martin if (pp->ctp_version < CTF_VERSION_3)
1368 1.1.1.1.2.2 martin hdrsz = sizeof (ctf_header_v2_t);
1369 1.1.1.1.2.2 martin
1370 1.1.1.1.2.2 martin if (ctfsect->cts_size < hdrsz)
1371 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));
1372 1.1.1.1.2.2 martin
1373 1.1.1.1.2.2 martin if ((fp = malloc (sizeof (ctf_file_t))) == NULL)
1374 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ENOMEM));
1375 1.1.1.1.2.2 martin
1376 1.1.1.1.2.2 martin memset (fp, 0, sizeof (ctf_file_t));
1377 1.1.1.1.2.2 martin
1378 1.1.1.1.2.2 martin if (writable)
1379 1.1.1.1.2.2 martin fp->ctf_flags |= LCTF_RDWR;
1380 1.1.1.1.2.2 martin
1381 1.1.1.1.2.2 martin if ((fp->ctf_header = malloc (sizeof (struct ctf_header))) == NULL)
1382 1.1.1.1.2.2 martin {
1383 1.1.1.1.2.2 martin free (fp);
1384 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ENOMEM));
1385 1.1.1.1.2.2 martin }
1386 1.1.1.1.2.2 martin hp = fp->ctf_header;
1387 1.1.1.1.2.2 martin memcpy (hp, ctfsect->cts_data, hdrsz);
1388 1.1.1.1.2.2 martin if (pp->ctp_version < CTF_VERSION_3)
1389 1.1.1.1.2.2 martin upgrade_header (hp);
1390 1.1.1.1.2.2 martin
1391 1.1.1.1.2.2 martin if (foreign_endian)
1392 1.1.1.1.2.2 martin flip_header (hp);
1393 1.1.1.1.2.2 martin fp->ctf_openflags = hp->cth_flags;
1394 1.1.1.1.2.2 martin fp->ctf_size = hp->cth_stroff + hp->cth_strlen;
1395 1.1.1.1.2.2 martin
1396 1.1.1.1.2.2 martin ctf_dprintf ("ctf_bufopen: uncompressed size=%lu\n",
1397 1.1.1.1.2.2 martin (unsigned long) fp->ctf_size);
1398 1.1.1.1.2.2 martin
1399 1.1.1.1.2.2 martin if (hp->cth_lbloff > fp->ctf_size || hp->cth_objtoff > fp->ctf_size
1400 1.1.1.1.2.2 martin || hp->cth_funcoff > fp->ctf_size || hp->cth_objtidxoff > fp->ctf_size
1401 1.1.1.1.2.2 martin || hp->cth_funcidxoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
1402 1.1.1.1.2.2 martin || hp->cth_stroff > fp->ctf_size)
1403 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1404 1.1.1.1.2.2 martin
1405 1.1.1.1.2.2 martin if (hp->cth_lbloff > hp->cth_objtoff
1406 1.1.1.1.2.2 martin || hp->cth_objtoff > hp->cth_funcoff
1407 1.1.1.1.2.2 martin || hp->cth_funcoff > hp->cth_typeoff
1408 1.1.1.1.2.2 martin || hp->cth_funcoff > hp->cth_objtidxoff
1409 1.1.1.1.2.2 martin || hp->cth_objtidxoff > hp->cth_funcidxoff
1410 1.1.1.1.2.2 martin || hp->cth_funcidxoff > hp->cth_varoff
1411 1.1.1.1.2.2 martin || hp->cth_varoff > hp->cth_typeoff || hp->cth_typeoff > hp->cth_stroff)
1412 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1413 1.1.1.1.2.2 martin
1414 1.1.1.1.2.2 martin if ((hp->cth_lbloff & 3) || (hp->cth_objtoff & 2)
1415 1.1.1.1.2.2 martin || (hp->cth_funcoff & 2) || (hp->cth_objtidxoff & 2)
1416 1.1.1.1.2.2 martin || (hp->cth_funcidxoff & 2) || (hp->cth_varoff & 3)
1417 1.1.1.1.2.2 martin || (hp->cth_typeoff & 3))
1418 1.1.1.1.2.2 martin return (ctf_set_open_errno (errp, ECTF_CORRUPT));
1419 1.1.1.1.2.2 martin
1420 1.1.1.1.2.2 martin /* Once everything is determined to be valid, attempt to decompress the CTF
1421 1.1.1.1.2.2 martin data buffer if it is compressed, or copy it into new storage if it is not
1422 1.1.1.1.2.2 martin compressed but needs endian-flipping. Otherwise we just put the data
1423 1.1.1.1.2.2 martin section's buffer pointer into ctf_buf, below. */
1424 1.1.1.1.2.2 martin
1425 1.1.1.1.2.2 martin /* Note: if this is a v1 buffer, it will be reallocated and expanded by
1426 1.1.1.1.2.2 martin init_types(). */
1427 1.1.1.1.2.2 martin
1428 1.1.1.1.2.2 martin if (hp->cth_flags & CTF_F_COMPRESS)
1429 1.1.1.1.2.2 martin {
1430 1.1.1.1.2.2 martin size_t srclen;
1431 1.1.1.1.2.2 martin uLongf dstlen;
1432 1.1.1.1.2.2 martin const void *src;
1433 1.1.1.1.2.2 martin int rc = Z_OK;
1434 1.1.1.1.2.2 martin
1435 1.1.1.1.2.2 martin /* We are allocating this ourselves, so we can drop the ctf header
1436 1.1.1.1.2.2 martin copy in favour of ctf->ctf_header. */
1437 1.1.1.1.2.2 martin
1438 1.1.1.1.2.2 martin if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL)
1439 1.1.1.1.2.2 martin {
1440 1.1.1.1.2.2 martin err = ECTF_ZALLOC;
1441 1.1.1.1.2.2 martin goto bad;
1442 1.1.1.1.2.2 martin }
1443 1.1.1.1.2.2 martin fp->ctf_dynbase = fp->ctf_base;
1444 1.1.1.1.2.2 martin hp->cth_flags &= ~CTF_F_COMPRESS;
1445 1.1.1.1.2.2 martin
1446 1.1.1.1.2.2 martin src = (unsigned char *) ctfsect->cts_data + hdrsz;
1447 1.1.1.1.2.2 martin srclen = ctfsect->cts_size - hdrsz;
1448 1.1.1.1.2.2 martin dstlen = fp->ctf_size;
1449 1.1.1.1.2.2 martin fp->ctf_buf = fp->ctf_base;
1450 1.1.1.1.2.2 martin
1451 1.1.1.1.2.2 martin if ((rc = uncompress (fp->ctf_base, &dstlen, src, srclen)) != Z_OK)
1452 1.1.1.1.2.2 martin {
1453 1.1.1.1.2.2 martin ctf_dprintf ("zlib inflate err: %s\n", zError (rc));
1454 1.1.1.1.2.2 martin err = ECTF_DECOMPRESS;
1455 1.1.1.1.2.2 martin goto bad;
1456 1.1.1.1.2.2 martin }
1457 1.1.1.1.2.2 martin
1458 1.1.1.1.2.2 martin if ((size_t) dstlen != fp->ctf_size)
1459 1.1.1.1.2.2 martin {
1460 1.1.1.1.2.2 martin ctf_dprintf ("zlib inflate short -- got %lu of %lu "
1461 1.1.1.1.2.2 martin "bytes\n", (unsigned long) dstlen,
1462 1.1.1.1.2.2 martin (unsigned long) fp->ctf_size);
1463 1.1.1.1.2.2 martin err = ECTF_CORRUPT;
1464 1.1.1.1.2.2 martin goto bad;
1465 1.1.1.1.2.2 martin }
1466 1.1.1.1.2.2 martin }
1467 1.1.1.1.2.2 martin else if (foreign_endian)
1468 1.1.1.1.2.2 martin {
1469 1.1.1.1.2.2 martin if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL)
1470 1.1.1.1.2.2 martin {
1471 1.1.1.1.2.2 martin err = ECTF_ZALLOC;
1472 1.1.1.1.2.2 martin goto bad;
1473 1.1.1.1.2.2 martin }
1474 1.1.1.1.2.2 martin fp->ctf_dynbase = fp->ctf_base;
1475 1.1.1.1.2.2 martin memcpy (fp->ctf_base, ((unsigned char *) ctfsect->cts_data) + hdrsz,
1476 1.1.1.1.2.2 martin fp->ctf_size);
1477 1.1.1.1.2.2 martin fp->ctf_buf = fp->ctf_base;
1478 1.1.1.1.2.2 martin }
1479 1.1.1.1.2.2 martin else
1480 1.1.1.1.2.2 martin {
1481 1.1.1.1.2.2 martin /* We are just using the section passed in -- but its header may be an old
1482 1.1.1.1.2.2 martin version. Point ctf_buf past the old header, and never touch it
1483 1.1.1.1.2.2 martin again. */
1484 1.1.1.1.2.2 martin fp->ctf_base = (unsigned char *) ctfsect->cts_data;
1485 1.1.1.1.2.2 martin fp->ctf_dynbase = NULL;
1486 1.1.1.1.2.2 martin fp->ctf_buf = fp->ctf_base + hdrsz;
1487 1.1.1.1.2.2 martin }
1488 1.1.1.1.2.2 martin
1489 1.1.1.1.2.2 martin /* Once we have uncompressed and validated the CTF data buffer, we can
1490 1.1.1.1.2.2 martin proceed with initializing the ctf_file_t we allocated above.
1491 1.1.1.1.2.2 martin
1492 1.1.1.1.2.2 martin Nothing that depends on buf or base should be set directly in this function
1493 1.1.1.1.2.2 martin before the init_types() call, because it may be reallocated during
1494 1.1.1.1.2.2 martin transparent upgrade if this recension of libctf is so configured: see
1495 1.1.1.1.2.2 martin ctf_set_base(). */
1496 1.1.1.1.2.2 martin
1497 1.1.1.1.2.2 martin ctf_set_version (fp, hp, hp->cth_version);
1498 1.1.1.1.2.2 martin ctf_str_create_atoms (fp);
1499 1.1.1.1.2.2 martin fp->ctf_parmax = CTF_MAX_PTYPE;
1500 1.1.1.1.2.2 martin memcpy (&fp->ctf_data, ctfsect, sizeof (ctf_sect_t));
1501 1.1.1.1.2.2 martin
1502 1.1.1.1.2.2 martin if (symsect != NULL)
1503 1.1.1.1.2.2 martin {
1504 1.1.1.1.2.2 martin memcpy (&fp->ctf_symtab, symsect, sizeof (ctf_sect_t));
1505 1.1.1.1.2.2 martin memcpy (&fp->ctf_strtab, strsect, sizeof (ctf_sect_t));
1506 1.1.1.1.2.2 martin }
1507 1.1.1.1.2.2 martin
1508 1.1.1.1.2.2 martin if (fp->ctf_data.cts_name != NULL)
1509 1.1.1.1.2.2 martin if ((fp->ctf_data.cts_name = strdup (fp->ctf_data.cts_name)) == NULL)
1510 1.1.1.1.2.2 martin {
1511 1.1.1.1.2.2 martin err = ENOMEM;
1512 1.1.1.1.2.2 martin goto bad;
1513 1.1.1.1.2.2 martin }
1514 1.1.1.1.2.2 martin if (fp->ctf_symtab.cts_name != NULL)
1515 1.1.1.1.2.2 martin if ((fp->ctf_symtab.cts_name = strdup (fp->ctf_symtab.cts_name)) == NULL)
1516 1.1.1.1.2.2 martin {
1517 1.1.1.1.2.2 martin err = ENOMEM;
1518 1.1.1.1.2.2 martin goto bad;
1519 1.1.1.1.2.2 martin }
1520 1.1.1.1.2.2 martin if (fp->ctf_strtab.cts_name != NULL)
1521 1.1.1.1.2.2 martin if ((fp->ctf_strtab.cts_name = strdup (fp->ctf_strtab.cts_name)) == NULL)
1522 1.1.1.1.2.2 martin {
1523 1.1.1.1.2.2 martin err = ENOMEM;
1524 1.1.1.1.2.2 martin goto bad;
1525 1.1.1.1.2.2 martin }
1526 1.1.1.1.2.2 martin
1527 1.1.1.1.2.2 martin if (fp->ctf_data.cts_name == NULL)
1528 1.1.1.1.2.2 martin fp->ctf_data.cts_name = _CTF_NULLSTR;
1529 1.1.1.1.2.2 martin if (fp->ctf_symtab.cts_name == NULL)
1530 1.1.1.1.2.2 martin fp->ctf_symtab.cts_name = _CTF_NULLSTR;
1531 1.1.1.1.2.2 martin if (fp->ctf_strtab.cts_name == NULL)
1532 1.1.1.1.2.2 martin fp->ctf_strtab.cts_name = _CTF_NULLSTR;
1533 1.1.1.1.2.2 martin
1534 1.1.1.1.2.2 martin if (strsect != NULL)
1535 1.1.1.1.2.2 martin {
1536 1.1.1.1.2.2 martin fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;
1537 1.1.1.1.2.2 martin fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;
1538 1.1.1.1.2.2 martin }
1539 1.1.1.1.2.2 martin fp->ctf_syn_ext_strtab = syn_strtab;
1540 1.1.1.1.2.2 martin
1541 1.1.1.1.2.2 martin if (foreign_endian &&
1542 1.1.1.1.2.2 martin (err = flip_ctf (hp, fp->ctf_buf)) != 0)
1543 1.1.1.1.2.2 martin {
1544 1.1.1.1.2.2 martin /* We can be certain that flip_ctf() will have endian-flipped everything
1545 1.1.1.1.2.2 martin other than the types table when we return. In particular the header
1546 1.1.1.1.2.2 martin is fine, so set it, to allow freeing to use the usual code path. */
1547 1.1.1.1.2.2 martin
1548 1.1.1.1.2.2 martin ctf_set_base (fp, hp, fp->ctf_base);
1549 1.1.1.1.2.2 martin goto bad;
1550 1.1.1.1.2.2 martin }
1551 1.1.1.1.2.2 martin
1552 1.1.1.1.2.2 martin ctf_set_base (fp, hp, fp->ctf_base);
1553 1.1.1.1.2.2 martin
1554 1.1.1.1.2.2 martin /* No need to do anything else for dynamic containers: they do not support
1555 1.1.1.1.2.2 martin symbol lookups, and the type table is maintained in the dthashes. */
1556 1.1.1.1.2.2 martin if (fp->ctf_flags & LCTF_RDWR)
1557 1.1.1.1.2.2 martin {
1558 1.1.1.1.2.2 martin fp->ctf_refcnt = 1;
1559 1.1.1.1.2.2 martin return fp;
1560 1.1.1.1.2.2 martin }
1561 1.1.1.1.2.2 martin
1562 1.1.1.1.2.2 martin if ((err = init_types (fp, hp)) != 0)
1563 1.1.1.1.2.2 martin goto bad;
1564 1.1.1.1.2.2 martin
1565 1.1.1.1.2.2 martin /* If we have a symbol table section, allocate and initialize
1566 1.1.1.1.2.2 martin the symtab translation table, pointed to by ctf_sxlate. This table may be
1567 1.1.1.1.2.2 martin too large for the actual size of the object and function info sections: if
1568 1.1.1.1.2.2 martin so, ctf_nsyms will be adjusted and the excess will never be used. */
1569 1.1.1.1.2.2 martin
1570 1.1.1.1.2.2 martin if (symsect != NULL)
1571 1.1.1.1.2.2 martin {
1572 1.1.1.1.2.2 martin fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize;
1573 1.1.1.1.2.2 martin fp->ctf_sxlate = malloc (fp->ctf_nsyms * sizeof (uint32_t));
1574 1.1.1.1.2.2 martin
1575 1.1.1.1.2.2 martin if (fp->ctf_sxlate == NULL)
1576 1.1.1.1.2.2 martin {
1577 1.1.1.1.2.2 martin err = ENOMEM;
1578 1.1.1.1.2.2 martin goto bad;
1579 1.1.1.1.2.2 martin }
1580 1.1.1.1.2.2 martin
1581 1.1.1.1.2.2 martin if ((err = init_symtab (fp, hp, symsect, strsect)) != 0)
1582 1.1.1.1.2.2 martin goto bad;
1583 1.1.1.1.2.2 martin }
1584 1.1.1.1.2.2 martin
1585 1.1.1.1.2.2 martin ctf_set_ctl_hashes (fp);
1586 1.1.1.1.2.2 martin
1587 1.1.1.1.2.2 martin if (symsect != NULL)
1588 1.1.1.1.2.2 martin {
1589 1.1.1.1.2.2 martin if (symsect->cts_entsize == sizeof (Elf64_Sym))
1590 1.1.1.1.2.2 martin (void) ctf_setmodel (fp, CTF_MODEL_LP64);
1591 1.1.1.1.2.2 martin else
1592 1.1.1.1.2.2 martin (void) ctf_setmodel (fp, CTF_MODEL_ILP32);
1593 1.1.1.1.2.2 martin }
1594 1.1.1.1.2.2 martin else
1595 1.1.1.1.2.2 martin (void) ctf_setmodel (fp, CTF_MODEL_NATIVE);
1596 1.1.1.1.2.2 martin
1597 1.1.1.1.2.2 martin fp->ctf_refcnt = 1;
1598 1.1.1.1.2.2 martin return fp;
1599 1.1.1.1.2.2 martin
1600 1.1.1.1.2.2 martin bad:
1601 1.1.1.1.2.2 martin ctf_set_open_errno (errp, err);
1602 1.1.1.1.2.2 martin ctf_file_close (fp);
1603 1.1.1.1.2.2 martin return NULL;
1604 1.1.1.1.2.2 martin }
1605 1.1.1.1.2.2 martin
1606 1.1.1.1.2.2 martin /* Close the specified CTF container and free associated data structures. Note
1607 1.1.1.1.2.2 martin that ctf_file_close() is a reference counted operation: if the specified file
1608 1.1.1.1.2.2 martin is the parent of other active containers, its reference count will be greater
1609 1.1.1.1.2.2 martin than one and it will be freed later when no active children exist. */
1610 1.1.1.1.2.2 martin
1611 1.1.1.1.2.2 martin void
1612 1.1.1.1.2.2 martin ctf_file_close (ctf_file_t *fp)
1613 1.1.1.1.2.2 martin {
1614 1.1.1.1.2.2 martin ctf_dtdef_t *dtd, *ntd;
1615 1.1.1.1.2.2 martin ctf_dvdef_t *dvd, *nvd;
1616 1.1.1.1.2.2 martin
1617 1.1.1.1.2.2 martin if (fp == NULL)
1618 1.1.1.1.2.2 martin return; /* Allow ctf_file_close(NULL) to simplify caller code. */
1619 1.1.1.1.2.2 martin
1620 1.1.1.1.2.2 martin ctf_dprintf ("ctf_file_close(%p) refcnt=%u\n", (void *) fp, fp->ctf_refcnt);
1621 1.1.1.1.2.2 martin
1622 1.1.1.1.2.2 martin if (fp->ctf_refcnt > 1)
1623 1.1.1.1.2.2 martin {
1624 1.1.1.1.2.2 martin fp->ctf_refcnt--;
1625 1.1.1.1.2.2 martin return;
1626 1.1.1.1.2.2 martin }
1627 1.1.1.1.2.2 martin
1628 1.1.1.1.2.2 martin free (fp->ctf_dyncuname);
1629 1.1.1.1.2.2 martin free (fp->ctf_dynparname);
1630 1.1.1.1.2.2 martin ctf_file_close (fp->ctf_parent);
1631 1.1.1.1.2.2 martin
1632 1.1.1.1.2.2 martin for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
1633 1.1.1.1.2.2 martin {
1634 1.1.1.1.2.2 martin ntd = ctf_list_next (dtd);
1635 1.1.1.1.2.2 martin ctf_dtd_delete (fp, dtd);
1636 1.1.1.1.2.2 martin }
1637 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_dthash);
1638 1.1.1.1.2.2 martin if (fp->ctf_flags & LCTF_RDWR)
1639 1.1.1.1.2.2 martin {
1640 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_structs.ctn_writable);
1641 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_unions.ctn_writable);
1642 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_enums.ctn_writable);
1643 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_names.ctn_writable);
1644 1.1.1.1.2.2 martin }
1645 1.1.1.1.2.2 martin else
1646 1.1.1.1.2.2 martin {
1647 1.1.1.1.2.2 martin ctf_hash_destroy (fp->ctf_structs.ctn_readonly);
1648 1.1.1.1.2.2 martin ctf_hash_destroy (fp->ctf_unions.ctn_readonly);
1649 1.1.1.1.2.2 martin ctf_hash_destroy (fp->ctf_enums.ctn_readonly);
1650 1.1.1.1.2.2 martin ctf_hash_destroy (fp->ctf_names.ctn_readonly);
1651 1.1.1.1.2.2 martin }
1652 1.1.1.1.2.2 martin
1653 1.1.1.1.2.2 martin for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
1654 1.1.1.1.2.2 martin {
1655 1.1.1.1.2.2 martin nvd = ctf_list_next (dvd);
1656 1.1.1.1.2.2 martin ctf_dvd_delete (fp, dvd);
1657 1.1.1.1.2.2 martin }
1658 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_dvhash);
1659 1.1.1.1.2.2 martin ctf_str_free_atoms (fp);
1660 1.1.1.1.2.2 martin free (fp->ctf_tmp_typeslice);
1661 1.1.1.1.2.2 martin
1662 1.1.1.1.2.2 martin if (fp->ctf_data.cts_name != _CTF_NULLSTR)
1663 1.1.1.1.2.2 martin free ((char *) fp->ctf_data.cts_name);
1664 1.1.1.1.2.2 martin
1665 1.1.1.1.2.2 martin if (fp->ctf_symtab.cts_name != _CTF_NULLSTR)
1666 1.1.1.1.2.2 martin free ((char *) fp->ctf_symtab.cts_name);
1667 1.1.1.1.2.2 martin
1668 1.1.1.1.2.2 martin if (fp->ctf_strtab.cts_name != _CTF_NULLSTR)
1669 1.1.1.1.2.2 martin free ((char *) fp->ctf_strtab.cts_name);
1670 1.1.1.1.2.2 martin else if (fp->ctf_data_mmapped)
1671 1.1.1.1.2.2 martin ctf_munmap (fp->ctf_data_mmapped, fp->ctf_data_mmapped_len);
1672 1.1.1.1.2.2 martin
1673 1.1.1.1.2.2 martin free (fp->ctf_dynbase);
1674 1.1.1.1.2.2 martin
1675 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_syn_ext_strtab);
1676 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_link_inputs);
1677 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_link_outputs);
1678 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_link_type_mapping);
1679 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_link_cu_mapping);
1680 1.1.1.1.2.2 martin ctf_dynhash_destroy (fp->ctf_add_processing);
1681 1.1.1.1.2.2 martin
1682 1.1.1.1.2.2 martin free (fp->ctf_sxlate);
1683 1.1.1.1.2.2 martin free (fp->ctf_txlate);
1684 1.1.1.1.2.2 martin free (fp->ctf_ptrtab);
1685 1.1.1.1.2.2 martin
1686 1.1.1.1.2.2 martin free (fp->ctf_header);
1687 1.1.1.1.2.2 martin free (fp);
1688 1.1.1.1.2.2 martin }
1689 1.1.1.1.2.2 martin
1690 1.1.1.1.2.2 martin /* The converse of ctf_open(). ctf_open() disguises whatever it opens as an
1691 1.1.1.1.2.2 martin archive, so closing one is just like closing an archive. */
1692 1.1.1.1.2.2 martin void
1693 1.1.1.1.2.2 martin ctf_close (ctf_archive_t *arc)
1694 1.1.1.1.2.2 martin {
1695 1.1.1.1.2.2 martin ctf_arc_close (arc);
1696 1.1.1.1.2.2 martin }
1697 1.1.1.1.2.2 martin
1698 1.1.1.1.2.2 martin /* Get the CTF archive from which this ctf_file_t is derived. */
1699 1.1.1.1.2.2 martin ctf_archive_t *
1700 1.1.1.1.2.2 martin ctf_get_arc (const ctf_file_t *fp)
1701 1.1.1.1.2.2 martin {
1702 1.1.1.1.2.2 martin return fp->ctf_archive;
1703 1.1.1.1.2.2 martin }
1704 1.1.1.1.2.2 martin
1705 1.1.1.1.2.2 martin /* Return the ctfsect out of the core ctf_impl. Useful for freeing the
1706 1.1.1.1.2.2 martin ctfsect's data * after ctf_file_close(), which is why we return the actual
1707 1.1.1.1.2.2 martin structure, not a pointer to it, since that is likely to become a pointer to
1708 1.1.1.1.2.2 martin freed data before the return value is used under the expected use case of
1709 1.1.1.1.2.2 martin ctf_getsect()/ ctf_file_close()/free(). */
1710 1.1.1.1.2.2 martin ctf_sect_t
1711 1.1.1.1.2.2 martin ctf_getdatasect (const ctf_file_t *fp)
1712 1.1.1.1.2.2 martin {
1713 1.1.1.1.2.2 martin return fp->ctf_data;
1714 1.1.1.1.2.2 martin }
1715 1.1.1.1.2.2 martin
1716 1.1.1.1.2.2 martin /* Return the CTF handle for the parent CTF container, if one exists.
1717 1.1.1.1.2.2 martin Otherwise return NULL to indicate this container has no imported parent. */
1718 1.1.1.1.2.2 martin ctf_file_t *
1719 1.1.1.1.2.2 martin ctf_parent_file (ctf_file_t *fp)
1720 1.1.1.1.2.2 martin {
1721 1.1.1.1.2.2 martin return fp->ctf_parent;
1722 1.1.1.1.2.2 martin }
1723 1.1.1.1.2.2 martin
1724 1.1.1.1.2.2 martin /* Return the name of the parent CTF container, if one exists. Otherwise
1725 1.1.1.1.2.2 martin return NULL to indicate this container is a root container. */
1726 1.1.1.1.2.2 martin const char *
1727 1.1.1.1.2.2 martin ctf_parent_name (ctf_file_t *fp)
1728 1.1.1.1.2.2 martin {
1729 1.1.1.1.2.2 martin return fp->ctf_parname;
1730 1.1.1.1.2.2 martin }
1731 1.1.1.1.2.2 martin
1732 1.1.1.1.2.2 martin /* Set the parent name. It is an error to call this routine without calling
1733 1.1.1.1.2.2 martin ctf_import() at some point. */
1734 1.1.1.1.2.2 martin int
1735 1.1.1.1.2.2 martin ctf_parent_name_set (ctf_file_t *fp, const char *name)
1736 1.1.1.1.2.2 martin {
1737 1.1.1.1.2.2 martin if (fp->ctf_dynparname != NULL)
1738 1.1.1.1.2.2 martin free (fp->ctf_dynparname);
1739 1.1.1.1.2.2 martin
1740 1.1.1.1.2.2 martin if ((fp->ctf_dynparname = strdup (name)) == NULL)
1741 1.1.1.1.2.2 martin return (ctf_set_errno (fp, ENOMEM));
1742 1.1.1.1.2.2 martin fp->ctf_parname = fp->ctf_dynparname;
1743 1.1.1.1.2.2 martin return 0;
1744 1.1.1.1.2.2 martin }
1745 1.1.1.1.2.2 martin
1746 1.1.1.1.2.2 martin /* Return the name of the compilation unit this CTF file applies to. Usually
1747 1.1.1.1.2.2 martin non-NULL only for non-parent containers. */
1748 1.1.1.1.2.2 martin const char *
1749 1.1.1.1.2.2 martin ctf_cuname (ctf_file_t *fp)
1750 1.1.1.1.2.2 martin {
1751 1.1.1.1.2.2 martin return fp->ctf_cuname;
1752 1.1.1.1.2.2 martin }
1753 1.1.1.1.2.2 martin
1754 1.1.1.1.2.2 martin /* Set the compilation unit name. */
1755 1.1.1.1.2.2 martin int
1756 1.1.1.1.2.2 martin ctf_cuname_set (ctf_file_t *fp, const char *name)
1757 1.1.1.1.2.2 martin {
1758 1.1.1.1.2.2 martin if (fp->ctf_dyncuname != NULL)
1759 1.1.1.1.2.2 martin free (fp->ctf_dyncuname);
1760 1.1.1.1.2.2 martin
1761 1.1.1.1.2.2 martin if ((fp->ctf_dyncuname = strdup (name)) == NULL)
1762 1.1.1.1.2.2 martin return (ctf_set_errno (fp, ENOMEM));
1763 1.1.1.1.2.2 martin fp->ctf_cuname = fp->ctf_dyncuname;
1764 1.1.1.1.2.2 martin return 0;
1765 1.1.1.1.2.2 martin }
1766 1.1.1.1.2.2 martin
1767 1.1.1.1.2.2 martin /* Import the types from the specified parent container by storing a pointer
1768 1.1.1.1.2.2 martin to it in ctf_parent and incrementing its reference count. Only one parent
1769 1.1.1.1.2.2 martin is allowed: if a parent already exists, it is replaced by the new parent. */
1770 1.1.1.1.2.2 martin int
1771 1.1.1.1.2.2 martin ctf_import (ctf_file_t *fp, ctf_file_t *pfp)
1772 1.1.1.1.2.2 martin {
1773 1.1.1.1.2.2 martin if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))
1774 1.1.1.1.2.2 martin return (ctf_set_errno (fp, EINVAL));
1775 1.1.1.1.2.2 martin
1776 1.1.1.1.2.2 martin if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)
1777 1.1.1.1.2.2 martin return (ctf_set_errno (fp, ECTF_DMODEL));
1778 1.1.1.1.2.2 martin
1779 1.1.1.1.2.2 martin if (fp->ctf_parent != NULL)
1780 1.1.1.1.2.2 martin {
1781 1.1.1.1.2.2 martin fp->ctf_parent->ctf_refcnt--;
1782 1.1.1.1.2.2 martin ctf_file_close (fp->ctf_parent);
1783 1.1.1.1.2.2 martin fp->ctf_parent = NULL;
1784 1.1.1.1.2.2 martin }
1785 1.1.1.1.2.2 martin
1786 1.1.1.1.2.2 martin if (pfp != NULL)
1787 1.1.1.1.2.2 martin {
1788 1.1.1.1.2.2 martin int err;
1789 1.1.1.1.2.2 martin
1790 1.1.1.1.2.2 martin if (fp->ctf_parname == NULL)
1791 1.1.1.1.2.2 martin if ((err = ctf_parent_name_set (fp, "PARENT")) < 0)
1792 1.1.1.1.2.2 martin return err;
1793 1.1.1.1.2.2 martin
1794 1.1.1.1.2.2 martin fp->ctf_flags |= LCTF_CHILD;
1795 1.1.1.1.2.2 martin pfp->ctf_refcnt++;
1796 1.1.1.1.2.2 martin }
1797 1.1.1.1.2.2 martin
1798 1.1.1.1.2.2 martin fp->ctf_parent = pfp;
1799 1.1.1.1.2.2 martin return 0;
1800 1.1.1.1.2.2 martin }
1801 1.1.1.1.2.2 martin
1802 1.1.1.1.2.2 martin /* Set the data model constant for the CTF container. */
1803 1.1.1.1.2.2 martin int
1804 1.1.1.1.2.2 martin ctf_setmodel (ctf_file_t *fp, int model)
1805 1.1.1.1.2.2 martin {
1806 1.1.1.1.2.2 martin const ctf_dmodel_t *dp;
1807 1.1.1.1.2.2 martin
1808 1.1.1.1.2.2 martin for (dp = _libctf_models; dp->ctd_name != NULL; dp++)
1809 1.1.1.1.2.2 martin {
1810 1.1.1.1.2.2 martin if (dp->ctd_code == model)
1811 1.1.1.1.2.2 martin {
1812 1.1.1.1.2.2 martin fp->ctf_dmodel = dp;
1813 1.1.1.1.2.2 martin return 0;
1814 1.1.1.1.2.2 martin }
1815 1.1.1.1.2.2 martin }
1816 1.1.1.1.2.2 martin
1817 1.1.1.1.2.2 martin return (ctf_set_errno (fp, EINVAL));
1818 1.1.1.1.2.2 martin }
1819 1.1.1.1.2.2 martin
1820 1.1.1.1.2.2 martin /* Return the data model constant for the CTF container. */
1821 1.1.1.1.2.2 martin int
1822 1.1.1.1.2.2 martin ctf_getmodel (ctf_file_t *fp)
1823 1.1.1.1.2.2 martin {
1824 1.1.1.1.2.2 martin return fp->ctf_dmodel->ctd_code;
1825 1.1.1.1.2.2 martin }
1826 1.1.1.1.2.2 martin
1827 1.1.1.1.2.2 martin /* The caller can hang an arbitrary pointer off each ctf_file_t using this
1828 1.1.1.1.2.2 martin function. */
1829 1.1.1.1.2.2 martin void
1830 1.1.1.1.2.2 martin ctf_setspecific (ctf_file_t *fp, void *data)
1831 1.1.1.1.2.2 martin {
1832 1.1.1.1.2.2 martin fp->ctf_specific = data;
1833 1.1.1.1.2.2 martin }
1834 1.1.1.1.2.2 martin
1835 1.1.1.1.2.2 martin /* Retrieve the arbitrary pointer again. */
1836 1.1.1.1.2.2 martin void *
1837 1.1.1.1.2.2 martin ctf_getspecific (ctf_file_t *fp)
1838 1.1.1.1.2.2 martin {
1839 1.1.1.1.2.2 martin return fp->ctf_specific;
1840 1.1.1.1.2.2 martin }
1841