ctf-create.c revision 1.1.1.2 1 1.1.1.2 christos /* CTF dict creation.
2 1.1.1.2 christos Copyright (C) 2019-2022 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of libctf.
5 1.1 christos
6 1.1 christos libctf is free software; you can redistribute it and/or modify it under
7 1.1 christos the terms of the GNU General Public License as published by the Free
8 1.1 christos Software Foundation; either version 3, or (at your option) any later
9 1.1 christos version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful, but
12 1.1 christos WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 1.1 christos See the GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; see the file COPYING. If not see
18 1.1 christos <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include <ctf-impl.h>
21 1.1 christos #include <sys/param.h>
22 1.1 christos #include <string.h>
23 1.1 christos #include <unistd.h>
24 1.1 christos
25 1.1 christos #ifndef EOVERFLOW
26 1.1 christos #define EOVERFLOW ERANGE
27 1.1 christos #endif
28 1.1 christos
29 1.1 christos #ifndef roundup
30 1.1 christos #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
31 1.1 christos #endif
32 1.1 christos
33 1.1.1.2 christos /* The initial size of a dynamic type's vlen in members. Arbitrary: the bigger
34 1.1.1.2 christos this is, the less allocation needs to be done for small structure
35 1.1.1.2 christos initialization, and the more memory is wasted for small structures during CTF
36 1.1.1.2 christos construction. No effect on generated CTF or ctf_open()ed CTF. */
37 1.1.1.2 christos #define INITIAL_VLEN 16
38 1.1.1.2 christos
39 1.1 christos /* Make sure the ptrtab has enough space for at least one more type.
40 1.1 christos
41 1.1 christos We start with 4KiB of ptrtab, enough for a thousand types, then grow it 25%
42 1.1 christos at a time. */
43 1.1 christos
44 1.1 christos static int
45 1.1.1.2 christos ctf_grow_ptrtab (ctf_dict_t *fp)
46 1.1 christos {
47 1.1 christos size_t new_ptrtab_len = fp->ctf_ptrtab_len;
48 1.1 christos
49 1.1 christos /* We allocate one more ptrtab entry than we need, for the initial zero,
50 1.1 christos plus one because the caller will probably allocate a new type. */
51 1.1 christos
52 1.1 christos if (fp->ctf_ptrtab == NULL)
53 1.1 christos new_ptrtab_len = 1024;
54 1.1 christos else if ((fp->ctf_typemax + 2) > fp->ctf_ptrtab_len)
55 1.1 christos new_ptrtab_len = fp->ctf_ptrtab_len * 1.25;
56 1.1 christos
57 1.1 christos if (new_ptrtab_len != fp->ctf_ptrtab_len)
58 1.1 christos {
59 1.1 christos uint32_t *new_ptrtab;
60 1.1 christos
61 1.1 christos if ((new_ptrtab = realloc (fp->ctf_ptrtab,
62 1.1 christos new_ptrtab_len * sizeof (uint32_t))) == NULL)
63 1.1 christos return (ctf_set_errno (fp, ENOMEM));
64 1.1 christos
65 1.1 christos fp->ctf_ptrtab = new_ptrtab;
66 1.1 christos memset (fp->ctf_ptrtab + fp->ctf_ptrtab_len, 0,
67 1.1 christos (new_ptrtab_len - fp->ctf_ptrtab_len) * sizeof (uint32_t));
68 1.1 christos fp->ctf_ptrtab_len = new_ptrtab_len;
69 1.1 christos }
70 1.1 christos return 0;
71 1.1 christos }
72 1.1 christos
73 1.1.1.2 christos /* Make sure a vlen has enough space: expand it otherwise. Unlike the ptrtab,
74 1.1.1.2 christos which grows quite slowly, the vlen grows in big jumps because it is quite
75 1.1.1.2 christos expensive to expand: the caller has to scan the old vlen for string refs
76 1.1.1.2 christos first and remove them, then re-add them afterwards. The initial size is
77 1.1.1.2 christos more or less arbitrary. */
78 1.1.1.2 christos static int
79 1.1.1.2 christos ctf_grow_vlen (ctf_dict_t *fp, ctf_dtdef_t *dtd, size_t vlen)
80 1.1.1.2 christos {
81 1.1.1.2 christos unsigned char *old = dtd->dtd_vlen;
82 1.1.1.2 christos
83 1.1.1.2 christos if (dtd->dtd_vlen_alloc > vlen)
84 1.1.1.2 christos return 0;
85 1.1.1.2 christos
86 1.1.1.2 christos if ((dtd->dtd_vlen = realloc (dtd->dtd_vlen,
87 1.1.1.2 christos dtd->dtd_vlen_alloc * 2)) == NULL)
88 1.1.1.2 christos {
89 1.1.1.2 christos dtd->dtd_vlen = old;
90 1.1.1.2 christos return (ctf_set_errno (fp, ENOMEM));
91 1.1.1.2 christos }
92 1.1.1.2 christos memset (dtd->dtd_vlen + dtd->dtd_vlen_alloc, 0, dtd->dtd_vlen_alloc);
93 1.1.1.2 christos dtd->dtd_vlen_alloc *= 2;
94 1.1.1.2 christos return 0;
95 1.1.1.2 christos }
96 1.1.1.2 christos
97 1.1.1.2 christos /* To create an empty CTF dict, we just declare a zeroed header and call
98 1.1.1.2 christos ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new dict r/w and
99 1.1.1.2 christos initialize the dynamic members. We start assigning type IDs at 1 because
100 1.1 christos type ID 0 is used as a sentinel and a not-found indicator. */
101 1.1 christos
102 1.1.1.2 christos ctf_dict_t *
103 1.1 christos ctf_create (int *errp)
104 1.1 christos {
105 1.1 christos static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
106 1.1 christos
107 1.1 christos ctf_dynhash_t *dthash;
108 1.1 christos ctf_dynhash_t *dvhash;
109 1.1 christos ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL;
110 1.1.1.2 christos ctf_dynhash_t *objthash = NULL, *funchash = NULL;
111 1.1 christos ctf_sect_t cts;
112 1.1.1.2 christos ctf_dict_t *fp;
113 1.1 christos
114 1.1 christos libctf_init_debug();
115 1.1 christos dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
116 1.1 christos NULL, NULL);
117 1.1 christos if (dthash == NULL)
118 1.1 christos {
119 1.1 christos ctf_set_open_errno (errp, EAGAIN);
120 1.1 christos goto err;
121 1.1 christos }
122 1.1 christos
123 1.1 christos dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
124 1.1 christos NULL, NULL);
125 1.1 christos if (dvhash == NULL)
126 1.1 christos {
127 1.1 christos ctf_set_open_errno (errp, EAGAIN);
128 1.1 christos goto err_dt;
129 1.1 christos }
130 1.1 christos
131 1.1 christos structs = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
132 1.1 christos NULL, NULL);
133 1.1 christos unions = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
134 1.1 christos NULL, NULL);
135 1.1 christos enums = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
136 1.1 christos NULL, NULL);
137 1.1 christos names = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
138 1.1 christos NULL, NULL);
139 1.1.1.2 christos objthash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
140 1.1.1.2 christos free, NULL);
141 1.1.1.2 christos funchash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
142 1.1.1.2 christos free, NULL);
143 1.1 christos if (!structs || !unions || !enums || !names)
144 1.1 christos {
145 1.1 christos ctf_set_open_errno (errp, EAGAIN);
146 1.1 christos goto err_dv;
147 1.1 christos }
148 1.1 christos
149 1.1 christos cts.cts_name = _CTF_SECTION;
150 1.1 christos cts.cts_data = &hdr;
151 1.1 christos cts.cts_size = sizeof (hdr);
152 1.1 christos cts.cts_entsize = 1;
153 1.1 christos
154 1.1 christos if ((fp = ctf_bufopen_internal (&cts, NULL, NULL, NULL, 1, errp)) == NULL)
155 1.1 christos goto err_dv;
156 1.1 christos
157 1.1 christos fp->ctf_structs.ctn_writable = structs;
158 1.1 christos fp->ctf_unions.ctn_writable = unions;
159 1.1 christos fp->ctf_enums.ctn_writable = enums;
160 1.1 christos fp->ctf_names.ctn_writable = names;
161 1.1.1.2 christos fp->ctf_objthash = objthash;
162 1.1.1.2 christos fp->ctf_funchash = funchash;
163 1.1 christos fp->ctf_dthash = dthash;
164 1.1 christos fp->ctf_dvhash = dvhash;
165 1.1 christos fp->ctf_dtoldid = 0;
166 1.1 christos fp->ctf_snapshots = 1;
167 1.1 christos fp->ctf_snapshot_lu = 0;
168 1.1 christos fp->ctf_flags |= LCTF_DIRTY;
169 1.1 christos
170 1.1 christos ctf_set_ctl_hashes (fp);
171 1.1 christos ctf_setmodel (fp, CTF_MODEL_NATIVE);
172 1.1 christos if (ctf_grow_ptrtab (fp) < 0)
173 1.1 christos {
174 1.1 christos ctf_set_open_errno (errp, ctf_errno (fp));
175 1.1.1.2 christos ctf_dict_close (fp);
176 1.1 christos return NULL;
177 1.1 christos }
178 1.1 christos
179 1.1 christos return fp;
180 1.1 christos
181 1.1 christos err_dv:
182 1.1 christos ctf_dynhash_destroy (structs);
183 1.1 christos ctf_dynhash_destroy (unions);
184 1.1 christos ctf_dynhash_destroy (enums);
185 1.1 christos ctf_dynhash_destroy (names);
186 1.1.1.2 christos ctf_dynhash_destroy (objthash);
187 1.1.1.2 christos ctf_dynhash_destroy (funchash);
188 1.1 christos ctf_dynhash_destroy (dvhash);
189 1.1 christos err_dt:
190 1.1 christos ctf_dynhash_destroy (dthash);
191 1.1 christos err:
192 1.1 christos return NULL;
193 1.1 christos }
194 1.1 christos
195 1.1 christos /* Compatibility: just update the threshold for ctf_discard. */
196 1.1 christos int
197 1.1.1.2 christos ctf_update (ctf_dict_t *fp)
198 1.1 christos {
199 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
200 1.1 christos return (ctf_set_errno (fp, ECTF_RDONLY));
201 1.1 christos
202 1.1 christos fp->ctf_dtoldid = fp->ctf_typemax;
203 1.1 christos return 0;
204 1.1 christos }
205 1.1 christos
206 1.1 christos ctf_names_t *
207 1.1.1.2 christos ctf_name_table (ctf_dict_t *fp, int kind)
208 1.1 christos {
209 1.1 christos switch (kind)
210 1.1 christos {
211 1.1 christos case CTF_K_STRUCT:
212 1.1 christos return &fp->ctf_structs;
213 1.1 christos case CTF_K_UNION:
214 1.1 christos return &fp->ctf_unions;
215 1.1 christos case CTF_K_ENUM:
216 1.1 christos return &fp->ctf_enums;
217 1.1 christos default:
218 1.1 christos return &fp->ctf_names;
219 1.1 christos }
220 1.1 christos }
221 1.1 christos
222 1.1 christos int
223 1.1.1.2 christos ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
224 1.1 christos {
225 1.1 christos const char *name;
226 1.1 christos if (ctf_dynhash_insert (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type,
227 1.1 christos dtd) < 0)
228 1.1.1.2 christos {
229 1.1.1.2 christos ctf_set_errno (fp, ENOMEM);
230 1.1.1.2 christos return -1;
231 1.1.1.2 christos }
232 1.1 christos
233 1.1 christos if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
234 1.1 christos && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
235 1.1 christos {
236 1.1 christos if (ctf_dynhash_insert (ctf_name_table (fp, kind)->ctn_writable,
237 1.1 christos (char *) name, (void *) (uintptr_t)
238 1.1 christos dtd->dtd_type) < 0)
239 1.1 christos {
240 1.1 christos ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t)
241 1.1 christos dtd->dtd_type);
242 1.1.1.2 christos ctf_set_errno (fp, ENOMEM);
243 1.1 christos return -1;
244 1.1 christos }
245 1.1 christos }
246 1.1 christos ctf_list_append (&fp->ctf_dtdefs, dtd);
247 1.1 christos return 0;
248 1.1 christos }
249 1.1 christos
250 1.1 christos void
251 1.1.1.2 christos ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
252 1.1 christos {
253 1.1 christos int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
254 1.1.1.2 christos size_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
255 1.1 christos int name_kind = kind;
256 1.1 christos const char *name;
257 1.1 christos
258 1.1 christos ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
259 1.1 christos
260 1.1 christos switch (kind)
261 1.1 christos {
262 1.1 christos case CTF_K_STRUCT:
263 1.1 christos case CTF_K_UNION:
264 1.1.1.2 christos {
265 1.1.1.2 christos ctf_lmember_t *memb = (ctf_lmember_t *) dtd->dtd_vlen;
266 1.1.1.2 christos size_t i;
267 1.1.1.2 christos
268 1.1.1.2 christos for (i = 0; i < vlen; i++)
269 1.1.1.2 christos ctf_str_remove_ref (fp, ctf_strraw (fp, memb[i].ctlm_name),
270 1.1.1.2 christos &memb[i].ctlm_name);
271 1.1.1.2 christos }
272 1.1 christos break;
273 1.1.1.2 christos case CTF_K_ENUM:
274 1.1.1.2 christos {
275 1.1.1.2 christos ctf_enum_t *en = (ctf_enum_t *) dtd->dtd_vlen;
276 1.1.1.2 christos size_t i;
277 1.1.1.2 christos
278 1.1.1.2 christos for (i = 0; i < vlen; i++)
279 1.1.1.2 christos ctf_str_remove_ref (fp, ctf_strraw (fp, en[i].cte_name),
280 1.1.1.2 christos &en[i].cte_name);
281 1.1.1.2 christos }
282 1.1 christos break;
283 1.1 christos case CTF_K_FORWARD:
284 1.1 christos name_kind = dtd->dtd_data.ctt_type;
285 1.1 christos break;
286 1.1 christos }
287 1.1.1.2 christos free (dtd->dtd_vlen);
288 1.1.1.2 christos dtd->dtd_vlen_alloc = 0;
289 1.1 christos
290 1.1 christos if (dtd->dtd_data.ctt_name
291 1.1 christos && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
292 1.1 christos && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
293 1.1 christos {
294 1.1 christos ctf_dynhash_remove (ctf_name_table (fp, name_kind)->ctn_writable,
295 1.1 christos name);
296 1.1 christos ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
297 1.1 christos }
298 1.1 christos
299 1.1 christos ctf_list_delete (&fp->ctf_dtdefs, dtd);
300 1.1 christos free (dtd);
301 1.1 christos }
302 1.1 christos
303 1.1 christos ctf_dtdef_t *
304 1.1.1.2 christos ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type)
305 1.1 christos {
306 1.1 christos return (ctf_dtdef_t *)
307 1.1 christos ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type);
308 1.1 christos }
309 1.1 christos
310 1.1 christos ctf_dtdef_t *
311 1.1.1.2 christos ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id)
312 1.1 christos {
313 1.1 christos ctf_id_t idx;
314 1.1 christos
315 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
316 1.1 christos return NULL;
317 1.1 christos
318 1.1 christos if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
319 1.1 christos fp = fp->ctf_parent;
320 1.1 christos
321 1.1 christos idx = LCTF_TYPE_TO_INDEX(fp, id);
322 1.1 christos
323 1.1 christos if ((unsigned long) idx <= fp->ctf_typemax)
324 1.1 christos return ctf_dtd_lookup (fp, id);
325 1.1 christos return NULL;
326 1.1 christos }
327 1.1 christos
328 1.1 christos int
329 1.1.1.2 christos ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
330 1.1 christos {
331 1.1 christos if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
332 1.1.1.2 christos {
333 1.1.1.2 christos ctf_set_errno (fp, ENOMEM);
334 1.1.1.2 christos return -1;
335 1.1.1.2 christos }
336 1.1 christos ctf_list_append (&fp->ctf_dvdefs, dvd);
337 1.1 christos return 0;
338 1.1 christos }
339 1.1 christos
340 1.1 christos void
341 1.1.1.2 christos ctf_dvd_delete (ctf_dict_t *fp, ctf_dvdef_t *dvd)
342 1.1 christos {
343 1.1 christos ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
344 1.1 christos free (dvd->dvd_name);
345 1.1 christos
346 1.1 christos ctf_list_delete (&fp->ctf_dvdefs, dvd);
347 1.1 christos free (dvd);
348 1.1 christos }
349 1.1 christos
350 1.1 christos ctf_dvdef_t *
351 1.1.1.2 christos ctf_dvd_lookup (const ctf_dict_t *fp, const char *name)
352 1.1 christos {
353 1.1 christos return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
354 1.1 christos }
355 1.1 christos
356 1.1 christos /* Discard all of the dynamic type definitions and variable definitions that
357 1.1.1.2 christos have been added to the dict since the last call to ctf_update(). We locate
358 1.1.1.2 christos such types by scanning the dtd list and deleting elements that have type IDs
359 1.1.1.2 christos greater than ctf_dtoldid, which is set by ctf_update(), above, and by
360 1.1.1.2 christos scanning the variable list and deleting elements that have update IDs equal
361 1.1.1.2 christos to the current value of the last-update snapshot count (indicating that they
362 1.1.1.2 christos were added after the most recent call to ctf_update()). */
363 1.1 christos int
364 1.1.1.2 christos ctf_discard (ctf_dict_t *fp)
365 1.1 christos {
366 1.1 christos ctf_snapshot_id_t last_update =
367 1.1 christos { fp->ctf_dtoldid,
368 1.1 christos fp->ctf_snapshot_lu + 1 };
369 1.1 christos
370 1.1 christos /* Update required? */
371 1.1 christos if (!(fp->ctf_flags & LCTF_DIRTY))
372 1.1 christos return 0;
373 1.1 christos
374 1.1 christos return (ctf_rollback (fp, last_update));
375 1.1 christos }
376 1.1 christos
377 1.1 christos ctf_snapshot_id_t
378 1.1.1.2 christos ctf_snapshot (ctf_dict_t *fp)
379 1.1 christos {
380 1.1 christos ctf_snapshot_id_t snapid;
381 1.1 christos snapid.dtd_id = fp->ctf_typemax;
382 1.1 christos snapid.snapshot_id = fp->ctf_snapshots++;
383 1.1 christos return snapid;
384 1.1 christos }
385 1.1 christos
386 1.1 christos /* Like ctf_discard(), only discards everything after a particular ID. */
387 1.1 christos int
388 1.1.1.2 christos ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
389 1.1 christos {
390 1.1 christos ctf_dtdef_t *dtd, *ntd;
391 1.1 christos ctf_dvdef_t *dvd, *nvd;
392 1.1 christos
393 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
394 1.1 christos return (ctf_set_errno (fp, ECTF_RDONLY));
395 1.1 christos
396 1.1 christos if (fp->ctf_snapshot_lu >= id.snapshot_id)
397 1.1 christos return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
398 1.1 christos
399 1.1 christos for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
400 1.1 christos {
401 1.1 christos int kind;
402 1.1 christos const char *name;
403 1.1 christos
404 1.1 christos ntd = ctf_list_next (dtd);
405 1.1 christos
406 1.1 christos if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
407 1.1 christos continue;
408 1.1 christos
409 1.1 christos kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
410 1.1 christos if (kind == CTF_K_FORWARD)
411 1.1 christos kind = dtd->dtd_data.ctt_type;
412 1.1 christos
413 1.1 christos if (dtd->dtd_data.ctt_name
414 1.1 christos && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
415 1.1 christos && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
416 1.1 christos {
417 1.1 christos ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
418 1.1 christos name);
419 1.1 christos ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
420 1.1 christos }
421 1.1 christos
422 1.1 christos ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
423 1.1 christos ctf_dtd_delete (fp, dtd);
424 1.1 christos }
425 1.1 christos
426 1.1 christos for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
427 1.1 christos {
428 1.1 christos nvd = ctf_list_next (dvd);
429 1.1 christos
430 1.1 christos if (dvd->dvd_snapshots <= id.snapshot_id)
431 1.1 christos continue;
432 1.1 christos
433 1.1 christos ctf_dvd_delete (fp, dvd);
434 1.1 christos }
435 1.1 christos
436 1.1 christos fp->ctf_typemax = id.dtd_id;
437 1.1 christos fp->ctf_snapshots = id.snapshot_id;
438 1.1 christos
439 1.1 christos if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
440 1.1 christos fp->ctf_flags &= ~LCTF_DIRTY;
441 1.1 christos
442 1.1 christos return 0;
443 1.1 christos }
444 1.1 christos
445 1.1.1.2 christos /* Note: vlen is the amount of space *allocated* for the vlen. It may well not
446 1.1.1.2 christos be the amount of space used (yet): the space used is declared in per-kind
447 1.1.1.2 christos fashion in the dtd_data's info word. */
448 1.1 christos static ctf_id_t
449 1.1.1.2 christos ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
450 1.1.1.2 christos size_t vlen, ctf_dtdef_t **rp)
451 1.1 christos {
452 1.1 christos ctf_dtdef_t *dtd;
453 1.1 christos ctf_id_t type;
454 1.1 christos
455 1.1 christos if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
456 1.1 christos return (ctf_set_errno (fp, EINVAL));
457 1.1 christos
458 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
459 1.1 christos return (ctf_set_errno (fp, ECTF_RDONLY));
460 1.1 christos
461 1.1 christos if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
462 1.1 christos return (ctf_set_errno (fp, ECTF_FULL));
463 1.1 christos
464 1.1 christos if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
465 1.1 christos return (ctf_set_errno (fp, ECTF_FULL));
466 1.1 christos
467 1.1 christos /* Make sure ptrtab always grows to be big enough for all types. */
468 1.1 christos if (ctf_grow_ptrtab (fp) < 0)
469 1.1.1.2 christos return CTF_ERR; /* errno is set for us. */
470 1.1 christos
471 1.1.1.2 christos if ((dtd = calloc (1, sizeof (ctf_dtdef_t))) == NULL)
472 1.1 christos return (ctf_set_errno (fp, EAGAIN));
473 1.1 christos
474 1.1.1.2 christos dtd->dtd_vlen_alloc = vlen;
475 1.1.1.2 christos if (vlen > 0)
476 1.1.1.2 christos {
477 1.1.1.2 christos if ((dtd->dtd_vlen = calloc (1, vlen)) == NULL)
478 1.1.1.2 christos goto oom;
479 1.1.1.2 christos }
480 1.1.1.2 christos else
481 1.1.1.2 christos dtd->dtd_vlen = NULL;
482 1.1.1.2 christos
483 1.1 christos type = ++fp->ctf_typemax;
484 1.1 christos type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
485 1.1 christos
486 1.1.1.2 christos dtd->dtd_data.ctt_name = ctf_str_add_pending (fp, name,
487 1.1.1.2 christos &dtd->dtd_data.ctt_name);
488 1.1 christos dtd->dtd_type = type;
489 1.1 christos
490 1.1 christos if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
491 1.1.1.2 christos goto oom;
492 1.1 christos
493 1.1 christos if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
494 1.1.1.2 christos goto err; /* errno is set for us. */
495 1.1.1.2 christos
496 1.1 christos fp->ctf_flags |= LCTF_DIRTY;
497 1.1 christos
498 1.1 christos *rp = dtd;
499 1.1 christos return type;
500 1.1.1.2 christos
501 1.1.1.2 christos oom:
502 1.1.1.2 christos ctf_set_errno (fp, EAGAIN);
503 1.1.1.2 christos err:
504 1.1.1.2 christos free (dtd->dtd_vlen);
505 1.1.1.2 christos free (dtd);
506 1.1.1.2 christos return CTF_ERR;
507 1.1 christos }
508 1.1 christos
509 1.1 christos /* When encoding integer sizes, we want to convert a byte count in the range
510 1.1 christos 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
511 1.1 christos is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
512 1.1 christos static size_t
513 1.1 christos clp2 (size_t x)
514 1.1 christos {
515 1.1 christos x--;
516 1.1 christos
517 1.1 christos x |= (x >> 1);
518 1.1 christos x |= (x >> 2);
519 1.1 christos x |= (x >> 4);
520 1.1 christos x |= (x >> 8);
521 1.1 christos x |= (x >> 16);
522 1.1 christos
523 1.1 christos return (x + 1);
524 1.1 christos }
525 1.1 christos
526 1.1 christos ctf_id_t
527 1.1.1.2 christos ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
528 1.1 christos const char *name, const ctf_encoding_t *ep, uint32_t kind)
529 1.1 christos {
530 1.1 christos ctf_dtdef_t *dtd;
531 1.1 christos ctf_id_t type;
532 1.1.1.2 christos uint32_t encoding;
533 1.1 christos
534 1.1 christos if (ep == NULL)
535 1.1 christos return (ctf_set_errno (fp, EINVAL));
536 1.1 christos
537 1.1.1.2 christos if (name == NULL || name[0] == '\0')
538 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_NONAME));
539 1.1.1.2 christos
540 1.1.1.2 christos if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT))
541 1.1.1.2 christos return -1; /* errno is set for us. */
542 1.1.1.2 christos
543 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, name, kind, sizeof (uint32_t),
544 1.1.1.2 christos &dtd)) == CTF_ERR)
545 1.1 christos return CTF_ERR; /* errno is set for us. */
546 1.1 christos
547 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
548 1.1 christos dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
549 1.1 christos / CHAR_BIT);
550 1.1.1.2 christos switch (kind)
551 1.1.1.2 christos {
552 1.1.1.2 christos case CTF_K_INTEGER:
553 1.1.1.2 christos encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
554 1.1.1.2 christos break;
555 1.1.1.2 christos case CTF_K_FLOAT:
556 1.1.1.2 christos encoding = CTF_FP_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
557 1.1.1.2 christos break;
558 1.1.1.2 christos }
559 1.1.1.2 christos memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
560 1.1 christos
561 1.1 christos return type;
562 1.1 christos }
563 1.1 christos
564 1.1 christos ctf_id_t
565 1.1.1.2 christos ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
566 1.1 christos {
567 1.1 christos ctf_dtdef_t *dtd;
568 1.1 christos ctf_id_t type;
569 1.1.1.2 christos ctf_dict_t *tmp = fp;
570 1.1 christos int child = fp->ctf_flags & LCTF_CHILD;
571 1.1 christos
572 1.1 christos if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
573 1.1 christos return (ctf_set_errno (fp, EINVAL));
574 1.1 christos
575 1.1 christos if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
576 1.1 christos return CTF_ERR; /* errno is set for us. */
577 1.1 christos
578 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, NULL, kind, 0, &dtd)) == CTF_ERR)
579 1.1 christos return CTF_ERR; /* errno is set for us. */
580 1.1 christos
581 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
582 1.1 christos dtd->dtd_data.ctt_type = (uint32_t) ref;
583 1.1 christos
584 1.1 christos if (kind != CTF_K_POINTER)
585 1.1 christos return type;
586 1.1 christos
587 1.1.1.2 christos /* If we are adding a pointer, update the ptrtab, pointing at this type from
588 1.1.1.2 christos the type it points to. Note that ctf_typemax is at this point one higher
589 1.1.1.2 christos than we want to check against, because it's just been incremented for the
590 1.1.1.2 christos addition of this type. The pptrtab is lazily-updated as needed, so is not
591 1.1.1.2 christos touched here. */
592 1.1 christos
593 1.1 christos uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
594 1.1 christos uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
595 1.1 christos
596 1.1 christos if (LCTF_TYPE_ISCHILD (fp, ref) == child
597 1.1 christos && ref_idx < fp->ctf_typemax)
598 1.1.1.2 christos fp->ctf_ptrtab[ref_idx] = type_idx;
599 1.1 christos
600 1.1 christos return type;
601 1.1 christos }
602 1.1 christos
603 1.1 christos ctf_id_t
604 1.1.1.2 christos ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
605 1.1 christos const ctf_encoding_t *ep)
606 1.1 christos {
607 1.1 christos ctf_dtdef_t *dtd;
608 1.1.1.2 christos ctf_slice_t slice;
609 1.1 christos ctf_id_t resolved_ref = ref;
610 1.1 christos ctf_id_t type;
611 1.1 christos int kind;
612 1.1 christos const ctf_type_t *tp;
613 1.1.1.2 christos ctf_dict_t *tmp = fp;
614 1.1 christos
615 1.1 christos if (ep == NULL)
616 1.1 christos return (ctf_set_errno (fp, EINVAL));
617 1.1 christos
618 1.1 christos if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
619 1.1 christos return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
620 1.1 christos
621 1.1 christos if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
622 1.1 christos return (ctf_set_errno (fp, EINVAL));
623 1.1 christos
624 1.1 christos if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
625 1.1 christos return CTF_ERR; /* errno is set for us. */
626 1.1 christos
627 1.1 christos /* Make sure we ultimately point to an integral type. We also allow slices to
628 1.1 christos point to the unimplemented type, for now, because the compiler can emit
629 1.1 christos such slices, though they're not very much use. */
630 1.1 christos
631 1.1 christos resolved_ref = ctf_type_resolve_unsliced (tmp, ref);
632 1.1 christos kind = ctf_type_kind_unsliced (tmp, resolved_ref);
633 1.1 christos
634 1.1 christos if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
635 1.1 christos (kind != CTF_K_ENUM)
636 1.1 christos && (ref != 0))
637 1.1 christos return (ctf_set_errno (fp, ECTF_NOTINTFP));
638 1.1 christos
639 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE,
640 1.1.1.2 christos sizeof (ctf_slice_t), &dtd)) == CTF_ERR)
641 1.1 christos return CTF_ERR; /* errno is set for us. */
642 1.1 christos
643 1.1.1.2 christos memset (&slice, 0, sizeof (ctf_slice_t));
644 1.1.1.2 christos
645 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
646 1.1 christos dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
647 1.1 christos / CHAR_BIT);
648 1.1.1.2 christos slice.cts_type = (uint32_t) ref;
649 1.1.1.2 christos slice.cts_bits = ep->cte_bits;
650 1.1.1.2 christos slice.cts_offset = ep->cte_offset;
651 1.1.1.2 christos memcpy (dtd->dtd_vlen, &slice, sizeof (ctf_slice_t));
652 1.1 christos
653 1.1 christos return type;
654 1.1 christos }
655 1.1 christos
656 1.1 christos ctf_id_t
657 1.1.1.2 christos ctf_add_integer (ctf_dict_t *fp, uint32_t flag,
658 1.1 christos const char *name, const ctf_encoding_t *ep)
659 1.1 christos {
660 1.1 christos return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
661 1.1 christos }
662 1.1 christos
663 1.1 christos ctf_id_t
664 1.1.1.2 christos ctf_add_float (ctf_dict_t *fp, uint32_t flag,
665 1.1 christos const char *name, const ctf_encoding_t *ep)
666 1.1 christos {
667 1.1 christos return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
668 1.1 christos }
669 1.1 christos
670 1.1 christos ctf_id_t
671 1.1.1.2 christos ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
672 1.1 christos {
673 1.1 christos return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
674 1.1 christos }
675 1.1 christos
676 1.1 christos ctf_id_t
677 1.1.1.2 christos ctf_add_array (ctf_dict_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
678 1.1 christos {
679 1.1 christos ctf_dtdef_t *dtd;
680 1.1.1.2 christos ctf_array_t cta;
681 1.1 christos ctf_id_t type;
682 1.1.1.2 christos ctf_dict_t *tmp = fp;
683 1.1 christos
684 1.1 christos if (arp == NULL)
685 1.1 christos return (ctf_set_errno (fp, EINVAL));
686 1.1 christos
687 1.1 christos if (arp->ctr_contents != 0
688 1.1 christos && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
689 1.1 christos return CTF_ERR; /* errno is set for us. */
690 1.1 christos
691 1.1 christos tmp = fp;
692 1.1 christos if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
693 1.1 christos return CTF_ERR; /* errno is set for us. */
694 1.1 christos
695 1.1.1.2 christos if (ctf_type_kind (fp, arp->ctr_index) == CTF_K_FORWARD)
696 1.1.1.2 christos {
697 1.1.1.2 christos ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
698 1.1.1.2 christos _("ctf_add_array: index type %lx is incomplete"),
699 1.1.1.2 christos arp->ctr_contents);
700 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_INCOMPLETE));
701 1.1.1.2 christos }
702 1.1.1.2 christos
703 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY,
704 1.1.1.2 christos sizeof (ctf_array_t), &dtd)) == CTF_ERR)
705 1.1 christos return CTF_ERR; /* errno is set for us. */
706 1.1 christos
707 1.1.1.2 christos memset (&cta, 0, sizeof (ctf_array_t));
708 1.1.1.2 christos
709 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
710 1.1 christos dtd->dtd_data.ctt_size = 0;
711 1.1.1.2 christos cta.cta_contents = (uint32_t) arp->ctr_contents;
712 1.1.1.2 christos cta.cta_index = (uint32_t) arp->ctr_index;
713 1.1.1.2 christos cta.cta_nelems = arp->ctr_nelems;
714 1.1.1.2 christos memcpy (dtd->dtd_vlen, &cta, sizeof (ctf_array_t));
715 1.1 christos
716 1.1 christos return type;
717 1.1 christos }
718 1.1 christos
719 1.1 christos int
720 1.1.1.2 christos ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
721 1.1 christos {
722 1.1 christos ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
723 1.1.1.2 christos ctf_array_t *vlen;
724 1.1 christos
725 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
726 1.1 christos return (ctf_set_errno (fp, ECTF_RDONLY));
727 1.1 christos
728 1.1 christos if (dtd == NULL
729 1.1 christos || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
730 1.1 christos return (ctf_set_errno (fp, ECTF_BADID));
731 1.1 christos
732 1.1.1.2 christos vlen = (ctf_array_t *) dtd->dtd_vlen;
733 1.1 christos fp->ctf_flags |= LCTF_DIRTY;
734 1.1.1.2 christos vlen->cta_contents = (uint32_t) arp->ctr_contents;
735 1.1.1.2 christos vlen->cta_index = (uint32_t) arp->ctr_index;
736 1.1.1.2 christos vlen->cta_nelems = arp->ctr_nelems;
737 1.1 christos
738 1.1 christos return 0;
739 1.1 christos }
740 1.1 christos
741 1.1 christos ctf_id_t
742 1.1.1.2 christos ctf_add_function (ctf_dict_t *fp, uint32_t flag,
743 1.1 christos const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
744 1.1 christos {
745 1.1 christos ctf_dtdef_t *dtd;
746 1.1 christos ctf_id_t type;
747 1.1 christos uint32_t vlen;
748 1.1.1.2 christos uint32_t *vdat;
749 1.1.1.2 christos ctf_dict_t *tmp = fp;
750 1.1.1.2 christos size_t initial_vlen;
751 1.1 christos size_t i;
752 1.1 christos
753 1.1.1.2 christos if (!(fp->ctf_flags & LCTF_RDWR))
754 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_RDONLY));
755 1.1.1.2 christos
756 1.1 christos if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
757 1.1 christos || (ctc->ctc_argc != 0 && argv == NULL))
758 1.1 christos return (ctf_set_errno (fp, EINVAL));
759 1.1 christos
760 1.1 christos vlen = ctc->ctc_argc;
761 1.1 christos if (ctc->ctc_flags & CTF_FUNC_VARARG)
762 1.1 christos vlen++; /* Add trailing zero to indicate varargs (see below). */
763 1.1 christos
764 1.1 christos if (ctc->ctc_return != 0
765 1.1 christos && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
766 1.1.1.2 christos return CTF_ERR; /* errno is set for us. */
767 1.1 christos
768 1.1 christos if (vlen > CTF_MAX_VLEN)
769 1.1 christos return (ctf_set_errno (fp, EOVERFLOW));
770 1.1 christos
771 1.1.1.2 christos /* One word extra allocated for padding for 4-byte alignment if need be.
772 1.1.1.2 christos Not reflected in vlen: we don't want to copy anything into it, and
773 1.1.1.2 christos it's in addition to (e.g.) the trailing 0 indicating varargs. */
774 1.1.1.2 christos
775 1.1.1.2 christos initial_vlen = (sizeof (uint32_t) * (vlen + (vlen & 1)));
776 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
777 1.1.1.2 christos initial_vlen, &dtd)) == CTF_ERR)
778 1.1.1.2 christos return CTF_ERR; /* errno is set for us. */
779 1.1.1.2 christos
780 1.1.1.2 christos vdat = (uint32_t *) dtd->dtd_vlen;
781 1.1 christos
782 1.1 christos for (i = 0; i < ctc->ctc_argc; i++)
783 1.1 christos {
784 1.1 christos tmp = fp;
785 1.1 christos if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
786 1.1.1.2 christos return CTF_ERR; /* errno is set for us. */
787 1.1 christos vdat[i] = (uint32_t) argv[i];
788 1.1 christos }
789 1.1 christos
790 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
791 1.1 christos dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
792 1.1 christos
793 1.1 christos if (ctc->ctc_flags & CTF_FUNC_VARARG)
794 1.1 christos vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
795 1.1 christos
796 1.1 christos return type;
797 1.1 christos }
798 1.1 christos
799 1.1 christos ctf_id_t
800 1.1.1.2 christos ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
801 1.1 christos size_t size)
802 1.1 christos {
803 1.1 christos ctf_dtdef_t *dtd;
804 1.1 christos ctf_id_t type = 0;
805 1.1.1.2 christos size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
806 1.1 christos
807 1.1 christos /* Promote root-visible forwards to structs. */
808 1.1 christos if (name != NULL)
809 1.1 christos type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
810 1.1 christos
811 1.1 christos if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
812 1.1 christos dtd = ctf_dtd_lookup (fp, type);
813 1.1 christos else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
814 1.1.1.2 christos initial_vlen, &dtd)) == CTF_ERR)
815 1.1 christos return CTF_ERR; /* errno is set for us. */
816 1.1 christos
817 1.1.1.2 christos /* Forwards won't have any vlen yet. */
818 1.1.1.2 christos if (dtd->dtd_vlen_alloc == 0)
819 1.1 christos {
820 1.1.1.2 christos if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
821 1.1.1.2 christos return (ctf_set_errno (fp, ENOMEM));
822 1.1.1.2 christos dtd->dtd_vlen_alloc = initial_vlen;
823 1.1 christos }
824 1.1.1.2 christos
825 1.1.1.2 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
826 1.1.1.2 christos dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
827 1.1.1.2 christos dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
828 1.1.1.2 christos dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
829 1.1 christos
830 1.1 christos return type;
831 1.1 christos }
832 1.1 christos
833 1.1 christos ctf_id_t
834 1.1.1.2 christos ctf_add_struct (ctf_dict_t *fp, uint32_t flag, const char *name)
835 1.1 christos {
836 1.1 christos return (ctf_add_struct_sized (fp, flag, name, 0));
837 1.1 christos }
838 1.1 christos
839 1.1 christos ctf_id_t
840 1.1.1.2 christos ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
841 1.1 christos size_t size)
842 1.1 christos {
843 1.1 christos ctf_dtdef_t *dtd;
844 1.1 christos ctf_id_t type = 0;
845 1.1.1.2 christos size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
846 1.1 christos
847 1.1 christos /* Promote root-visible forwards to unions. */
848 1.1 christos if (name != NULL)
849 1.1 christos type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
850 1.1 christos
851 1.1 christos if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
852 1.1 christos dtd = ctf_dtd_lookup (fp, type);
853 1.1 christos else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
854 1.1.1.2 christos initial_vlen, &dtd)) == CTF_ERR)
855 1.1 christos return CTF_ERR; /* errno is set for us */
856 1.1 christos
857 1.1.1.2 christos /* Forwards won't have any vlen yet. */
858 1.1.1.2 christos if (dtd->dtd_vlen_alloc == 0)
859 1.1 christos {
860 1.1.1.2 christos if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
861 1.1.1.2 christos return (ctf_set_errno (fp, ENOMEM));
862 1.1.1.2 christos dtd->dtd_vlen_alloc = initial_vlen;
863 1.1 christos }
864 1.1.1.2 christos
865 1.1.1.2 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
866 1.1.1.2 christos dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
867 1.1.1.2 christos dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
868 1.1.1.2 christos dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
869 1.1 christos
870 1.1 christos return type;
871 1.1 christos }
872 1.1 christos
873 1.1 christos ctf_id_t
874 1.1.1.2 christos ctf_add_union (ctf_dict_t *fp, uint32_t flag, const char *name)
875 1.1 christos {
876 1.1 christos return (ctf_add_union_sized (fp, flag, name, 0));
877 1.1 christos }
878 1.1 christos
879 1.1 christos ctf_id_t
880 1.1.1.2 christos ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name)
881 1.1 christos {
882 1.1 christos ctf_dtdef_t *dtd;
883 1.1 christos ctf_id_t type = 0;
884 1.1.1.2 christos size_t initial_vlen = sizeof (ctf_enum_t) * INITIAL_VLEN;
885 1.1 christos
886 1.1 christos /* Promote root-visible forwards to enums. */
887 1.1 christos if (name != NULL)
888 1.1 christos type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
889 1.1 christos
890 1.1 christos if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
891 1.1 christos dtd = ctf_dtd_lookup (fp, type);
892 1.1 christos else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
893 1.1.1.2 christos initial_vlen, &dtd)) == CTF_ERR)
894 1.1 christos return CTF_ERR; /* errno is set for us. */
895 1.1 christos
896 1.1.1.2 christos /* Forwards won't have any vlen yet. */
897 1.1.1.2 christos if (dtd->dtd_vlen_alloc == 0)
898 1.1.1.2 christos {
899 1.1.1.2 christos if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
900 1.1.1.2 christos return (ctf_set_errno (fp, ENOMEM));
901 1.1.1.2 christos dtd->dtd_vlen_alloc = initial_vlen;
902 1.1.1.2 christos }
903 1.1.1.2 christos
904 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
905 1.1 christos dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
906 1.1 christos
907 1.1 christos return type;
908 1.1 christos }
909 1.1 christos
910 1.1 christos ctf_id_t
911 1.1.1.2 christos ctf_add_enum_encoded (ctf_dict_t *fp, uint32_t flag, const char *name,
912 1.1 christos const ctf_encoding_t *ep)
913 1.1 christos {
914 1.1 christos ctf_id_t type = 0;
915 1.1 christos
916 1.1 christos /* First, create the enum if need be, using most of the same machinery as
917 1.1 christos ctf_add_enum(), to ensure that we do not allow things past that are not
918 1.1 christos enums or forwards to them. (This includes other slices: you cannot slice a
919 1.1 christos slice, which would be a useless thing to do anyway.) */
920 1.1 christos
921 1.1 christos if (name != NULL)
922 1.1 christos type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
923 1.1 christos
924 1.1 christos if (type != 0)
925 1.1 christos {
926 1.1 christos if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
927 1.1 christos (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
928 1.1 christos return (ctf_set_errno (fp, ECTF_NOTINTFP));
929 1.1 christos }
930 1.1 christos else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
931 1.1 christos return CTF_ERR; /* errno is set for us. */
932 1.1 christos
933 1.1 christos /* Now attach a suitable slice to it. */
934 1.1 christos
935 1.1 christos return ctf_add_slice (fp, flag, type, ep);
936 1.1 christos }
937 1.1 christos
938 1.1 christos ctf_id_t
939 1.1.1.2 christos ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name,
940 1.1 christos uint32_t kind)
941 1.1 christos {
942 1.1 christos ctf_dtdef_t *dtd;
943 1.1 christos ctf_id_t type = 0;
944 1.1 christos
945 1.1 christos if (!ctf_forwardable_kind (kind))
946 1.1 christos return (ctf_set_errno (fp, ECTF_NOTSUE));
947 1.1 christos
948 1.1.1.2 christos if (name == NULL || name[0] == '\0')
949 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_NONAME));
950 1.1.1.2 christos
951 1.1 christos /* If the type is already defined or exists as a forward tag, just
952 1.1 christos return the ctf_id_t of the existing definition. */
953 1.1 christos
954 1.1.1.2 christos type = ctf_lookup_by_rawname (fp, kind, name);
955 1.1 christos
956 1.1 christos if (type)
957 1.1 christos return type;
958 1.1 christos
959 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, name, kind, 0, &dtd)) == CTF_ERR)
960 1.1 christos return CTF_ERR; /* errno is set for us. */
961 1.1 christos
962 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
963 1.1 christos dtd->dtd_data.ctt_type = kind;
964 1.1 christos
965 1.1 christos return type;
966 1.1 christos }
967 1.1 christos
968 1.1 christos ctf_id_t
969 1.1.1.2 christos ctf_add_unknown (ctf_dict_t *fp, uint32_t flag, const char *name)
970 1.1.1.2 christos {
971 1.1.1.2 christos ctf_dtdef_t *dtd;
972 1.1.1.2 christos ctf_id_t type = 0;
973 1.1.1.2 christos
974 1.1.1.2 christos /* If a type is already defined with this name, error (if not CTF_K_UNKNOWN)
975 1.1.1.2 christos or just return it. */
976 1.1.1.2 christos
977 1.1.1.2 christos if (name != NULL && name[0] != '\0' && flag == CTF_ADD_ROOT
978 1.1.1.2 christos && (type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name)))
979 1.1.1.2 christos {
980 1.1.1.2 christos if (ctf_type_kind (fp, type) == CTF_K_UNKNOWN)
981 1.1.1.2 christos return type;
982 1.1.1.2 christos else
983 1.1.1.2 christos {
984 1.1.1.2 christos ctf_err_warn (fp, 1, ECTF_CONFLICT,
985 1.1.1.2 christos _("ctf_add_unknown: cannot add unknown type "
986 1.1.1.2 christos "named %s: type of this name already defined"),
987 1.1.1.2 christos name ? name : _("(unnamed type)"));
988 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_CONFLICT));
989 1.1.1.2 christos }
990 1.1.1.2 christos }
991 1.1.1.2 christos
992 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNKNOWN, 0, &dtd)) == CTF_ERR)
993 1.1.1.2 christos return CTF_ERR; /* errno is set for us. */
994 1.1.1.2 christos
995 1.1.1.2 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNKNOWN, flag, 0);
996 1.1.1.2 christos dtd->dtd_data.ctt_type = 0;
997 1.1.1.2 christos
998 1.1.1.2 christos return type;
999 1.1.1.2 christos }
1000 1.1.1.2 christos
1001 1.1.1.2 christos ctf_id_t
1002 1.1.1.2 christos ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name,
1003 1.1 christos ctf_id_t ref)
1004 1.1 christos {
1005 1.1 christos ctf_dtdef_t *dtd;
1006 1.1 christos ctf_id_t type;
1007 1.1.1.2 christos ctf_dict_t *tmp = fp;
1008 1.1 christos
1009 1.1 christos if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1010 1.1 christos return (ctf_set_errno (fp, EINVAL));
1011 1.1 christos
1012 1.1.1.2 christos if (name == NULL || name[0] == '\0')
1013 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_NONAME));
1014 1.1.1.2 christos
1015 1.1 christos if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
1016 1.1 christos return CTF_ERR; /* errno is set for us. */
1017 1.1 christos
1018 1.1.1.2 christos if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF, 0,
1019 1.1 christos &dtd)) == CTF_ERR)
1020 1.1 christos return CTF_ERR; /* errno is set for us. */
1021 1.1 christos
1022 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1023 1.1 christos dtd->dtd_data.ctt_type = (uint32_t) ref;
1024 1.1 christos
1025 1.1 christos return type;
1026 1.1 christos }
1027 1.1 christos
1028 1.1 christos ctf_id_t
1029 1.1.1.2 christos ctf_add_volatile (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1030 1.1 christos {
1031 1.1 christos return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1032 1.1 christos }
1033 1.1 christos
1034 1.1 christos ctf_id_t
1035 1.1.1.2 christos ctf_add_const (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1036 1.1 christos {
1037 1.1 christos return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1038 1.1 christos }
1039 1.1 christos
1040 1.1 christos ctf_id_t
1041 1.1.1.2 christos ctf_add_restrict (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1042 1.1 christos {
1043 1.1 christos return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1044 1.1 christos }
1045 1.1 christos
1046 1.1 christos int
1047 1.1.1.2 christos ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name,
1048 1.1 christos int value)
1049 1.1 christos {
1050 1.1 christos ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1051 1.1.1.2 christos unsigned char *old_vlen;
1052 1.1.1.2 christos ctf_enum_t *en;
1053 1.1.1.2 christos size_t i;
1054 1.1 christos
1055 1.1 christos uint32_t kind, vlen, root;
1056 1.1 christos
1057 1.1 christos if (name == NULL)
1058 1.1 christos return (ctf_set_errno (fp, EINVAL));
1059 1.1 christos
1060 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
1061 1.1 christos return (ctf_set_errno (fp, ECTF_RDONLY));
1062 1.1 christos
1063 1.1 christos if (dtd == NULL)
1064 1.1 christos return (ctf_set_errno (fp, ECTF_BADID));
1065 1.1 christos
1066 1.1 christos kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1067 1.1 christos root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1068 1.1 christos vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1069 1.1 christos
1070 1.1 christos if (kind != CTF_K_ENUM)
1071 1.1 christos return (ctf_set_errno (fp, ECTF_NOTENUM));
1072 1.1 christos
1073 1.1 christos if (vlen == CTF_MAX_VLEN)
1074 1.1 christos return (ctf_set_errno (fp, ECTF_DTFULL));
1075 1.1 christos
1076 1.1.1.2 christos old_vlen = dtd->dtd_vlen;
1077 1.1.1.2 christos if (ctf_grow_vlen (fp, dtd, sizeof (ctf_enum_t) * (vlen + 1)) < 0)
1078 1.1.1.2 christos return -1; /* errno is set for us. */
1079 1.1.1.2 christos en = (ctf_enum_t *) dtd->dtd_vlen;
1080 1.1.1.2 christos
1081 1.1.1.2 christos if (dtd->dtd_vlen != old_vlen)
1082 1.1 christos {
1083 1.1.1.2 christos ptrdiff_t move = (signed char *) dtd->dtd_vlen - (signed char *) old_vlen;
1084 1.1 christos
1085 1.1.1.2 christos /* Remove pending refs in the old vlen region and reapply them. */
1086 1.1 christos
1087 1.1.1.2 christos for (i = 0; i < vlen; i++)
1088 1.1.1.2 christos ctf_str_move_pending (fp, &en[i].cte_name, move);
1089 1.1 christos }
1090 1.1 christos
1091 1.1.1.2 christos for (i = 0; i < vlen; i++)
1092 1.1.1.2 christos if (strcmp (ctf_strptr (fp, en[i].cte_name), name) == 0)
1093 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_DUPLICATE));
1094 1.1.1.2 christos
1095 1.1.1.2 christos en[i].cte_name = ctf_str_add_pending (fp, name, &en[i].cte_name);
1096 1.1.1.2 christos en[i].cte_value = value;
1097 1.1.1.2 christos
1098 1.1.1.2 christos if (en[i].cte_name == 0 && name != NULL && name[0] != '\0')
1099 1.1.1.2 christos return -1; /* errno is set for us. */
1100 1.1 christos
1101 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1102 1.1 christos
1103 1.1 christos fp->ctf_flags |= LCTF_DIRTY;
1104 1.1 christos
1105 1.1 christos return 0;
1106 1.1 christos }
1107 1.1 christos
1108 1.1 christos int
1109 1.1.1.2 christos ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1110 1.1 christos ctf_id_t type, unsigned long bit_offset)
1111 1.1 christos {
1112 1.1 christos ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1113 1.1 christos
1114 1.1 christos ssize_t msize, malign, ssize;
1115 1.1 christos uint32_t kind, vlen, root;
1116 1.1.1.2 christos size_t i;
1117 1.1.1.2 christos int is_incomplete = 0;
1118 1.1.1.2 christos unsigned char *old_vlen;
1119 1.1.1.2 christos ctf_lmember_t *memb;
1120 1.1 christos
1121 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
1122 1.1 christos return (ctf_set_errno (fp, ECTF_RDONLY));
1123 1.1 christos
1124 1.1 christos if (dtd == NULL)
1125 1.1 christos return (ctf_set_errno (fp, ECTF_BADID));
1126 1.1 christos
1127 1.1 christos if (name != NULL && name[0] == '\0')
1128 1.1 christos name = NULL;
1129 1.1 christos
1130 1.1 christos kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1131 1.1 christos root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1132 1.1 christos vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1133 1.1 christos
1134 1.1 christos if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1135 1.1 christos return (ctf_set_errno (fp, ECTF_NOTSOU));
1136 1.1 christos
1137 1.1 christos if (vlen == CTF_MAX_VLEN)
1138 1.1 christos return (ctf_set_errno (fp, ECTF_DTFULL));
1139 1.1 christos
1140 1.1.1.2 christos old_vlen = dtd->dtd_vlen;
1141 1.1.1.2 christos if (ctf_grow_vlen (fp, dtd, sizeof (ctf_lmember_t) * (vlen + 1)) < 0)
1142 1.1.1.2 christos return -1; /* errno is set for us. */
1143 1.1.1.2 christos memb = (ctf_lmember_t *) dtd->dtd_vlen;
1144 1.1.1.2 christos
1145 1.1.1.2 christos if (dtd->dtd_vlen != old_vlen)
1146 1.1.1.2 christos {
1147 1.1.1.2 christos ptrdiff_t move = (signed char *) dtd->dtd_vlen - (signed char *) old_vlen;
1148 1.1.1.2 christos
1149 1.1.1.2 christos /* Remove pending refs in the old vlen region and reapply them. */
1150 1.1.1.2 christos
1151 1.1.1.2 christos for (i = 0; i < vlen; i++)
1152 1.1.1.2 christos ctf_str_move_pending (fp, &memb[i].ctlm_name, move);
1153 1.1.1.2 christos }
1154 1.1.1.2 christos
1155 1.1 christos if (name != NULL)
1156 1.1 christos {
1157 1.1.1.2 christos for (i = 0; i < vlen; i++)
1158 1.1.1.2 christos if (strcmp (ctf_strptr (fp, memb[i].ctlm_name), name) == 0)
1159 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_DUPLICATE));
1160 1.1 christos }
1161 1.1 christos
1162 1.1 christos if ((msize = ctf_type_size (fp, type)) < 0 ||
1163 1.1 christos (malign = ctf_type_align (fp, type)) < 0)
1164 1.1 christos {
1165 1.1 christos /* The unimplemented type, and any type that resolves to it, has no size
1166 1.1 christos and no alignment: it can correspond to any number of compiler-inserted
1167 1.1.1.2 christos types. We allow incomplete types through since they are routinely
1168 1.1.1.2 christos added to the ends of structures, and can even be added elsewhere in
1169 1.1.1.2 christos structures by the deduplicator. They are assumed to be zero-size with
1170 1.1.1.2 christos no alignment: this is often wrong, but problems can be avoided in this
1171 1.1.1.2 christos case by explicitly specifying the size of the structure via the _sized
1172 1.1.1.2 christos functions. The deduplicator always does this. */
1173 1.1 christos
1174 1.1.1.2 christos msize = 0;
1175 1.1.1.2 christos malign = 0;
1176 1.1 christos if (ctf_errno (fp) == ECTF_NONREPRESENTABLE)
1177 1.1.1.2 christos ctf_set_errno (fp, 0);
1178 1.1.1.2 christos else if (ctf_errno (fp) == ECTF_INCOMPLETE)
1179 1.1.1.2 christos is_incomplete = 1;
1180 1.1 christos else
1181 1.1 christos return -1; /* errno is set for us. */
1182 1.1 christos }
1183 1.1 christos
1184 1.1.1.2 christos memb[vlen].ctlm_name = ctf_str_add_pending (fp, name, &memb[vlen].ctlm_name);
1185 1.1.1.2 christos memb[vlen].ctlm_type = type;
1186 1.1.1.2 christos if (memb[vlen].ctlm_name == 0 && name != NULL && name[0] != '\0')
1187 1.1.1.2 christos return -1; /* errno is set for us. */
1188 1.1 christos
1189 1.1 christos if (kind == CTF_K_STRUCT && vlen != 0)
1190 1.1 christos {
1191 1.1 christos if (bit_offset == (unsigned long) - 1)
1192 1.1 christos {
1193 1.1 christos /* Natural alignment. */
1194 1.1 christos
1195 1.1.1.2 christos ctf_id_t ltype = ctf_type_resolve (fp, memb[vlen - 1].ctlm_type);
1196 1.1.1.2 christos size_t off = CTF_LMEM_OFFSET(&memb[vlen - 1]);
1197 1.1 christos
1198 1.1 christos ctf_encoding_t linfo;
1199 1.1 christos ssize_t lsize;
1200 1.1 christos
1201 1.1 christos /* Propagate any error from ctf_type_resolve. If the last member was
1202 1.1 christos of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we
1203 1.1 christos cannot insert right after such a member without explicit offset
1204 1.1 christos specification, because its alignment and size is not known. */
1205 1.1 christos if (ltype == CTF_ERR)
1206 1.1.1.2 christos return -1; /* errno is set for us. */
1207 1.1.1.2 christos
1208 1.1.1.2 christos if (is_incomplete)
1209 1.1 christos {
1210 1.1.1.2 christos ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
1211 1.1.1.2 christos _("ctf_add_member_offset: cannot add member %s of "
1212 1.1.1.2 christos "incomplete type %lx to struct %lx without "
1213 1.1.1.2 christos "specifying explicit offset\n"),
1214 1.1.1.2 christos name ? name : _("(unnamed member)"), type, souid);
1215 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_INCOMPLETE));
1216 1.1 christos }
1217 1.1 christos
1218 1.1 christos if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1219 1.1 christos off += linfo.cte_bits;
1220 1.1 christos else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1221 1.1 christos off += lsize * CHAR_BIT;
1222 1.1.1.2 christos else if (lsize == -1 && ctf_errno (fp) == ECTF_INCOMPLETE)
1223 1.1.1.2 christos {
1224 1.1.1.2 christos const char *lname = ctf_strraw (fp, memb[vlen - 1].ctlm_name);
1225 1.1.1.2 christos
1226 1.1.1.2 christos ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
1227 1.1.1.2 christos _("ctf_add_member_offset: cannot add member %s of "
1228 1.1.1.2 christos "type %lx to struct %lx without specifying "
1229 1.1.1.2 christos "explicit offset after member %s of type %lx, "
1230 1.1.1.2 christos "which is an incomplete type\n"),
1231 1.1.1.2 christos name ? name : _("(unnamed member)"), type, souid,
1232 1.1.1.2 christos lname ? lname : _("(unnamed member)"), ltype);
1233 1.1.1.2 christos return -1; /* errno is set for us. */
1234 1.1.1.2 christos }
1235 1.1 christos
1236 1.1 christos /* Round up the offset of the end of the last member to
1237 1.1 christos the next byte boundary, convert 'off' to bytes, and
1238 1.1 christos then round it up again to the next multiple of the
1239 1.1 christos alignment required by the new member. Finally,
1240 1.1 christos convert back to bits and store the result in
1241 1.1 christos dmd_offset. Technically we could do more efficient
1242 1.1 christos packing if the new member is a bit-field, but we're
1243 1.1 christos the "compiler" and ANSI says we can do as we choose. */
1244 1.1 christos
1245 1.1 christos off = roundup (off, CHAR_BIT) / CHAR_BIT;
1246 1.1 christos off = roundup (off, MAX (malign, 1));
1247 1.1.1.2 christos memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (off * CHAR_BIT);
1248 1.1.1.2 christos memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (off * CHAR_BIT);
1249 1.1 christos ssize = off + msize;
1250 1.1 christos }
1251 1.1 christos else
1252 1.1 christos {
1253 1.1 christos /* Specified offset in bits. */
1254 1.1 christos
1255 1.1.1.2 christos memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (bit_offset);
1256 1.1.1.2 christos memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (bit_offset);
1257 1.1 christos ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1258 1.1 christos ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
1259 1.1 christos }
1260 1.1 christos }
1261 1.1 christos else
1262 1.1 christos {
1263 1.1.1.2 christos memb[vlen].ctlm_offsethi = 0;
1264 1.1.1.2 christos memb[vlen].ctlm_offsetlo = 0;
1265 1.1 christos ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1266 1.1 christos ssize = MAX (ssize, msize);
1267 1.1 christos }
1268 1.1 christos
1269 1.1.1.2 christos dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1270 1.1.1.2 christos dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1271 1.1.1.2 christos dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1272 1.1 christos dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1273 1.1 christos
1274 1.1 christos fp->ctf_flags |= LCTF_DIRTY;
1275 1.1 christos return 0;
1276 1.1 christos }
1277 1.1 christos
1278 1.1 christos int
1279 1.1.1.2 christos ctf_add_member_encoded (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1280 1.1 christos ctf_id_t type, unsigned long bit_offset,
1281 1.1 christos const ctf_encoding_t encoding)
1282 1.1 christos {
1283 1.1 christos ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1284 1.1 christos int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1285 1.1 christos int otype = type;
1286 1.1 christos
1287 1.1 christos if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1288 1.1 christos return (ctf_set_errno (fp, ECTF_NOTINTFP));
1289 1.1 christos
1290 1.1 christos if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
1291 1.1 christos return -1; /* errno is set for us. */
1292 1.1 christos
1293 1.1 christos return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1294 1.1 christos }
1295 1.1 christos
1296 1.1 christos int
1297 1.1.1.2 christos ctf_add_member (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1298 1.1 christos ctf_id_t type)
1299 1.1 christos {
1300 1.1 christos return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1301 1.1 christos }
1302 1.1 christos
1303 1.1 christos int
1304 1.1.1.2 christos ctf_add_variable (ctf_dict_t *fp, const char *name, ctf_id_t ref)
1305 1.1 christos {
1306 1.1 christos ctf_dvdef_t *dvd;
1307 1.1.1.2 christos ctf_dict_t *tmp = fp;
1308 1.1 christos
1309 1.1 christos if (!(fp->ctf_flags & LCTF_RDWR))
1310 1.1 christos return (ctf_set_errno (fp, ECTF_RDONLY));
1311 1.1 christos
1312 1.1 christos if (ctf_dvd_lookup (fp, name) != NULL)
1313 1.1 christos return (ctf_set_errno (fp, ECTF_DUPLICATE));
1314 1.1 christos
1315 1.1 christos if (ctf_lookup_by_id (&tmp, ref) == NULL)
1316 1.1 christos return -1; /* errno is set for us. */
1317 1.1 christos
1318 1.1 christos /* Make sure this type is representable. */
1319 1.1 christos if ((ctf_type_resolve (fp, ref) == CTF_ERR)
1320 1.1 christos && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
1321 1.1 christos return -1;
1322 1.1 christos
1323 1.1 christos if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
1324 1.1 christos return (ctf_set_errno (fp, EAGAIN));
1325 1.1 christos
1326 1.1 christos if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
1327 1.1 christos {
1328 1.1 christos free (dvd);
1329 1.1 christos return (ctf_set_errno (fp, EAGAIN));
1330 1.1 christos }
1331 1.1 christos dvd->dvd_type = ref;
1332 1.1 christos dvd->dvd_snapshots = fp->ctf_snapshots;
1333 1.1 christos
1334 1.1 christos if (ctf_dvd_insert (fp, dvd) < 0)
1335 1.1 christos {
1336 1.1 christos free (dvd->dvd_name);
1337 1.1 christos free (dvd);
1338 1.1 christos return -1; /* errno is set for us. */
1339 1.1 christos }
1340 1.1 christos
1341 1.1 christos fp->ctf_flags |= LCTF_DIRTY;
1342 1.1 christos return 0;
1343 1.1 christos }
1344 1.1 christos
1345 1.1.1.2 christos int
1346 1.1.1.2 christos ctf_add_funcobjt_sym (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
1347 1.1.1.2 christos {
1348 1.1.1.2 christos ctf_dict_t *tmp = fp;
1349 1.1.1.2 christos char *dupname;
1350 1.1.1.2 christos ctf_dynhash_t *h = is_function ? fp->ctf_funchash : fp->ctf_objthash;
1351 1.1.1.2 christos
1352 1.1.1.2 christos if (!(fp->ctf_flags & LCTF_RDWR))
1353 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_RDONLY));
1354 1.1.1.2 christos
1355 1.1.1.2 christos if (ctf_dynhash_lookup (fp->ctf_objthash, name) != NULL ||
1356 1.1.1.2 christos ctf_dynhash_lookup (fp->ctf_funchash, name) != NULL)
1357 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_DUPLICATE));
1358 1.1.1.2 christos
1359 1.1.1.2 christos if (ctf_lookup_by_id (&tmp, id) == NULL)
1360 1.1.1.2 christos return -1; /* errno is set for us. */
1361 1.1.1.2 christos
1362 1.1.1.2 christos if (is_function && ctf_type_kind (fp, id) != CTF_K_FUNCTION)
1363 1.1.1.2 christos return (ctf_set_errno (fp, ECTF_NOTFUNC));
1364 1.1.1.2 christos
1365 1.1.1.2 christos if ((dupname = strdup (name)) == NULL)
1366 1.1.1.2 christos return (ctf_set_errno (fp, ENOMEM));
1367 1.1.1.2 christos
1368 1.1.1.2 christos if (ctf_dynhash_insert (h, dupname, (void *) (uintptr_t) id) < 0)
1369 1.1.1.2 christos {
1370 1.1.1.2 christos free (dupname);
1371 1.1.1.2 christos return (ctf_set_errno (fp, ENOMEM));
1372 1.1.1.2 christos }
1373 1.1.1.2 christos return 0;
1374 1.1.1.2 christos }
1375 1.1.1.2 christos
1376 1.1.1.2 christos int
1377 1.1.1.2 christos ctf_add_objt_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
1378 1.1.1.2 christos {
1379 1.1.1.2 christos return (ctf_add_funcobjt_sym (fp, 0, name, id));
1380 1.1.1.2 christos }
1381 1.1.1.2 christos
1382 1.1.1.2 christos int
1383 1.1.1.2 christos ctf_add_func_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
1384 1.1.1.2 christos {
1385 1.1.1.2 christos return (ctf_add_funcobjt_sym (fp, 1, name, id));
1386 1.1.1.2 christos }
1387 1.1.1.2 christos
1388 1.1 christos typedef struct ctf_bundle
1389 1.1 christos {
1390 1.1.1.2 christos ctf_dict_t *ctb_dict; /* CTF dict handle. */
1391 1.1 christos ctf_id_t ctb_type; /* CTF type identifier. */
1392 1.1 christos ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any). */
1393 1.1 christos } ctf_bundle_t;
1394 1.1 christos
1395 1.1 christos static int
1396 1.1 christos enumcmp (const char *name, int value, void *arg)
1397 1.1 christos {
1398 1.1 christos ctf_bundle_t *ctb = arg;
1399 1.1 christos int bvalue;
1400 1.1 christos
1401 1.1.1.2 christos if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
1402 1.1 christos {
1403 1.1.1.2 christos ctf_err_warn (ctb->ctb_dict, 0, 0,
1404 1.1 christos _("conflict due to enum %s iteration error"), name);
1405 1.1 christos return 1;
1406 1.1 christos }
1407 1.1 christos if (value != bvalue)
1408 1.1 christos {
1409 1.1.1.2 christos ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
1410 1.1 christos _("conflict due to enum value change: %i versus %i"),
1411 1.1 christos value, bvalue);
1412 1.1 christos return 1;
1413 1.1 christos }
1414 1.1 christos return 0;
1415 1.1 christos }
1416 1.1 christos
1417 1.1 christos static int
1418 1.1 christos enumadd (const char *name, int value, void *arg)
1419 1.1 christos {
1420 1.1 christos ctf_bundle_t *ctb = arg;
1421 1.1 christos
1422 1.1.1.2 christos return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
1423 1.1 christos name, value) < 0);
1424 1.1 christos }
1425 1.1 christos
1426 1.1 christos static int
1427 1.1 christos membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1428 1.1 christos void *arg)
1429 1.1 christos {
1430 1.1 christos ctf_bundle_t *ctb = arg;
1431 1.1 christos ctf_membinfo_t ctm;
1432 1.1 christos
1433 1.1 christos /* Don't check nameless members (e.g. anonymous structs/unions) against each
1434 1.1 christos other. */
1435 1.1 christos if (name[0] == 0)
1436 1.1 christos return 0;
1437 1.1 christos
1438 1.1.1.2 christos if (ctf_member_info (ctb->ctb_dict, ctb->ctb_type, name, &ctm) < 0)
1439 1.1 christos {
1440 1.1.1.2 christos ctf_err_warn (ctb->ctb_dict, 0, 0,
1441 1.1 christos _("conflict due to struct member %s iteration error"),
1442 1.1 christos name);
1443 1.1 christos return 1;
1444 1.1 christos }
1445 1.1 christos if (ctm.ctm_offset != offset)
1446 1.1 christos {
1447 1.1.1.2 christos ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
1448 1.1 christos _("conflict due to struct member %s offset change: "
1449 1.1 christos "%lx versus %lx"),
1450 1.1 christos name, ctm.ctm_offset, offset);
1451 1.1 christos return 1;
1452 1.1 christos }
1453 1.1 christos return 0;
1454 1.1 christos }
1455 1.1 christos
1456 1.1.1.2 christos /* Record the correspondence between a source and ctf_add_type()-added
1457 1.1.1.2 christos destination type: both types are translated into parent type IDs if need be,
1458 1.1.1.2 christos so they relate to the actual dictionary they are in. Outside controlled
1459 1.1.1.2 christos circumstances (like linking) it is probably not useful to do more than
1460 1.1.1.2 christos compare these pointers, since there is nothing stopping the user closing the
1461 1.1.1.2 christos source dict whenever they want to.
1462 1.1.1.2 christos
1463 1.1.1.2 christos Our OOM handling here is just to not do anything, because this is called deep
1464 1.1.1.2 christos enough in the call stack that doing anything useful is painfully difficult:
1465 1.1.1.2 christos the worst consequence if we do OOM is a bit of type duplication anyway. */
1466 1.1.1.2 christos
1467 1.1.1.2 christos static void
1468 1.1.1.2 christos ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type,
1469 1.1.1.2 christos ctf_dict_t *dst_fp, ctf_id_t dst_type)
1470 1.1 christos {
1471 1.1.1.2 christos if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
1472 1.1.1.2 christos src_fp = src_fp->ctf_parent;
1473 1.1 christos
1474 1.1.1.2 christos src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
1475 1.1 christos
1476 1.1.1.2 christos if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
1477 1.1.1.2 christos dst_fp = dst_fp->ctf_parent;
1478 1.1.1.2 christos
1479 1.1.1.2 christos dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
1480 1.1.1.2 christos
1481 1.1.1.2 christos if (dst_fp->ctf_link_type_mapping == NULL)
1482 1.1 christos {
1483 1.1.1.2 christos ctf_hash_fun f = ctf_hash_type_key;
1484 1.1.1.2 christos ctf_hash_eq_fun e = ctf_hash_eq_type_key;
1485 1.1.1.2 christos
1486 1.1.1.2 christos if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
1487 1.1.1.2 christos NULL)) == NULL)
1488 1.1.1.2 christos return;
1489 1.1 christos }
1490 1.1 christos
1491 1.1.1.2 christos ctf_link_type_key_t *key;
1492 1.1.1.2 christos key = calloc (1, sizeof (struct ctf_link_type_key));
1493 1.1.1.2 christos if (!key)
1494 1.1.1.2 christos return;
1495 1.1 christos
1496 1.1.1.2 christos key->cltk_fp = src_fp;
1497 1.1.1.2 christos key->cltk_idx = src_type;
1498 1.1 christos
1499 1.1.1.2 christos /* No OOM checking needed, because if this doesn't work the worst we'll do is
1500 1.1.1.2 christos add a few more duplicate types (which will probably run out of memory
1501 1.1.1.2 christos anyway). */
1502 1.1.1.2 christos ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
1503 1.1.1.2 christos (void *) (uintptr_t) dst_type);
1504 1.1 christos }
1505 1.1 christos
1506 1.1.1.2 christos /* Look up a type mapping: return 0 if none. The DST_FP is modified to point to
1507 1.1.1.2 christos the parent if need be. The ID returned is from the dst_fp's perspective. */
1508 1.1.1.2 christos static ctf_id_t
1509 1.1.1.2 christos ctf_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_dict_t **dst_fp)
1510 1.1.1.2 christos {
1511 1.1.1.2 christos ctf_link_type_key_t key;
1512 1.1.1.2 christos ctf_dict_t *target_fp = *dst_fp;
1513 1.1.1.2 christos ctf_id_t dst_type = 0;
1514 1.1.1.2 christos
1515 1.1.1.2 christos if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
1516 1.1.1.2 christos src_fp = src_fp->ctf_parent;
1517 1.1.1.2 christos
1518 1.1.1.2 christos src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
1519 1.1.1.2 christos key.cltk_fp = src_fp;
1520 1.1.1.2 christos key.cltk_idx = src_type;
1521 1.1.1.2 christos
1522 1.1.1.2 christos if (target_fp->ctf_link_type_mapping)
1523 1.1.1.2 christos dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
1524 1.1.1.2 christos &key);
1525 1.1.1.2 christos
1526 1.1.1.2 christos if (dst_type != 0)
1527 1.1.1.2 christos {
1528 1.1.1.2 christos dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
1529 1.1.1.2 christos target_fp->ctf_parent != NULL);
1530 1.1.1.2 christos *dst_fp = target_fp;
1531 1.1.1.2 christos return dst_type;
1532 1.1.1.2 christos }
1533 1.1.1.2 christos
1534 1.1.1.2 christos if (target_fp->ctf_parent)
1535 1.1.1.2 christos target_fp = target_fp->ctf_parent;
1536 1.1.1.2 christos else
1537 1.1.1.2 christos return 0;
1538 1.1.1.2 christos
1539 1.1.1.2 christos if (target_fp->ctf_link_type_mapping)
1540 1.1.1.2 christos dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
1541 1.1.1.2 christos &key);
1542 1.1.1.2 christos
1543 1.1.1.2 christos if (dst_type)
1544 1.1.1.2 christos dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
1545 1.1.1.2 christos target_fp->ctf_parent != NULL);
1546 1.1.1.2 christos
1547 1.1.1.2 christos *dst_fp = target_fp;
1548 1.1.1.2 christos return dst_type;
1549 1.1.1.2 christos }
1550 1.1.1.2 christos
1551 1.1.1.2 christos /* The ctf_add_type routine is used to copy a type from a source CTF dictionary
1552 1.1.1.2 christos to a dynamic destination dictionary. This routine operates recursively by
1553 1.1 christos following the source type's links and embedded member types. If the
1554 1.1.1.2 christos destination dict already contains a named type which has the same attributes,
1555 1.1.1.2 christos then we succeed and return this type but no changes occur. */
1556 1.1 christos static ctf_id_t
1557 1.1.1.2 christos ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type,
1558 1.1.1.2 christos ctf_dict_t *proc_tracking_fp)
1559 1.1 christos {
1560 1.1 christos ctf_id_t dst_type = CTF_ERR;
1561 1.1 christos uint32_t dst_kind = CTF_K_UNKNOWN;
1562 1.1.1.2 christos ctf_dict_t *tmp_fp = dst_fp;
1563 1.1 christos ctf_id_t tmp;
1564 1.1 christos
1565 1.1 christos const char *name;
1566 1.1 christos uint32_t kind, forward_kind, flag, vlen;
1567 1.1 christos
1568 1.1 christos const ctf_type_t *src_tp, *dst_tp;
1569 1.1 christos ctf_bundle_t src, dst;
1570 1.1 christos ctf_encoding_t src_en, dst_en;
1571 1.1 christos ctf_arinfo_t src_ar, dst_ar;
1572 1.1 christos
1573 1.1 christos ctf_funcinfo_t ctc;
1574 1.1 christos
1575 1.1 christos ctf_id_t orig_src_type = src_type;
1576 1.1 christos
1577 1.1 christos if (!(dst_fp->ctf_flags & LCTF_RDWR))
1578 1.1 christos return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1579 1.1 christos
1580 1.1 christos if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1581 1.1 christos return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1582 1.1 christos
1583 1.1 christos if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
1584 1.1 christos && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
1585 1.1 christos return (ctf_set_errno (dst_fp, ECTF_NONREPRESENTABLE));
1586 1.1 christos
1587 1.1 christos name = ctf_strptr (src_fp, src_tp->ctt_name);
1588 1.1 christos kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1589 1.1 christos flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1590 1.1 christos vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1591 1.1 christos
1592 1.1 christos /* If this is a type we are currently in the middle of adding, hand it
1593 1.1 christos straight back. (This lets us handle self-referential structures without
1594 1.1 christos considering forwards and empty structures the same as their completed
1595 1.1 christos forms.) */
1596 1.1 christos
1597 1.1 christos tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
1598 1.1 christos
1599 1.1 christos if (tmp != 0)
1600 1.1 christos {
1601 1.1 christos if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
1602 1.1 christos (void *) (uintptr_t) src_type))
1603 1.1 christos return tmp;
1604 1.1 christos
1605 1.1.1.2 christos /* If this type has already been added from this dictionary, and is the
1606 1.1.1.2 christos same kind and (if a struct or union) has the same number of members,
1607 1.1.1.2 christos hand it straight back. */
1608 1.1 christos
1609 1.1 christos if (ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
1610 1.1 christos {
1611 1.1 christos if (kind == CTF_K_STRUCT || kind == CTF_K_UNION
1612 1.1 christos || kind == CTF_K_ENUM)
1613 1.1 christos {
1614 1.1 christos if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
1615 1.1 christos if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
1616 1.1 christos return tmp;
1617 1.1 christos }
1618 1.1 christos else
1619 1.1 christos return tmp;
1620 1.1 christos }
1621 1.1 christos }
1622 1.1 christos
1623 1.1 christos forward_kind = kind;
1624 1.1 christos if (kind == CTF_K_FORWARD)
1625 1.1 christos forward_kind = src_tp->ctt_type;
1626 1.1 christos
1627 1.1.1.2 christos /* If the source type has a name and is a root type (visible at the top-level
1628 1.1.1.2 christos scope), lookup the name in the destination dictionary and verify that it is
1629 1.1.1.2 christos of the same kind before we do anything else. */
1630 1.1 christos
1631 1.1 christos if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1632 1.1 christos && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
1633 1.1 christos {
1634 1.1 christos dst_type = tmp;
1635 1.1 christos dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1636 1.1 christos }
1637 1.1 christos
1638 1.1 christos /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1639 1.1 christos unless dst_type is a forward declaration and src_type is a struct,
1640 1.1 christos union, or enum (i.e. the definition of the previous forward decl).
1641 1.1 christos
1642 1.1 christos We also allow addition in the opposite order (addition of a forward when a
1643 1.1 christos struct, union, or enum already exists), which is a NOP and returns the
1644 1.1 christos already-present struct, union, or enum. */
1645 1.1 christos
1646 1.1 christos if (dst_type != CTF_ERR && dst_kind != kind)
1647 1.1 christos {
1648 1.1 christos if (kind == CTF_K_FORWARD
1649 1.1 christos && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
1650 1.1 christos || dst_kind == CTF_K_UNION))
1651 1.1 christos {
1652 1.1 christos ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1653 1.1 christos return dst_type;
1654 1.1 christos }
1655 1.1 christos
1656 1.1 christos if (dst_kind != CTF_K_FORWARD
1657 1.1 christos || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1658 1.1 christos && kind != CTF_K_UNION))
1659 1.1 christos {
1660 1.1 christos ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1661 1.1.1.2 christos _("ctf_add_type: conflict for type %s: "
1662 1.1 christos "kinds differ, new: %i; old (ID %lx): %i"),
1663 1.1 christos name, kind, dst_type, dst_kind);
1664 1.1 christos return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1665 1.1 christos }
1666 1.1 christos }
1667 1.1 christos
1668 1.1 christos /* We take special action for an integer, float, or slice since it is
1669 1.1 christos described not only by its name but also its encoding. For integers,
1670 1.1 christos bit-fields exploit this degeneracy. */
1671 1.1 christos
1672 1.1 christos if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1673 1.1 christos {
1674 1.1 christos if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1675 1.1 christos return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1676 1.1 christos
1677 1.1 christos if (dst_type != CTF_ERR)
1678 1.1 christos {
1679 1.1.1.2 christos ctf_dict_t *fp = dst_fp;
1680 1.1 christos
1681 1.1 christos if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1682 1.1 christos return CTF_ERR;
1683 1.1 christos
1684 1.1 christos if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1685 1.1 christos return CTF_ERR; /* errno set for us. */
1686 1.1 christos
1687 1.1 christos if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1688 1.1 christos {
1689 1.1 christos /* The type that we found in the hash is also root-visible. If
1690 1.1 christos the two types match then use the existing one; otherwise,
1691 1.1 christos declare a conflict. Note: slices are not certain to match
1692 1.1 christos even if there is no conflict: we must check the contained type
1693 1.1 christos too. */
1694 1.1 christos
1695 1.1 christos if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1696 1.1 christos {
1697 1.1 christos if (kind != CTF_K_SLICE)
1698 1.1 christos {
1699 1.1 christos ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1700 1.1 christos return dst_type;
1701 1.1 christos }
1702 1.1 christos }
1703 1.1 christos else
1704 1.1 christos {
1705 1.1 christos return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1706 1.1 christos }
1707 1.1 christos }
1708 1.1 christos else
1709 1.1 christos {
1710 1.1 christos /* We found a non-root-visible type in the hash. If its encoding
1711 1.1 christos is the same, we can reuse it, unless it is a slice. */
1712 1.1 christos
1713 1.1 christos if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1714 1.1 christos {
1715 1.1 christos if (kind != CTF_K_SLICE)
1716 1.1 christos {
1717 1.1 christos ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1718 1.1 christos return dst_type;
1719 1.1 christos }
1720 1.1 christos }
1721 1.1 christos }
1722 1.1 christos }
1723 1.1 christos }
1724 1.1 christos
1725 1.1.1.2 christos src.ctb_dict = src_fp;
1726 1.1 christos src.ctb_type = src_type;
1727 1.1 christos src.ctb_dtd = NULL;
1728 1.1 christos
1729 1.1.1.2 christos dst.ctb_dict = dst_fp;
1730 1.1 christos dst.ctb_type = dst_type;
1731 1.1 christos dst.ctb_dtd = NULL;
1732 1.1 christos
1733 1.1 christos /* Now perform kind-specific processing. If dst_type is CTF_ERR, then we add
1734 1.1 christos a new type with the same properties as src_type to dst_fp. If dst_type is
1735 1.1 christos not CTF_ERR, then we verify that dst_type has the same attributes as
1736 1.1 christos src_type. We recurse for embedded references. Before we start, we note
1737 1.1 christos that we are processing this type, to prevent infinite recursion: we do not
1738 1.1 christos re-process any type that appears in this list. The list is emptied
1739 1.1 christos wholesale at the end of processing everything in this recursive stack. */
1740 1.1 christos
1741 1.1 christos if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
1742 1.1 christos (void *) (uintptr_t) src_type, (void *) 1) < 0)
1743 1.1 christos return ctf_set_errno (dst_fp, ENOMEM);
1744 1.1 christos
1745 1.1 christos switch (kind)
1746 1.1 christos {
1747 1.1 christos case CTF_K_INTEGER:
1748 1.1 christos /* If we found a match we will have either returned it or declared a
1749 1.1 christos conflict. */
1750 1.1 christos dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1751 1.1 christos break;
1752 1.1 christos
1753 1.1 christos case CTF_K_FLOAT:
1754 1.1 christos /* If we found a match we will have either returned it or declared a
1755 1.1 christos conflict. */
1756 1.1 christos dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1757 1.1 christos break;
1758 1.1 christos
1759 1.1 christos case CTF_K_SLICE:
1760 1.1 christos /* We have checked for conflicting encodings: now try to add the
1761 1.1 christos contained type. */
1762 1.1 christos src_type = ctf_type_reference (src_fp, src_type);
1763 1.1 christos src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1764 1.1 christos proc_tracking_fp);
1765 1.1 christos
1766 1.1 christos if (src_type == CTF_ERR)
1767 1.1 christos return CTF_ERR; /* errno is set for us. */
1768 1.1 christos
1769 1.1 christos dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1770 1.1 christos break;
1771 1.1 christos
1772 1.1 christos case CTF_K_POINTER:
1773 1.1 christos case CTF_K_VOLATILE:
1774 1.1 christos case CTF_K_CONST:
1775 1.1 christos case CTF_K_RESTRICT:
1776 1.1 christos src_type = ctf_type_reference (src_fp, src_type);
1777 1.1 christos src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1778 1.1 christos proc_tracking_fp);
1779 1.1 christos
1780 1.1 christos if (src_type == CTF_ERR)
1781 1.1 christos return CTF_ERR; /* errno is set for us. */
1782 1.1 christos
1783 1.1 christos dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1784 1.1 christos break;
1785 1.1 christos
1786 1.1 christos case CTF_K_ARRAY:
1787 1.1 christos if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
1788 1.1 christos return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1789 1.1 christos
1790 1.1 christos src_ar.ctr_contents =
1791 1.1 christos ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
1792 1.1 christos proc_tracking_fp);
1793 1.1 christos src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
1794 1.1 christos src_ar.ctr_index,
1795 1.1 christos proc_tracking_fp);
1796 1.1 christos src_ar.ctr_nelems = src_ar.ctr_nelems;
1797 1.1 christos
1798 1.1 christos if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1799 1.1 christos return CTF_ERR; /* errno is set for us. */
1800 1.1 christos
1801 1.1 christos if (dst_type != CTF_ERR)
1802 1.1 christos {
1803 1.1 christos if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1804 1.1 christos return CTF_ERR; /* errno is set for us. */
1805 1.1 christos
1806 1.1 christos if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1807 1.1 christos {
1808 1.1 christos ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1809 1.1 christos _("conflict for type %s against ID %lx: array info "
1810 1.1 christos "differs, old %lx/%lx/%x; new: %lx/%lx/%x"),
1811 1.1 christos name, dst_type, src_ar.ctr_contents,
1812 1.1 christos src_ar.ctr_index, src_ar.ctr_nelems,
1813 1.1 christos dst_ar.ctr_contents, dst_ar.ctr_index,
1814 1.1 christos dst_ar.ctr_nelems);
1815 1.1 christos return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1816 1.1 christos }
1817 1.1 christos }
1818 1.1 christos else
1819 1.1 christos dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1820 1.1 christos break;
1821 1.1 christos
1822 1.1 christos case CTF_K_FUNCTION:
1823 1.1 christos ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
1824 1.1 christos src_tp->ctt_type,
1825 1.1 christos proc_tracking_fp);
1826 1.1 christos ctc.ctc_argc = 0;
1827 1.1 christos ctc.ctc_flags = 0;
1828 1.1 christos
1829 1.1 christos if (ctc.ctc_return == CTF_ERR)
1830 1.1 christos return CTF_ERR; /* errno is set for us. */
1831 1.1 christos
1832 1.1 christos dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1833 1.1 christos break;
1834 1.1 christos
1835 1.1 christos case CTF_K_STRUCT:
1836 1.1 christos case CTF_K_UNION:
1837 1.1 christos {
1838 1.1.1.2 christos ctf_next_t *i = NULL;
1839 1.1.1.2 christos ssize_t offset;
1840 1.1.1.2 christos const char *membname;
1841 1.1.1.2 christos ctf_id_t src_membtype;
1842 1.1 christos
1843 1.1 christos /* Technically to match a struct or union we need to check both
1844 1.1 christos ways (src members vs. dst, dst members vs. src) but we make
1845 1.1 christos this more optimal by only checking src vs. dst and comparing
1846 1.1 christos the total size of the structure (which we must do anyway)
1847 1.1 christos which covers the possibility of dst members not in src.
1848 1.1 christos This optimization can be defeated for unions, but is so
1849 1.1 christos pathological as to render it irrelevant for our purposes. */
1850 1.1 christos
1851 1.1 christos if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1852 1.1 christos && dst_kind != CTF_K_FORWARD)
1853 1.1 christos {
1854 1.1 christos if (ctf_type_size (src_fp, src_type) !=
1855 1.1 christos ctf_type_size (dst_fp, dst_type))
1856 1.1 christos {
1857 1.1 christos ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1858 1.1 christos _("conflict for type %s against ID %lx: union "
1859 1.1 christos "size differs, old %li, new %li"), name,
1860 1.1 christos dst_type, (long) ctf_type_size (src_fp, src_type),
1861 1.1 christos (long) ctf_type_size (dst_fp, dst_type));
1862 1.1 christos return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1863 1.1 christos }
1864 1.1 christos
1865 1.1 christos if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1866 1.1 christos {
1867 1.1 christos ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1868 1.1 christos _("conflict for type %s against ID %lx: members "
1869 1.1 christos "differ, see above"), name, dst_type);
1870 1.1 christos return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1871 1.1 christos }
1872 1.1 christos
1873 1.1 christos break;
1874 1.1 christos }
1875 1.1 christos
1876 1.1.1.2 christos dst_type = ctf_add_struct_sized (dst_fp, flag, name,
1877 1.1.1.2 christos ctf_type_size (src_fp, src_type));
1878 1.1 christos if (dst_type == CTF_ERR)
1879 1.1 christos return CTF_ERR; /* errno is set for us. */
1880 1.1 christos
1881 1.1 christos /* Pre-emptively add this struct to the type mapping so that
1882 1.1 christos structures that refer to themselves work. */
1883 1.1 christos ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1884 1.1 christos
1885 1.1.1.2 christos while ((offset = ctf_member_next (src_fp, src_type, &i, &membname,
1886 1.1.1.2 christos &src_membtype, 0)) >= 0)
1887 1.1 christos {
1888 1.1.1.2 christos ctf_dict_t *dst = dst_fp;
1889 1.1.1.2 christos ctf_id_t dst_membtype = ctf_type_mapping (src_fp, src_membtype, &dst);
1890 1.1 christos
1891 1.1.1.2 christos if (dst_membtype == 0)
1892 1.1 christos {
1893 1.1.1.2 christos dst_membtype = ctf_add_type_internal (dst_fp, src_fp,
1894 1.1.1.2 christos src_membtype,
1895 1.1.1.2 christos proc_tracking_fp);
1896 1.1.1.2 christos if (dst_membtype == CTF_ERR)
1897 1.1 christos {
1898 1.1 christos if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
1899 1.1.1.2 christos {
1900 1.1.1.2 christos ctf_next_destroy (i);
1901 1.1.1.2 christos break;
1902 1.1.1.2 christos }
1903 1.1 christos }
1904 1.1 christos }
1905 1.1 christos
1906 1.1.1.2 christos if (ctf_add_member_offset (dst_fp, dst_type, membname,
1907 1.1.1.2 christos dst_membtype, offset) < 0)
1908 1.1.1.2 christos {
1909 1.1.1.2 christos ctf_next_destroy (i);
1910 1.1.1.2 christos break;
1911 1.1.1.2 christos }
1912 1.1.1.2 christos }
1913 1.1.1.2 christos if (ctf_errno (src_fp) != ECTF_NEXT_END)
1914 1.1 christos return CTF_ERR; /* errno is set for us. */
1915 1.1 christos break;
1916 1.1 christos }
1917 1.1 christos
1918 1.1 christos case CTF_K_ENUM:
1919 1.1 christos if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1920 1.1 christos && dst_kind != CTF_K_FORWARD)
1921 1.1 christos {
1922 1.1 christos if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1923 1.1 christos || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1924 1.1 christos {
1925 1.1 christos ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1926 1.1 christos _("conflict for enum %s against ID %lx: members "
1927 1.1 christos "differ, see above"), name, dst_type);
1928 1.1 christos return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1929 1.1 christos }
1930 1.1 christos }
1931 1.1 christos else
1932 1.1 christos {
1933 1.1 christos dst_type = ctf_add_enum (dst_fp, flag, name);
1934 1.1 christos if ((dst.ctb_type = dst_type) == CTF_ERR
1935 1.1 christos || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1936 1.1 christos return CTF_ERR; /* errno is set for us */
1937 1.1 christos }
1938 1.1 christos break;
1939 1.1 christos
1940 1.1 christos case CTF_K_FORWARD:
1941 1.1 christos if (dst_type == CTF_ERR)
1942 1.1 christos dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
1943 1.1 christos break;
1944 1.1 christos
1945 1.1 christos case CTF_K_TYPEDEF:
1946 1.1 christos src_type = ctf_type_reference (src_fp, src_type);
1947 1.1 christos src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1948 1.1 christos proc_tracking_fp);
1949 1.1 christos
1950 1.1 christos if (src_type == CTF_ERR)
1951 1.1 christos return CTF_ERR; /* errno is set for us. */
1952 1.1 christos
1953 1.1 christos /* If dst_type is not CTF_ERR at this point, we should check if
1954 1.1 christos ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1955 1.1 christos ECTF_CONFLICT. However, this causes problems with bitness typedefs
1956 1.1 christos that vary based on things like if 32-bit then pid_t is int otherwise
1957 1.1 christos long. We therefore omit this check and assume that if the identically
1958 1.1 christos named typedef already exists in dst_fp, it is correct or
1959 1.1 christos equivalent. */
1960 1.1 christos
1961 1.1 christos if (dst_type == CTF_ERR)
1962 1.1 christos dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
1963 1.1 christos
1964 1.1 christos break;
1965 1.1 christos
1966 1.1 christos default:
1967 1.1 christos return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
1968 1.1 christos }
1969 1.1 christos
1970 1.1 christos if (dst_type != CTF_ERR)
1971 1.1 christos ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
1972 1.1 christos return dst_type;
1973 1.1 christos }
1974 1.1 christos
1975 1.1 christos ctf_id_t
1976 1.1.1.2 christos ctf_add_type (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type)
1977 1.1 christos {
1978 1.1 christos ctf_id_t id;
1979 1.1 christos
1980 1.1 christos if (!src_fp->ctf_add_processing)
1981 1.1 christos src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
1982 1.1 christos ctf_hash_eq_integer,
1983 1.1 christos NULL, NULL);
1984 1.1 christos
1985 1.1 christos /* We store the hash on the source, because it contains only source type IDs:
1986 1.1 christos but callers will invariably expect errors to appear on the dest. */
1987 1.1 christos if (!src_fp->ctf_add_processing)
1988 1.1 christos return (ctf_set_errno (dst_fp, ENOMEM));
1989 1.1 christos
1990 1.1 christos id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
1991 1.1 christos ctf_dynhash_empty (src_fp->ctf_add_processing);
1992 1.1 christos
1993 1.1 christos return id;
1994 1.1 christos }
1995