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