1 1.1 christos /* CTF dict creation. 2 1.1.1.4 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 <assert.h> 22 1.1 christos #include <string.h> 23 1.1 christos #include <unistd.h> 24 1.1 christos #include <zlib.h> 25 1.1 christos 26 1.1 christos #include <elf.h> 27 1.1 christos #include "elf-bfd.h" 28 1.1 christos 29 1.1 christos /* Symtypetab sections. */ 30 1.1 christos 31 1.1 christos /* Symtypetab emission flags. */ 32 1.1 christos 33 1.1 christos #define CTF_SYMTYPETAB_EMIT_FUNCTION 0x1 34 1.1 christos #define CTF_SYMTYPETAB_EMIT_PAD 0x2 35 1.1 christos #define CTF_SYMTYPETAB_FORCE_INDEXED 0x4 36 1.1 christos 37 1.1 christos /* Properties of symtypetab emission, shared by symtypetab section 38 1.1 christos sizing and symtypetab emission itself. */ 39 1.1 christos 40 1.1 christos typedef struct emit_symtypetab_state 41 1.1 christos { 42 1.1 christos /* True if linker-reported symbols are being filtered out. symfp is set if 43 1.1 christos this is true: otherwise, indexing is forced and the symflags indicate as 44 1.1 christos much. */ 45 1.1 christos int filter_syms; 46 1.1 christos 47 1.1 christos /* True if symbols are being sorted. */ 48 1.1 christos int sort_syms; 49 1.1 christos 50 1.1 christos /* Flags for symtypetab emission. */ 51 1.1 christos int symflags; 52 1.1 christos 53 1.1 christos /* The dict to which the linker has reported symbols. */ 54 1.1 christos ctf_dict_t *symfp; 55 1.1 christos 56 1.1 christos /* The maximum number of objects seen. */ 57 1.1 christos size_t maxobjt; 58 1.1 christos 59 1.1 christos /* The maximum number of func info entris seen. */ 60 1.1 christos size_t maxfunc; 61 1.1 christos } emit_symtypetab_state_t; 62 1.1 christos 63 1.1 christos /* Determine if a symbol is "skippable" and should never appear in the 64 1.1 christos symtypetab sections. */ 65 1.1 christos 66 1.1 christos int 67 1.1 christos ctf_symtab_skippable (ctf_link_sym_t *sym) 68 1.1 christos { 69 1.1 christos /* Never skip symbols whose name is not yet known. */ 70 1.1 christos if (sym->st_nameidx_set) 71 1.1 christos return 0; 72 1.1 christos 73 1.1 christos return (sym->st_name == NULL || sym->st_name[0] == 0 74 1.1 christos || sym->st_shndx == SHN_UNDEF 75 1.1 christos || strcmp (sym->st_name, "_START_") == 0 76 1.1 christos || strcmp (sym->st_name, "_END_") == 0 77 1.1.1.4 christos || strcmp (sym->st_name, "_DYNAMIC") == 0 78 1.1.1.4 christos || strcmp (sym->st_name, "_GLOBAL_OFFSET_TABLE_") == 0 79 1.1.1.4 christos || strcmp (sym->st_name, "_PROCEDURE_LINKAGE_TABLE_") == 0 80 1.1.1.4 christos || strcmp (sym->st_name, "_edata") == 0 81 1.1.1.4 christos || strcmp (sym->st_name, "_end") == 0 82 1.1.1.4 christos || strcmp (sym->st_name, "_etext") == 0 83 1.1 christos || (sym->st_type == STT_OBJECT && sym->st_shndx == SHN_EXTABS 84 1.1 christos && sym->st_value == 0)); 85 1.1 christos } 86 1.1 christos 87 1.1 christos /* Get the number of symbols in a symbol hash, the count of symbols, the maximum 88 1.1 christos seen, the eventual size, without any padding elements, of the func/data and 89 1.1 christos (if generated) index sections, and the size of accumulated padding elements. 90 1.1 christos The linker-reported set of symbols is found in SYMFP: it may be NULL if 91 1.1 christos symbol filtering is not desired, in which case CTF_SYMTYPETAB_FORCE_INDEXED 92 1.1 christos will always be set in the flags. 93 1.1 christos 94 1.1 christos Also figure out if any symbols need to be moved to the variable section, and 95 1.1 christos add them (if not already present). */ 96 1.1 christos 97 1.1 christos _libctf_nonnull_ ((1,3,4,5,6,7,8)) 98 1.1 christos static int 99 1.1 christos symtypetab_density (ctf_dict_t *fp, ctf_dict_t *symfp, ctf_dynhash_t *symhash, 100 1.1 christos size_t *count, size_t *max, size_t *unpadsize, 101 1.1 christos size_t *padsize, size_t *idxsize, int flags) 102 1.1 christos { 103 1.1 christos ctf_next_t *i = NULL; 104 1.1 christos const void *name; 105 1.1 christos const void *ctf_sym; 106 1.1 christos ctf_dynhash_t *linker_known = NULL; 107 1.1 christos int err; 108 1.1 christos int beyond_max = 0; 109 1.1 christos 110 1.1 christos *count = 0; 111 1.1 christos *max = 0; 112 1.1 christos *unpadsize = 0; 113 1.1 christos *idxsize = 0; 114 1.1 christos *padsize = 0; 115 1.1 christos 116 1.1 christos if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED)) 117 1.1 christos { 118 1.1 christos /* Make a dynhash citing only symbols reported by the linker of the 119 1.1 christos appropriate type, then traverse all potential-symbols we know the types 120 1.1 christos of, removing them from linker_known as we go. Once this is done, the 121 1.1 christos only symbols remaining in linker_known are symbols we don't know the 122 1.1 christos types of: we must emit pads for those symbols that are below the 123 1.1 christos maximum symbol we will emit (any beyond that are simply skipped). 124 1.1 christos 125 1.1 christos If there are none, this symtypetab will be empty: just report that. */ 126 1.1 christos 127 1.1 christos if (!symfp->ctf_dynsyms) 128 1.1 christos return 0; 129 1.1 christos 130 1.1 christos if ((linker_known = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string, 131 1.1 christos NULL, NULL)) == NULL) 132 1.1 christos return (ctf_set_errno (fp, ENOMEM)); 133 1.1 christos 134 1.1 christos while ((err = ctf_dynhash_cnext (symfp->ctf_dynsyms, &i, 135 1.1 christos &name, &ctf_sym)) == 0) 136 1.1 christos { 137 1.1 christos ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym; 138 1.1 christos 139 1.1 christos if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 140 1.1 christos && sym->st_type != STT_FUNC) 141 1.1 christos || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 142 1.1 christos && sym->st_type != STT_OBJECT)) 143 1.1 christos continue; 144 1.1 christos 145 1.1 christos if (ctf_symtab_skippable (sym)) 146 1.1 christos continue; 147 1.1 christos 148 1.1 christos /* This should only be true briefly before all the names are 149 1.1 christos finalized, long before we get this far. */ 150 1.1 christos if (!ctf_assert (fp, !sym->st_nameidx_set)) 151 1.1 christos return -1; /* errno is set for us. */ 152 1.1 christos 153 1.1 christos if (ctf_dynhash_cinsert (linker_known, name, ctf_sym) < 0) 154 1.1 christos { 155 1.1 christos ctf_dynhash_destroy (linker_known); 156 1.1 christos return (ctf_set_errno (fp, ENOMEM)); 157 1.1 christos } 158 1.1 christos } 159 1.1 christos if (err != ECTF_NEXT_END) 160 1.1 christos { 161 1.1 christos ctf_err_warn (fp, 0, err, _("iterating over linker-known symbols during " 162 1.1 christos "serialization")); 163 1.1 christos ctf_dynhash_destroy (linker_known); 164 1.1 christos return (ctf_set_errno (fp, err)); 165 1.1 christos } 166 1.1 christos } 167 1.1 christos 168 1.1 christos while ((err = ctf_dynhash_cnext (symhash, &i, &name, NULL)) == 0) 169 1.1 christos { 170 1.1 christos ctf_link_sym_t *sym; 171 1.1 christos 172 1.1 christos if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED)) 173 1.1 christos { 174 1.1 christos /* Linker did not report symbol in symtab. Remove it from the 175 1.1 christos set of known data symbols and continue. */ 176 1.1 christos if ((sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, name)) == NULL) 177 1.1 christos { 178 1.1 christos ctf_dynhash_remove (symhash, name); 179 1.1 christos continue; 180 1.1 christos } 181 1.1 christos 182 1.1 christos /* We don't remove skippable symbols from the symhash because we don't 183 1.1 christos want them to be migrated into variables. */ 184 1.1 christos if (ctf_symtab_skippable (sym)) 185 1.1 christos continue; 186 1.1 christos 187 1.1 christos if ((flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 188 1.1 christos && sym->st_type != STT_FUNC) 189 1.1 christos { 190 1.1 christos ctf_err_warn (fp, 1, 0, _("symbol %s (%x) added to CTF as a " 191 1.1 christos "function but is of type %x. " 192 1.1 christos "The symbol type lookup tables " 193 1.1 christos "are probably corrupted"), 194 1.1 christos sym->st_name, sym->st_symidx, sym->st_type); 195 1.1 christos ctf_dynhash_remove (symhash, name); 196 1.1 christos continue; 197 1.1 christos } 198 1.1 christos else if (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 199 1.1 christos && sym->st_type != STT_OBJECT) 200 1.1 christos { 201 1.1 christos ctf_err_warn (fp, 1, 0, _("symbol %s (%x) added to CTF as a " 202 1.1 christos "data object but is of type %x. " 203 1.1 christos "The symbol type lookup tables " 204 1.1 christos "are probably corrupted"), 205 1.1 christos sym->st_name, sym->st_symidx, sym->st_type); 206 1.1 christos ctf_dynhash_remove (symhash, name); 207 1.1 christos continue; 208 1.1 christos } 209 1.1 christos 210 1.1 christos ctf_dynhash_remove (linker_known, name); 211 1.1 christos 212 1.1 christos if (*max < sym->st_symidx) 213 1.1 christos *max = sym->st_symidx; 214 1.1 christos } 215 1.1 christos else 216 1.1 christos (*max)++; 217 1.1.1.3 christos 218 1.1.1.3 christos *unpadsize += sizeof (uint32_t); 219 1.1.1.3 christos (*count)++; 220 1.1 christos } 221 1.1 christos if (err != ECTF_NEXT_END) 222 1.1 christos { 223 1.1 christos ctf_err_warn (fp, 0, err, _("iterating over CTF symtypetab during " 224 1.1 christos "serialization")); 225 1.1 christos ctf_dynhash_destroy (linker_known); 226 1.1 christos return (ctf_set_errno (fp, err)); 227 1.1 christos } 228 1.1 christos 229 1.1 christos if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED)) 230 1.1 christos { 231 1.1 christos while ((err = ctf_dynhash_cnext (linker_known, &i, NULL, &ctf_sym)) == 0) 232 1.1 christos { 233 1.1 christos ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym; 234 1.1 christos 235 1.1 christos if (sym->st_symidx > *max) 236 1.1 christos beyond_max++; 237 1.1 christos } 238 1.1 christos if (err != ECTF_NEXT_END) 239 1.1 christos { 240 1.1 christos ctf_err_warn (fp, 0, err, _("iterating over linker-known symbols " 241 1.1 christos "during CTF serialization")); 242 1.1 christos ctf_dynhash_destroy (linker_known); 243 1.1 christos return (ctf_set_errno (fp, err)); 244 1.1 christos } 245 1.1 christos } 246 1.1 christos 247 1.1 christos *idxsize = *count * sizeof (uint32_t); 248 1.1 christos if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED)) 249 1.1 christos *padsize = (ctf_dynhash_elements (linker_known) - beyond_max) * sizeof (uint32_t); 250 1.1 christos 251 1.1 christos ctf_dynhash_destroy (linker_known); 252 1.1 christos return 0; 253 1.1 christos } 254 1.1 christos 255 1.1 christos /* Emit an objt or func symtypetab into DP in a particular order defined by an 256 1.1 christos array of ctf_link_sym_t or symbol names passed in. The index has NIDX 257 1.1 christos elements in it: unindexed output would terminate at symbol OUTMAX and is in 258 1.1 christos any case no larger than SIZE bytes. Some index elements are expected to be 259 1.1 christos skipped: see symtypetab_density. The linker-reported set of symbols (if any) 260 1.1 christos is found in SYMFP. */ 261 1.1 christos static int 262 1.1 christos emit_symtypetab (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp, 263 1.1 christos ctf_link_sym_t **idx, const char **nameidx, uint32_t nidx, 264 1.1 christos uint32_t outmax, int size, int flags) 265 1.1 christos { 266 1.1 christos uint32_t i; 267 1.1 christos uint32_t *dpp = dp; 268 1.1 christos ctf_dynhash_t *symhash; 269 1.1 christos 270 1.1 christos ctf_dprintf ("Emitting table of size %i, outmax %u, %u symtypetab entries, " 271 1.1 christos "flags %i\n", size, outmax, nidx, flags); 272 1.1 christos 273 1.1 christos /* Empty table? Nothing to do. */ 274 1.1 christos if (size == 0) 275 1.1 christos return 0; 276 1.1 christos 277 1.1 christos if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 278 1.1 christos symhash = fp->ctf_funchash; 279 1.1 christos else 280 1.1 christos symhash = fp->ctf_objthash; 281 1.1 christos 282 1.1 christos for (i = 0; i < nidx; i++) 283 1.1 christos { 284 1.1 christos const char *sym_name; 285 1.1 christos void *type; 286 1.1 christos 287 1.1 christos /* If we have a linker-reported set of symbols, we may be given that set 288 1.1 christos to work from, or a set of symbol names. In both cases we want to look 289 1.1 christos at the corresponding linker-reported symbol (if any). */ 290 1.1 christos if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED)) 291 1.1 christos { 292 1.1 christos ctf_link_sym_t *this_link_sym; 293 1.1 christos 294 1.1 christos if (idx) 295 1.1 christos this_link_sym = idx[i]; 296 1.1 christos else 297 1.1 christos this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, nameidx[i]); 298 1.1 christos 299 1.1 christos /* Unreported symbol number. No pad, no nothing. */ 300 1.1 christos if (!this_link_sym) 301 1.1 christos continue; 302 1.1 christos 303 1.1 christos /* Symbol of the wrong type, or skippable? This symbol is not in this 304 1.1 christos table. */ 305 1.1 christos if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 306 1.1 christos && this_link_sym->st_type != STT_FUNC) 307 1.1 christos || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 308 1.1 christos && this_link_sym->st_type != STT_OBJECT)) 309 1.1 christos continue; 310 1.1 christos 311 1.1 christos if (ctf_symtab_skippable (this_link_sym)) 312 1.1 christos continue; 313 1.1 christos 314 1.1 christos sym_name = this_link_sym->st_name; 315 1.1 christos 316 1.1 christos /* Linker reports symbol of a different type to the symbol we actually 317 1.1 christos added? Skip the symbol. No pad, since the symbol doesn't actually 318 1.1 christos belong in this table at all. (Warned about in 319 1.1 christos symtypetab_density.) */ 320 1.1 christos if ((this_link_sym->st_type == STT_FUNC) 321 1.1 christos && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name))) 322 1.1 christos continue; 323 1.1 christos 324 1.1 christos if ((this_link_sym->st_type == STT_OBJECT) 325 1.1 christos && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name))) 326 1.1 christos continue; 327 1.1 christos } 328 1.1 christos else 329 1.1 christos sym_name = nameidx[i]; 330 1.1 christos 331 1.1 christos /* Symbol in index but no type set? Silently skip and (optionally) 332 1.1 christos pad. (In force-indexed mode, this is also where we track symbols of 333 1.1 christos the wrong type for this round of insertion.) */ 334 1.1 christos if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL) 335 1.1 christos { 336 1.1 christos if (flags & CTF_SYMTYPETAB_EMIT_PAD) 337 1.1 christos *dpp++ = 0; 338 1.1 christos continue; 339 1.1 christos } 340 1.1 christos 341 1.1 christos if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) < size)) 342 1.1 christos return -1; /* errno is set for us. */ 343 1.1 christos 344 1.1 christos *dpp++ = (ctf_id_t) (uintptr_t) type; 345 1.1 christos 346 1.1 christos /* When emitting unindexed output, all later symbols are pads: stop 347 1.1 christos early. */ 348 1.1 christos if ((flags & CTF_SYMTYPETAB_EMIT_PAD) && idx[i]->st_symidx == outmax) 349 1.1 christos break; 350 1.1 christos } 351 1.1 christos 352 1.1 christos return 0; 353 1.1 christos } 354 1.1 christos 355 1.1 christos /* Emit an objt or func symtypetab index into DP in a paticular order defined by 356 1.1 christos an array of symbol names passed in. Stop at NIDX. The linker-reported set 357 1.1 christos of symbols (if any) is found in SYMFP. */ 358 1.1 christos static int 359 1.1 christos emit_symtypetab_index (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp, 360 1.1 christos const char **idx, uint32_t nidx, int size, int flags) 361 1.1 christos { 362 1.1 christos uint32_t i; 363 1.1 christos uint32_t *dpp = dp; 364 1.1 christos ctf_dynhash_t *symhash; 365 1.1 christos 366 1.1 christos ctf_dprintf ("Emitting index of size %i, %u entries reported by linker, " 367 1.1 christos "flags %i\n", size, nidx, flags); 368 1.1 christos 369 1.1 christos /* Empty table? Nothing to do. */ 370 1.1 christos if (size == 0) 371 1.1 christos return 0; 372 1.1 christos 373 1.1 christos if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 374 1.1 christos symhash = fp->ctf_funchash; 375 1.1 christos else 376 1.1 christos symhash = fp->ctf_objthash; 377 1.1 christos 378 1.1 christos /* Indexes should always be unpadded. */ 379 1.1 christos if (!ctf_assert (fp, !(flags & CTF_SYMTYPETAB_EMIT_PAD))) 380 1.1 christos return -1; /* errno is set for us. */ 381 1.1 christos 382 1.1 christos for (i = 0; i < nidx; i++) 383 1.1 christos { 384 1.1 christos const char *sym_name; 385 1.1 christos void *type; 386 1.1 christos 387 1.1 christos if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED)) 388 1.1 christos { 389 1.1 christos ctf_link_sym_t *this_link_sym; 390 1.1 christos 391 1.1 christos this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, idx[i]); 392 1.1 christos 393 1.1 christos /* This is an index: unreported symbols should never appear in it. */ 394 1.1 christos if (!ctf_assert (fp, this_link_sym != NULL)) 395 1.1 christos return -1; /* errno is set for us. */ 396 1.1 christos 397 1.1 christos /* Symbol of the wrong type, or skippable? This symbol is not in this 398 1.1 christos table. */ 399 1.1 christos if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 400 1.1 christos && this_link_sym->st_type != STT_FUNC) 401 1.1 christos || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION) 402 1.1 christos && this_link_sym->st_type != STT_OBJECT)) 403 1.1 christos continue; 404 1.1 christos 405 1.1 christos if (ctf_symtab_skippable (this_link_sym)) 406 1.1 christos continue; 407 1.1 christos 408 1.1 christos sym_name = this_link_sym->st_name; 409 1.1 christos 410 1.1 christos /* Linker reports symbol of a different type to the symbol we actually 411 1.1 christos added? Skip the symbol. */ 412 1.1 christos if ((this_link_sym->st_type == STT_FUNC) 413 1.1 christos && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name))) 414 1.1 christos continue; 415 1.1 christos 416 1.1 christos if ((this_link_sym->st_type == STT_OBJECT) 417 1.1 christos && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name))) 418 1.1 christos continue; 419 1.1 christos } 420 1.1 christos else 421 1.1 christos sym_name = idx[i]; 422 1.1 christos 423 1.1 christos /* Symbol in index and reported by linker, but no type set? Silently skip 424 1.1 christos and (optionally) pad. (In force-indexed mode, this is also where we 425 1.1 christos track symbols of the wrong type for this round of insertion.) */ 426 1.1 christos if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL) 427 1.1 christos continue; 428 1.1 christos 429 1.1 christos ctf_str_add_ref (fp, sym_name, dpp++); 430 1.1 christos 431 1.1 christos if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) <= size)) 432 1.1 christos return -1; /* errno is set for us. */ 433 1.1 christos } 434 1.1 christos 435 1.1 christos return 0; 436 1.1 christos } 437 1.1 christos 438 1.1 christos /* Delete symbols that have been assigned names from the variable section. Must 439 1.1 christos be called from within ctf_serialize, because that is the only place you can 440 1.1 christos safely delete variables without messing up ctf_rollback. */ 441 1.1 christos 442 1.1 christos static int 443 1.1 christos symtypetab_delete_nonstatics (ctf_dict_t *fp, ctf_dict_t *symfp) 444 1.1 christos { 445 1.1 christos ctf_dvdef_t *dvd, *nvd; 446 1.1 christos ctf_id_t type; 447 1.1 christos 448 1.1 christos for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd) 449 1.1 christos { 450 1.1 christos nvd = ctf_list_next (dvd); 451 1.1 christos 452 1.1 christos if ((((type = (ctf_id_t) (uintptr_t) 453 1.1 christos ctf_dynhash_lookup (fp->ctf_objthash, dvd->dvd_name)) > 0) 454 1.1 christos || (type = (ctf_id_t) (uintptr_t) 455 1.1 christos ctf_dynhash_lookup (fp->ctf_funchash, dvd->dvd_name)) > 0) 456 1.1 christos && ctf_dynhash_lookup (symfp->ctf_dynsyms, dvd->dvd_name) != NULL 457 1.1 christos && type == dvd->dvd_type) 458 1.1 christos ctf_dvd_delete (fp, dvd); 459 1.1 christos } 460 1.1 christos 461 1.1 christos return 0; 462 1.1 christos } 463 1.1 christos 464 1.1 christos /* Figure out the sizes of the symtypetab sections, their indexed state, 465 1.1 christos etc. */ 466 1.1 christos static int 467 1.1 christos ctf_symtypetab_sect_sizes (ctf_dict_t *fp, emit_symtypetab_state_t *s, 468 1.1 christos ctf_header_t *hdr, size_t *objt_size, 469 1.1 christos size_t *func_size, size_t *objtidx_size, 470 1.1 christos size_t *funcidx_size) 471 1.1 christos { 472 1.1 christos size_t nfuncs, nobjts; 473 1.1 christos size_t objt_unpadsize, func_unpadsize, objt_padsize, func_padsize; 474 1.1 christos 475 1.1 christos /* If doing a writeout as part of linking, and the link flags request it, 476 1.1 christos filter out reported symbols from the variable section, and filter out all 477 1.1 christos other symbols from the symtypetab sections. (If we are not linking, the 478 1.1 christos symbols are sorted; if we are linking, don't bother sorting if we are not 479 1.1.1.3 christos filtering out reported symbols: this is almost certainly an ld -r and only 480 1.1 christos the linker is likely to consume these symtypetabs again. The linker 481 1.1.1.3 christos doesn't care what order the symtypetab entries are in, since it only 482 1.1 christos iterates over symbols and does not use the ctf_lookup_by_symbol* API.) */ 483 1.1 christos 484 1.1 christos s->sort_syms = 1; 485 1.1 christos if (fp->ctf_flags & LCTF_LINKING) 486 1.1 christos { 487 1.1 christos s->filter_syms = !(fp->ctf_link_flags & CTF_LINK_NO_FILTER_REPORTED_SYMS); 488 1.1 christos if (!s->filter_syms) 489 1.1 christos s->sort_syms = 0; 490 1.1 christos } 491 1.1 christos 492 1.1 christos /* Find the dict to which the linker has reported symbols, if any. */ 493 1.1 christos 494 1.1 christos if (s->filter_syms) 495 1.1 christos { 496 1.1 christos if (!fp->ctf_dynsyms && fp->ctf_parent && fp->ctf_parent->ctf_dynsyms) 497 1.1 christos s->symfp = fp->ctf_parent; 498 1.1 christos else 499 1.1 christos s->symfp = fp; 500 1.1 christos } 501 1.1 christos 502 1.1 christos /* If not filtering, keep all potential symbols in an unsorted, indexed 503 1.1 christos dict. */ 504 1.1 christos if (!s->filter_syms) 505 1.1 christos s->symflags = CTF_SYMTYPETAB_FORCE_INDEXED; 506 1.1 christos else 507 1.1 christos hdr->cth_flags |= CTF_F_IDXSORTED; 508 1.1 christos 509 1.1 christos if (!ctf_assert (fp, (s->filter_syms && s->symfp) 510 1.1 christos || (!s->filter_syms && !s->symfp 511 1.1 christos && ((s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED) != 0)))) 512 1.1 christos return -1; 513 1.1 christos 514 1.1 christos /* Work out the sizes of the object and function sections, and work out the 515 1.1 christos number of pad (unassigned) symbols in each, and the overall size of the 516 1.1 christos sections. */ 517 1.1 christos 518 1.1 christos if (symtypetab_density (fp, s->symfp, fp->ctf_objthash, &nobjts, &s->maxobjt, 519 1.1 christos &objt_unpadsize, &objt_padsize, objtidx_size, 520 1.1 christos s->symflags) < 0) 521 1.1 christos return -1; /* errno is set for us. */ 522 1.1 christos 523 1.1 christos ctf_dprintf ("Object symtypetab: %i objects, max %i, unpadded size %i, " 524 1.1 christos "%i bytes of pads, index size %i\n", (int) nobjts, 525 1.1 christos (int) s->maxobjt, (int) objt_unpadsize, (int) objt_padsize, 526 1.1 christos (int) *objtidx_size); 527 1.1 christos 528 1.1 christos if (symtypetab_density (fp, s->symfp, fp->ctf_funchash, &nfuncs, &s->maxfunc, 529 1.1 christos &func_unpadsize, &func_padsize, funcidx_size, 530 1.1 christos s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0) 531 1.1 christos return -1; /* errno is set for us. */ 532 1.1 christos 533 1.1 christos ctf_dprintf ("Function symtypetab: %i functions, max %i, unpadded size %i, " 534 1.1 christos "%i bytes of pads, index size %i\n", (int) nfuncs, 535 1.1 christos (int) s->maxfunc, (int) func_unpadsize, (int) func_padsize, 536 1.1 christos (int) *funcidx_size); 537 1.1 christos 538 1.1 christos /* It is worth indexing each section if it would save space to do so, due to 539 1.1 christos reducing the number of pads sufficiently. A pad is the same size as a 540 1.1 christos single index entry: but index sections compress relatively poorly compared 541 1.1 christos to constant pads, so it takes a lot of contiguous padding to equal one 542 1.1 christos index section entry. It would be nice to be able to *verify* whether we 543 1.1 christos would save space after compression rather than guessing, but this seems 544 1.1 christos difficult, since it would require complete reserialization. Regardless, if 545 1.1 christos the linker has not reported any symbols (e.g. if this is not a final link 546 1.1 christos but just an ld -r), we must emit things in indexed fashion just as the 547 1.1 christos compiler does. */ 548 1.1 christos 549 1.1 christos *objt_size = objt_unpadsize; 550 1.1 christos if (!(s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED) 551 1.1 christos && ((objt_padsize + objt_unpadsize) * CTF_INDEX_PAD_THRESHOLD 552 1.1 christos > objt_padsize)) 553 1.1 christos { 554 1.1 christos *objt_size += objt_padsize; 555 1.1 christos *objtidx_size = 0; 556 1.1 christos } 557 1.1 christos 558 1.1 christos *func_size = func_unpadsize; 559 1.1 christos if (!(s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED) 560 1.1 christos && ((func_padsize + func_unpadsize) * CTF_INDEX_PAD_THRESHOLD 561 1.1 christos > func_padsize)) 562 1.1 christos { 563 1.1 christos *func_size += func_padsize; 564 1.1 christos *funcidx_size = 0; 565 1.1 christos } 566 1.1 christos 567 1.1 christos /* If we are filtering symbols out, those symbols that the linker has not 568 1.1 christos reported have now been removed from the ctf_objthash and ctf_funchash. 569 1.1 christos Delete entries from the variable section that duplicate newly-added 570 1.1 christos symbols. There's no need to migrate new ones in: we do that (if necessary) 571 1.1 christos in ctf_link_deduplicating_variables. */ 572 1.1 christos 573 1.1 christos if (s->filter_syms && s->symfp->ctf_dynsyms && 574 1.1 christos symtypetab_delete_nonstatics (fp, s->symfp) < 0) 575 1.1 christos return -1; 576 1.1 christos 577 1.1 christos return 0; 578 1.1 christos } 579 1.1 christos 580 1.1 christos static int 581 1.1 christos ctf_emit_symtypetab_sects (ctf_dict_t *fp, emit_symtypetab_state_t *s, 582 1.1 christos unsigned char **tptr, size_t objt_size, 583 1.1 christos size_t func_size, size_t objtidx_size, 584 1.1 christos size_t funcidx_size) 585 1.1 christos { 586 1.1 christos unsigned char *t = *tptr; 587 1.1 christos size_t nsymtypes = 0; 588 1.1 christos const char **sym_name_order = NULL; 589 1.1 christos int err; 590 1.1 christos 591 1.1 christos /* Sort the linker's symbols into name order if need be. */ 592 1.1 christos 593 1.1 christos if ((objtidx_size != 0) || (funcidx_size != 0)) 594 1.1 christos { 595 1.1 christos ctf_next_t *i = NULL; 596 1.1 christos void *symname; 597 1.1 christos const char **walk; 598 1.1 christos 599 1.1 christos if (s->filter_syms) 600 1.1 christos { 601 1.1 christos if (s->symfp->ctf_dynsyms) 602 1.1 christos nsymtypes = ctf_dynhash_elements (s->symfp->ctf_dynsyms); 603 1.1 christos else 604 1.1 christos nsymtypes = 0; 605 1.1 christos } 606 1.1 christos else 607 1.1 christos nsymtypes = ctf_dynhash_elements (fp->ctf_objthash) 608 1.1 christos + ctf_dynhash_elements (fp->ctf_funchash); 609 1.1 christos 610 1.1 christos if ((sym_name_order = calloc (nsymtypes, sizeof (const char *))) == NULL) 611 1.1 christos goto oom; 612 1.1 christos 613 1.1 christos walk = sym_name_order; 614 1.1 christos 615 1.1 christos if (s->filter_syms) 616 1.1 christos { 617 1.1 christos if (s->symfp->ctf_dynsyms) 618 1.1 christos { 619 1.1 christos while ((err = ctf_dynhash_next_sorted (s->symfp->ctf_dynsyms, &i, 620 1.1 christos &symname, NULL, 621 1.1 christos ctf_dynhash_sort_by_name, 622 1.1 christos NULL)) == 0) 623 1.1 christos *walk++ = (const char *) symname; 624 1.1 christos if (err != ECTF_NEXT_END) 625 1.1 christos goto symerr; 626 1.1 christos } 627 1.1 christos } 628 1.1 christos else 629 1.1 christos { 630 1.1 christos ctf_hash_sort_f sort_fun = NULL; 631 1.1 christos 632 1.1 christos /* Since we partition the set of symbols back into objt and func, 633 1.1 christos we can sort the two independently without harm. */ 634 1.1 christos if (s->sort_syms) 635 1.1 christos sort_fun = ctf_dynhash_sort_by_name; 636 1.1 christos 637 1.1 christos while ((err = ctf_dynhash_next_sorted (fp->ctf_objthash, &i, &symname, 638 1.1 christos NULL, sort_fun, NULL)) == 0) 639 1.1 christos *walk++ = (const char *) symname; 640 1.1 christos if (err != ECTF_NEXT_END) 641 1.1 christos goto symerr; 642 1.1 christos 643 1.1 christos while ((err = ctf_dynhash_next_sorted (fp->ctf_funchash, &i, &symname, 644 1.1 christos NULL, sort_fun, NULL)) == 0) 645 1.1 christos *walk++ = (const char *) symname; 646 1.1 christos if (err != ECTF_NEXT_END) 647 1.1 christos goto symerr; 648 1.1 christos } 649 1.1 christos } 650 1.1 christos 651 1.1 christos /* Emit the object and function sections, and if necessary their indexes. 652 1.1 christos Emission is done in symtab order if there is no index, and in index 653 1.1 christos (name) order otherwise. */ 654 1.1 christos 655 1.1 christos if ((objtidx_size == 0) && s->symfp && s->symfp->ctf_dynsymidx) 656 1.1 christos { 657 1.1 christos ctf_dprintf ("Emitting unindexed objt symtypetab\n"); 658 1.1 christos if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, 659 1.1 christos s->symfp->ctf_dynsymidx, NULL, 660 1.1 christos s->symfp->ctf_dynsymmax + 1, s->maxobjt, 661 1.1 christos objt_size, s->symflags | CTF_SYMTYPETAB_EMIT_PAD) < 0) 662 1.1 christos goto err; /* errno is set for us. */ 663 1.1 christos } 664 1.1 christos else 665 1.1 christos { 666 1.1 christos ctf_dprintf ("Emitting indexed objt symtypetab\n"); 667 1.1 christos if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, NULL, 668 1.1 christos sym_name_order, nsymtypes, s->maxobjt, 669 1.1 christos objt_size, s->symflags) < 0) 670 1.1 christos goto err; /* errno is set for us. */ 671 1.1 christos } 672 1.1 christos 673 1.1 christos t += objt_size; 674 1.1 christos 675 1.1 christos if ((funcidx_size == 0) && s->symfp && s->symfp->ctf_dynsymidx) 676 1.1 christos { 677 1.1 christos ctf_dprintf ("Emitting unindexed func symtypetab\n"); 678 1.1 christos if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, 679 1.1 christos s->symfp->ctf_dynsymidx, NULL, 680 1.1 christos s->symfp->ctf_dynsymmax + 1, s->maxfunc, 681 1.1 christos func_size, s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION 682 1.1 christos | CTF_SYMTYPETAB_EMIT_PAD) < 0) 683 1.1 christos goto err; /* errno is set for us. */ 684 1.1 christos } 685 1.1 christos else 686 1.1 christos { 687 1.1 christos ctf_dprintf ("Emitting indexed func symtypetab\n"); 688 1.1 christos if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, NULL, sym_name_order, 689 1.1 christos nsymtypes, s->maxfunc, func_size, 690 1.1 christos s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0) 691 1.1 christos goto err; /* errno is set for us. */ 692 1.1 christos } 693 1.1 christos 694 1.1 christos t += func_size; 695 1.1 christos 696 1.1 christos if (objtidx_size > 0) 697 1.1 christos if (emit_symtypetab_index (fp, s->symfp, (uint32_t *) t, sym_name_order, 698 1.1 christos nsymtypes, objtidx_size, s->symflags) < 0) 699 1.1 christos goto err; 700 1.1 christos 701 1.1 christos t += objtidx_size; 702 1.1 christos 703 1.1 christos if (funcidx_size > 0) 704 1.1 christos if (emit_symtypetab_index (fp, s->symfp, (uint32_t *) t, sym_name_order, 705 1.1 christos nsymtypes, funcidx_size, 706 1.1 christos s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0) 707 1.1 christos goto err; 708 1.1 christos 709 1.1 christos t += funcidx_size; 710 1.1 christos free (sym_name_order); 711 1.1 christos *tptr = t; 712 1.1 christos 713 1.1 christos return 0; 714 1.1 christos 715 1.1 christos oom: 716 1.1 christos ctf_set_errno (fp, EAGAIN); 717 1.1 christos goto err; 718 1.1 christos symerr: 719 1.1 christos ctf_err_warn (fp, 0, err, _("error serializing symtypetabs")); 720 1.1 christos err: 721 1.1 christos free (sym_name_order); 722 1.1 christos return -1; 723 1.1 christos } 724 1.1 christos 725 1.1 christos /* Type section. */ 726 1.1 christos 727 1.1.1.3 christos /* Iterate through the static types and the dynamic type definition list and 728 1.1.1.3 christos compute the size of the CTF type section. */ 729 1.1 christos 730 1.1 christos static size_t 731 1.1 christos ctf_type_sect_size (ctf_dict_t *fp) 732 1.1 christos { 733 1.1 christos ctf_dtdef_t *dtd; 734 1.1 christos size_t type_size; 735 1.1 christos 736 1.1 christos for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs); 737 1.1 christos dtd != NULL; dtd = ctf_list_next (dtd)) 738 1.1 christos { 739 1.1 christos uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info); 740 1.1 christos uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info); 741 1.1 christos size_t type_ctt_size = dtd->dtd_data.ctt_size; 742 1.1 christos 743 1.1 christos /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t 744 1.1 christos if possible. */ 745 1.1 christos 746 1.1 christos if (kind == CTF_K_STRUCT || kind == CTF_K_UNION) 747 1.1 christos { 748 1.1 christos size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data); 749 1.1 christos 750 1.1 christos if (lsize <= CTF_MAX_SIZE) 751 1.1 christos type_ctt_size = lsize; 752 1.1 christos } 753 1.1 christos 754 1.1 christos if (type_ctt_size != CTF_LSIZE_SENT) 755 1.1 christos type_size += sizeof (ctf_stype_t); 756 1.1 christos else 757 1.1 christos type_size += sizeof (ctf_type_t); 758 1.1 christos 759 1.1 christos switch (kind) 760 1.1 christos { 761 1.1 christos case CTF_K_INTEGER: 762 1.1 christos case CTF_K_FLOAT: 763 1.1 christos type_size += sizeof (uint32_t); 764 1.1 christos break; 765 1.1 christos case CTF_K_ARRAY: 766 1.1 christos type_size += sizeof (ctf_array_t); 767 1.1 christos break; 768 1.1 christos case CTF_K_SLICE: 769 1.1 christos type_size += sizeof (ctf_slice_t); 770 1.1 christos break; 771 1.1 christos case CTF_K_FUNCTION: 772 1.1 christos type_size += sizeof (uint32_t) * (vlen + (vlen & 1)); 773 1.1 christos break; 774 1.1 christos case CTF_K_STRUCT: 775 1.1 christos case CTF_K_UNION: 776 1.1 christos if (type_ctt_size < CTF_LSTRUCT_THRESH) 777 1.1 christos type_size += sizeof (ctf_member_t) * vlen; 778 1.1 christos else 779 1.1 christos type_size += sizeof (ctf_lmember_t) * vlen; 780 1.1 christos break; 781 1.1 christos case CTF_K_ENUM: 782 1.1 christos type_size += sizeof (ctf_enum_t) * vlen; 783 1.1 christos break; 784 1.1 christos } 785 1.1 christos } 786 1.1 christos 787 1.1.1.3 christos return type_size + fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff; 788 1.1 christos } 789 1.1 christos 790 1.1 christos /* Take a final lap through the dynamic type definition list and copy the 791 1.1 christos appropriate type records to the output buffer, noting down the strings as 792 1.1 christos we go. */ 793 1.1 christos 794 1.1 christos static void 795 1.1 christos ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) 796 1.1 christos { 797 1.1 christos unsigned char *t = *tptr; 798 1.1 christos ctf_dtdef_t *dtd; 799 1.1 christos 800 1.1 christos for (dtd = ctf_list_next (&fp->ctf_dtdefs); 801 1.1 christos dtd != NULL; dtd = ctf_list_next (dtd)) 802 1.1 christos { 803 1.1 christos uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info); 804 1.1 christos uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info); 805 1.1 christos size_t type_ctt_size = dtd->dtd_data.ctt_size; 806 1.1 christos size_t len; 807 1.1 christos ctf_stype_t *copied; 808 1.1 christos const char *name; 809 1.1 christos size_t i; 810 1.1 christos 811 1.1 christos /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t 812 1.1 christos if possible. */ 813 1.1 christos 814 1.1 christos if (kind == CTF_K_STRUCT || kind == CTF_K_UNION) 815 1.1 christos { 816 1.1 christos size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data); 817 1.1 christos 818 1.1 christos if (lsize <= CTF_MAX_SIZE) 819 1.1 christos type_ctt_size = lsize; 820 1.1 christos } 821 1.1 christos 822 1.1 christos if (type_ctt_size != CTF_LSIZE_SENT) 823 1.1 christos len = sizeof (ctf_stype_t); 824 1.1 christos else 825 1.1 christos len = sizeof (ctf_type_t); 826 1.1 christos 827 1.1 christos memcpy (t, &dtd->dtd_data, len); 828 1.1 christos copied = (ctf_stype_t *) t; /* name is at the start: constant offset. */ 829 1.1 christos if (copied->ctt_name 830 1.1 christos && (name = ctf_strraw (fp, copied->ctt_name)) != NULL) 831 1.1.1.3 christos ctf_str_add_ref (fp, name, &copied->ctt_name); 832 1.1 christos copied->ctt_size = type_ctt_size; 833 1.1 christos t += len; 834 1.1 christos 835 1.1 christos switch (kind) 836 1.1 christos { 837 1.1 christos case CTF_K_INTEGER: 838 1.1 christos case CTF_K_FLOAT: 839 1.1 christos memcpy (t, dtd->dtd_vlen, sizeof (uint32_t)); 840 1.1 christos t += sizeof (uint32_t); 841 1.1 christos break; 842 1.1 christos 843 1.1 christos case CTF_K_SLICE: 844 1.1 christos memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_slice)); 845 1.1 christos t += sizeof (struct ctf_slice); 846 1.1 christos break; 847 1.1 christos 848 1.1 christos case CTF_K_ARRAY: 849 1.1 christos memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_array)); 850 1.1 christos t += sizeof (struct ctf_array); 851 1.1 christos break; 852 1.1 christos 853 1.1 christos case CTF_K_FUNCTION: 854 1.1 christos /* Functions with no args also have no vlen. */ 855 1.1 christos if (dtd->dtd_vlen) 856 1.1 christos memcpy (t, dtd->dtd_vlen, sizeof (uint32_t) * (vlen + (vlen & 1))); 857 1.1 christos t += sizeof (uint32_t) * (vlen + (vlen & 1)); 858 1.1 christos break; 859 1.1 christos 860 1.1 christos /* These need to be copied across element by element, depending on 861 1.1 christos their ctt_size. */ 862 1.1 christos case CTF_K_STRUCT: 863 1.1 christos case CTF_K_UNION: 864 1.1 christos { 865 1.1 christos ctf_lmember_t *dtd_vlen = (ctf_lmember_t *) dtd->dtd_vlen; 866 1.1 christos ctf_lmember_t *t_lvlen = (ctf_lmember_t *) t; 867 1.1 christos ctf_member_t *t_vlen = (ctf_member_t *) t; 868 1.1 christos 869 1.1 christos for (i = 0; i < vlen; i++) 870 1.1 christos { 871 1.1 christos const char *name = ctf_strraw (fp, dtd_vlen[i].ctlm_name); 872 1.1 christos 873 1.1 christos ctf_str_add_ref (fp, name, &dtd_vlen[i].ctlm_name); 874 1.1 christos 875 1.1 christos if (type_ctt_size < CTF_LSTRUCT_THRESH) 876 1.1 christos { 877 1.1 christos t_vlen[i].ctm_name = dtd_vlen[i].ctlm_name; 878 1.1 christos t_vlen[i].ctm_type = dtd_vlen[i].ctlm_type; 879 1.1 christos t_vlen[i].ctm_offset = CTF_LMEM_OFFSET (&dtd_vlen[i]); 880 1.1 christos ctf_str_add_ref (fp, name, &t_vlen[i].ctm_name); 881 1.1 christos } 882 1.1 christos else 883 1.1 christos { 884 1.1 christos t_lvlen[i] = dtd_vlen[i]; 885 1.1 christos ctf_str_add_ref (fp, name, &t_lvlen[i].ctlm_name); 886 1.1 christos } 887 1.1 christos } 888 1.1 christos } 889 1.1 christos 890 1.1 christos if (type_ctt_size < CTF_LSTRUCT_THRESH) 891 1.1 christos t += sizeof (ctf_member_t) * vlen; 892 1.1 christos else 893 1.1 christos t += sizeof (ctf_lmember_t) * vlen; 894 1.1 christos break; 895 1.1 christos 896 1.1 christos case CTF_K_ENUM: 897 1.1 christos { 898 1.1 christos ctf_enum_t *dtd_vlen = (struct ctf_enum *) dtd->dtd_vlen; 899 1.1 christos ctf_enum_t *t_vlen = (struct ctf_enum *) t; 900 1.1 christos 901 1.1 christos memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_enum) * vlen); 902 1.1 christos for (i = 0; i < vlen; i++) 903 1.1 christos { 904 1.1 christos const char *name = ctf_strraw (fp, dtd_vlen[i].cte_name); 905 1.1 christos 906 1.1 christos ctf_str_add_ref (fp, name, &t_vlen[i].cte_name); 907 1.1 christos ctf_str_add_ref (fp, name, &dtd_vlen[i].cte_name); 908 1.1 christos } 909 1.1 christos t += sizeof (struct ctf_enum) * vlen; 910 1.1 christos 911 1.1 christos break; 912 1.1 christos } 913 1.1 christos } 914 1.1 christos } 915 1.1 christos 916 1.1 christos *tptr = t; 917 1.1 christos } 918 1.1 christos 919 1.1 christos /* Variable section. */ 920 1.1 christos 921 1.1 christos /* Sort a newly-constructed static variable array. */ 922 1.1 christos 923 1.1 christos typedef struct ctf_sort_var_arg_cb 924 1.1 christos { 925 1.1 christos ctf_dict_t *fp; 926 1.1 christos ctf_strs_t *strtab; 927 1.1 christos } ctf_sort_var_arg_cb_t; 928 1.1 christos 929 1.1 christos static int 930 1.1 christos ctf_sort_var (const void *one_, const void *two_, void *arg_) 931 1.1 christos { 932 1.1 christos const ctf_varent_t *one = one_; 933 1.1 christos const ctf_varent_t *two = two_; 934 1.1 christos ctf_sort_var_arg_cb_t *arg = arg_; 935 1.1 christos 936 1.1 christos return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab), 937 1.1 christos ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab))); 938 1.1 christos } 939 1.1 christos 940 1.1 christos /* Overall serialization. */ 941 1.1 christos 942 1.1.1.3 christos /* Emit a new CTF dict which is a serialized copy of this one: also reify 943 1.1.1.3 christos the string table and update all offsets in the current dict suitably. 944 1.1.1.3 christos (This simplifies ctf-string.c a little, at the cost of storing a second 945 1.1.1.3 christos copy of the strtab if this dict was originally read in via ctf_open.) 946 1.1.1.3 christos 947 1.1.1.3 christos Other aspects of the existing dict are unchanged, although some 948 1.1.1.3 christos static entries may be duplicated in the dynamic state (which should 949 1.1.1.3 christos have no effect on visible operation). */ 950 1.1.1.3 christos 951 1.1.1.3 christos static unsigned char * 952 1.1.1.3 christos ctf_serialize (ctf_dict_t *fp, size_t *bufsiz) 953 1.1 christos { 954 1.1 christos ctf_header_t hdr, *hdrp; 955 1.1 christos ctf_dvdef_t *dvd; 956 1.1 christos ctf_varent_t *dvarents; 957 1.1.1.3 christos const ctf_strs_writable_t *strtab; 958 1.1.1.3 christos int sym_functions = 0; 959 1.1 christos 960 1.1 christos unsigned char *t; 961 1.1 christos unsigned long i; 962 1.1 christos size_t buf_size, type_size, objt_size, func_size; 963 1.1 christos size_t funcidx_size, objtidx_size; 964 1.1 christos size_t nvars; 965 1.1 christos unsigned char *buf = NULL, *newbuf; 966 1.1 christos 967 1.1 christos emit_symtypetab_state_t symstate; 968 1.1 christos memset (&symstate, 0, sizeof (emit_symtypetab_state_t)); 969 1.1 christos 970 1.1 christos /* Fill in an initial CTF header. We will leave the label, object, 971 1.1 christos and function sections empty and only output a header, type section, 972 1.1 christos and string table. The type section begins at a 4-byte aligned 973 1.1 christos boundary past the CTF header itself (at relative offset zero). The flag 974 1.1 christos indicating a new-style function info section (an array of CTF_K_FUNCTION 975 1.1 christos type IDs in the types section) is flipped on. */ 976 1.1 christos 977 1.1 christos memset (&hdr, 0, sizeof (hdr)); 978 1.1 christos hdr.cth_magic = CTF_MAGIC; 979 1.1 christos hdr.cth_version = CTF_VERSION; 980 1.1 christos 981 1.1 christos /* This is a new-format func info section, and the symtab and strtab come out 982 1.1 christos of the dynsym and dynstr these days. */ 983 1.1 christos hdr.cth_flags = (CTF_F_NEWFUNCINFO | CTF_F_DYNSTR); 984 1.1 christos 985 1.1.1.3 christos /* Propagate all symbols in the symtypetabs into the dynamic state, so that 986 1.1.1.3 christos we can put them back in the right order. Symbols already in the dynamic 987 1.1.1.3 christos state, likely due to repeated serialization, are left unchanged. */ 988 1.1.1.3 christos do 989 1.1.1.3 christos { 990 1.1.1.3 christos ctf_next_t *it = NULL; 991 1.1.1.3 christos const char *sym_name; 992 1.1.1.3 christos ctf_id_t sym; 993 1.1.1.3 christos 994 1.1.1.3 christos while ((sym = ctf_symbol_next_static (fp, &it, &sym_name, 995 1.1.1.3 christos sym_functions)) != CTF_ERR) 996 1.1.1.3 christos if ((ctf_add_funcobjt_sym_forced (fp, sym_functions, sym_name, sym)) < 0) 997 1.1.1.3 christos if (ctf_errno (fp) != ECTF_DUPLICATE) 998 1.1.1.3 christos return NULL; /* errno is set for us. */ 999 1.1.1.3 christos 1000 1.1.1.3 christos if (ctf_errno (fp) != ECTF_NEXT_END) 1001 1.1.1.3 christos return NULL; /* errno is set for us. */ 1002 1.1.1.3 christos } while (sym_functions++ < 1); 1003 1.1.1.3 christos 1004 1.1.1.3 christos /* Figure out how big the symtypetabs are now. */ 1005 1.1.1.3 christos 1006 1.1 christos if (ctf_symtypetab_sect_sizes (fp, &symstate, &hdr, &objt_size, &func_size, 1007 1.1 christos &objtidx_size, &funcidx_size) < 0) 1008 1.1.1.3 christos return NULL; /* errno is set for us. */ 1009 1.1.1.3 christos 1010 1.1.1.3 christos /* Propagate all vars into the dynamic state, so we can put them back later. 1011 1.1.1.3 christos Variables already in the dynamic state, likely due to repeated 1012 1.1.1.3 christos serialization, are left unchanged. */ 1013 1.1.1.3 christos 1014 1.1.1.3 christos for (i = 0; i < fp->ctf_nvars; i++) 1015 1.1.1.3 christos { 1016 1.1.1.3 christos const char *name = ctf_strptr (fp, fp->ctf_vars[i].ctv_name); 1017 1.1.1.3 christos 1018 1.1.1.3 christos if (name != NULL && !ctf_dvd_lookup (fp, name)) 1019 1.1.1.3 christos if (ctf_add_variable_forced (fp, name, fp->ctf_vars[i].ctv_type) < 0) 1020 1.1.1.3 christos return NULL; /* errno is set for us. */ 1021 1.1.1.3 christos } 1022 1.1 christos 1023 1.1 christos for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); 1024 1.1 christos dvd != NULL; dvd = ctf_list_next (dvd), nvars++); 1025 1.1 christos 1026 1.1 christos type_size = ctf_type_sect_size (fp); 1027 1.1 christos 1028 1.1 christos /* Compute the size of the CTF buffer we need, sans only the string table, 1029 1.1 christos then allocate a new buffer and memcpy the finished header to the start of 1030 1.1 christos the buffer. (We will adjust this later with strtab length info.) */ 1031 1.1 christos 1032 1.1 christos hdr.cth_lbloff = hdr.cth_objtoff = 0; 1033 1.1 christos hdr.cth_funcoff = hdr.cth_objtoff + objt_size; 1034 1.1 christos hdr.cth_objtidxoff = hdr.cth_funcoff + func_size; 1035 1.1 christos hdr.cth_funcidxoff = hdr.cth_objtidxoff + objtidx_size; 1036 1.1 christos hdr.cth_varoff = hdr.cth_funcidxoff + funcidx_size; 1037 1.1 christos hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t)); 1038 1.1 christos hdr.cth_stroff = hdr.cth_typeoff + type_size; 1039 1.1 christos hdr.cth_strlen = 0; 1040 1.1 christos 1041 1.1 christos buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen; 1042 1.1 christos 1043 1.1 christos if ((buf = malloc (buf_size)) == NULL) 1044 1.1.1.3 christos { 1045 1.1.1.3 christos ctf_set_errno (fp, EAGAIN); 1046 1.1.1.3 christos return NULL; 1047 1.1.1.3 christos } 1048 1.1 christos 1049 1.1 christos memcpy (buf, &hdr, sizeof (ctf_header_t)); 1050 1.1 christos t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_objtoff; 1051 1.1 christos 1052 1.1 christos hdrp = (ctf_header_t *) buf; 1053 1.1 christos if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL)) 1054 1.1 christos ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname); 1055 1.1 christos if (fp->ctf_cuname != NULL) 1056 1.1 christos ctf_str_add_ref (fp, fp->ctf_cuname, &hdrp->cth_cuname); 1057 1.1 christos 1058 1.1 christos if (ctf_emit_symtypetab_sects (fp, &symstate, &t, objt_size, func_size, 1059 1.1 christos objtidx_size, funcidx_size) < 0) 1060 1.1 christos goto err; 1061 1.1 christos 1062 1.1 christos assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff); 1063 1.1 christos 1064 1.1 christos /* Work over the variable list, translating everything into ctf_varent_t's and 1065 1.1 christos prepping the string table. */ 1066 1.1 christos 1067 1.1 christos dvarents = (ctf_varent_t *) t; 1068 1.1 christos for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; 1069 1.1 christos dvd = ctf_list_next (dvd), i++) 1070 1.1 christos { 1071 1.1 christos ctf_varent_t *var = &dvarents[i]; 1072 1.1 christos 1073 1.1 christos ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name); 1074 1.1 christos var->ctv_type = (uint32_t) dvd->dvd_type; 1075 1.1 christos } 1076 1.1 christos assert (i == nvars); 1077 1.1 christos 1078 1.1 christos t += sizeof (ctf_varent_t) * nvars; 1079 1.1 christos 1080 1.1 christos assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff); 1081 1.1 christos 1082 1.1.1.3 christos /* Copy in existing static types, then emit new dynamic types. */ 1083 1.1.1.3 christos 1084 1.1.1.3 christos memcpy (t, fp->ctf_buf + fp->ctf_header->cth_typeoff, 1085 1.1.1.3 christos fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff); 1086 1.1.1.3 christos t += fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff; 1087 1.1 christos ctf_emit_type_sect (fp, &t); 1088 1.1 christos 1089 1.1 christos assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff); 1090 1.1 christos 1091 1.1 christos /* Construct the final string table and fill out all the string refs with the 1092 1.1.1.3 christos final offsets. */ 1093 1.1.1.3 christos 1094 1.1 christos strtab = ctf_str_write_strtab (fp); 1095 1.1 christos 1096 1.1.1.3 christos if (strtab == NULL) 1097 1.1 christos goto oom; 1098 1.1 christos 1099 1.1 christos /* Now the string table is constructed, we can sort the buffer of 1100 1.1 christos ctf_varent_t's. */ 1101 1.1.1.3 christos ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) strtab }; 1102 1.1 christos ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var, 1103 1.1 christos &sort_var_arg); 1104 1.1 christos 1105 1.1.1.3 christos if ((newbuf = realloc (buf, buf_size + strtab->cts_len)) == NULL) 1106 1.1.1.3 christos goto oom; 1107 1.1.1.3 christos 1108 1.1 christos buf = newbuf; 1109 1.1.1.3 christos memcpy (buf + buf_size, strtab->cts_strs, strtab->cts_len); 1110 1.1 christos hdrp = (ctf_header_t *) buf; 1111 1.1.1.3 christos hdrp->cth_strlen = strtab->cts_len; 1112 1.1 christos buf_size += hdrp->cth_strlen; 1113 1.1.1.3 christos *bufsiz = buf_size; 1114 1.1 christos 1115 1.1.1.3 christos return buf; 1116 1.1 christos 1117 1.1 christos oom: 1118 1.1.1.3 christos ctf_set_errno (fp, EAGAIN); 1119 1.1 christos err: 1120 1.1 christos free (buf); 1121 1.1.1.3 christos return NULL; /* errno is set for us. */ 1122 1.1 christos } 1123 1.1 christos 1124 1.1 christos /* File writing. */ 1125 1.1 christos 1126 1.1 christos /* Write the compressed CTF data stream to the specified gzFile descriptor. The 1127 1.1 christos whole stream is compressed, and cannot be read by CTF opening functions in 1128 1.1 christos this library until it is decompressed. (The functions below this one leave 1129 1.1 christos the header uncompressed, and the CTF opening functions work on them without 1130 1.1 christos manual decompression.) 1131 1.1 christos 1132 1.1 christos No support for (testing-only) endian-flipping. */ 1133 1.1 christos int 1134 1.1 christos ctf_gzwrite (ctf_dict_t *fp, gzFile fd) 1135 1.1 christos { 1136 1.1.1.3 christos unsigned char *buf; 1137 1.1.1.3 christos unsigned char *p; 1138 1.1.1.3 christos size_t bufsiz; 1139 1.1.1.3 christos size_t len, written = 0; 1140 1.1.1.3 christos 1141 1.1.1.3 christos if ((buf = ctf_serialize (fp, &bufsiz)) == NULL) 1142 1.1.1.3 christos return -1; /* errno is set for us. */ 1143 1.1 christos 1144 1.1.1.3 christos p = buf; 1145 1.1.1.3 christos while (written < bufsiz) 1146 1.1.1.3 christos { 1147 1.1.1.3 christos if ((len = gzwrite (fd, p, bufsiz - written)) <= 0) 1148 1.1.1.3 christos { 1149 1.1.1.3 christos free (buf); 1150 1.1.1.3 christos return (ctf_set_errno (fp, errno)); 1151 1.1.1.3 christos } 1152 1.1.1.3 christos written += len; 1153 1.1.1.3 christos p += len; 1154 1.1 christos } 1155 1.1 christos 1156 1.1.1.3 christos free (buf); 1157 1.1 christos return 0; 1158 1.1 christos } 1159 1.1 christos 1160 1.1 christos /* Optionally compress the specified CTF data stream and return it as a new 1161 1.1 christos dynamically-allocated string. Possibly write it with reversed 1162 1.1 christos endianness. */ 1163 1.1 christos unsigned char * 1164 1.1 christos ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold) 1165 1.1 christos { 1166 1.1.1.3 christos unsigned char *rawbuf; 1167 1.1.1.3 christos unsigned char *buf = NULL; 1168 1.1 christos unsigned char *bp; 1169 1.1.1.3 christos ctf_header_t *rawhp, *hp; 1170 1.1.1.3 christos unsigned char *src; 1171 1.1.1.3 christos size_t rawbufsiz; 1172 1.1.1.3 christos size_t alloc_len = 0; 1173 1.1.1.3 christos int uncompressed = 0; 1174 1.1 christos int flip_endian; 1175 1.1 christos int rc; 1176 1.1 christos 1177 1.1 christos flip_endian = getenv ("LIBCTF_WRITE_FOREIGN_ENDIAN") != NULL; 1178 1.1 christos 1179 1.1.1.3 christos if ((rawbuf = ctf_serialize (fp, &rawbufsiz)) == NULL) 1180 1.1 christos return NULL; /* errno is set for us. */ 1181 1.1 christos 1182 1.1.1.3 christos if (!ctf_assert (fp, rawbufsiz >= sizeof (ctf_header_t))) 1183 1.1.1.3 christos goto err; 1184 1.1.1.3 christos 1185 1.1.1.3 christos if (rawbufsiz >= threshold) 1186 1.1.1.3 christos alloc_len = compressBound (rawbufsiz - sizeof (ctf_header_t)) 1187 1.1.1.3 christos + sizeof (ctf_header_t); 1188 1.1.1.3 christos 1189 1.1.1.3 christos /* Trivial operation if the buffer is too small to bother compressing, and 1190 1.1.1.3 christos we're not doing a forced write-time flip. */ 1191 1.1.1.3 christos 1192 1.1.1.3 christos if (rawbufsiz < threshold) 1193 1.1.1.3 christos { 1194 1.1.1.3 christos alloc_len = rawbufsiz; 1195 1.1.1.3 christos uncompressed = 1; 1196 1.1.1.3 christos } 1197 1.1.1.3 christos 1198 1.1.1.3 christos if (!flip_endian && uncompressed) 1199 1.1.1.3 christos { 1200 1.1.1.3 christos *size = rawbufsiz; 1201 1.1.1.3 christos return rawbuf; 1202 1.1.1.3 christos } 1203 1.1.1.3 christos 1204 1.1.1.3 christos if ((buf = malloc (alloc_len)) == NULL) 1205 1.1 christos { 1206 1.1 christos ctf_set_errno (fp, ENOMEM); 1207 1.1 christos ctf_err_warn (fp, 0, 0, _("ctf_write_mem: cannot allocate %li bytes"), 1208 1.1.1.3 christos (unsigned long) (alloc_len)); 1209 1.1.1.3 christos goto err; 1210 1.1 christos } 1211 1.1 christos 1212 1.1.1.3 christos rawhp = (ctf_header_t *) rawbuf; 1213 1.1 christos hp = (ctf_header_t *) buf; 1214 1.1.1.3 christos memcpy (hp, rawbuf, sizeof (ctf_header_t)); 1215 1.1.1.3 christos bp = buf + sizeof (ctf_header_t); 1216 1.1.1.3 christos *size = sizeof (ctf_header_t); 1217 1.1 christos 1218 1.1.1.3 christos if (!uncompressed) 1219 1.1 christos hp->cth_flags |= CTF_F_COMPRESS; 1220 1.1 christos 1221 1.1.1.3 christos src = rawbuf + sizeof (ctf_header_t); 1222 1.1 christos 1223 1.1 christos if (flip_endian) 1224 1.1 christos { 1225 1.1 christos ctf_flip_header (hp); 1226 1.1.1.3 christos if (ctf_flip (fp, rawhp, src, 1) < 0) 1227 1.1.1.3 christos goto err; /* errno is set for us. */ 1228 1.1 christos } 1229 1.1 christos 1230 1.1.1.3 christos if (!uncompressed) 1231 1.1 christos { 1232 1.1.1.3 christos size_t compress_len = alloc_len - sizeof (ctf_header_t); 1233 1.1.1.3 christos 1234 1.1 christos if ((rc = compress (bp, (uLongf *) &compress_len, 1235 1.1.1.3 christos src, rawbufsiz - sizeof (ctf_header_t))) != Z_OK) 1236 1.1 christos { 1237 1.1 christos ctf_set_errno (fp, ECTF_COMPRESS); 1238 1.1 christos ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc)); 1239 1.1.1.3 christos goto err; 1240 1.1 christos } 1241 1.1 christos *size += compress_len; 1242 1.1 christos } 1243 1.1.1.3 christos else 1244 1.1.1.3 christos { 1245 1.1.1.3 christos memcpy (bp, src, rawbufsiz - sizeof (ctf_header_t)); 1246 1.1.1.3 christos *size += rawbufsiz - sizeof (ctf_header_t); 1247 1.1.1.3 christos } 1248 1.1 christos 1249 1.1.1.3 christos free (rawbuf); 1250 1.1 christos return buf; 1251 1.1.1.3 christos err: 1252 1.1.1.3 christos free (buf); 1253 1.1.1.3 christos free (rawbuf); 1254 1.1.1.3 christos return NULL; 1255 1.1 christos } 1256 1.1 christos 1257 1.1.1.3 christos /* Write the compressed CTF data stream to the specified file descriptor, 1258 1.1.1.3 christos possibly compressed. Internal only (for now). */ 1259 1.1 christos int 1260 1.1.1.3 christos ctf_write_thresholded (ctf_dict_t *fp, int fd, size_t threshold) 1261 1.1 christos { 1262 1.1 christos unsigned char *buf; 1263 1.1 christos unsigned char *bp; 1264 1.1 christos size_t tmp; 1265 1.1 christos ssize_t buf_len; 1266 1.1 christos ssize_t len; 1267 1.1 christos int err = 0; 1268 1.1 christos 1269 1.1.1.3 christos if ((buf = ctf_write_mem (fp, &tmp, threshold)) == NULL) 1270 1.1 christos return -1; /* errno is set for us. */ 1271 1.1 christos 1272 1.1 christos buf_len = tmp; 1273 1.1 christos bp = buf; 1274 1.1 christos 1275 1.1 christos while (buf_len > 0) 1276 1.1 christos { 1277 1.1 christos if ((len = write (fd, bp, buf_len)) < 0) 1278 1.1 christos { 1279 1.1 christos err = ctf_set_errno (fp, errno); 1280 1.1 christos ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing")); 1281 1.1 christos goto ret; 1282 1.1 christos } 1283 1.1 christos buf_len -= len; 1284 1.1 christos bp += len; 1285 1.1 christos } 1286 1.1 christos 1287 1.1 christos ret: 1288 1.1 christos free (buf); 1289 1.1 christos return err; 1290 1.1 christos } 1291 1.1 christos 1292 1.1.1.3 christos /* Compress the specified CTF data stream and write it to the specified file 1293 1.1.1.3 christos descriptor. */ 1294 1.1.1.3 christos int 1295 1.1.1.3 christos ctf_compress_write (ctf_dict_t *fp, int fd) 1296 1.1.1.3 christos { 1297 1.1.1.3 christos return ctf_write_thresholded (fp, fd, 0); 1298 1.1.1.3 christos } 1299 1.1.1.3 christos 1300 1.1 christos /* Write the uncompressed CTF data stream to the specified file descriptor. */ 1301 1.1 christos int 1302 1.1 christos ctf_write (ctf_dict_t *fp, int fd) 1303 1.1 christos { 1304 1.1.1.3 christos return ctf_write_thresholded (fp, fd, (size_t) -1); 1305 1.1 christos } 1306