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