X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=libctf%2Fctf-open.c;h=64081464425193b15314b69e4b360ffc78e6611b;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=9dcd274d31a750fc9a9bf1135b2a46a3dc9a4174;hpb=5ae6af75b50bb4137d286a14e2fd1e74cfa089f4;p=deliverable%2Fbinutils-gdb.git diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 9dcd274d31..6408146442 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -1,5 +1,5 @@ /* Opening CTF files. - Copyright (C) 2019 Free Software Foundation, Inc. + Copyright (C) 2019-2020 Free Software Foundation, Inc. This file is part of libctf. @@ -446,7 +446,7 @@ upgrade_types_v1 (ctf_file_t *fp, ctf_header_t *cth) number unchanged, so that LCTF_INFO_* still works on the as-yet-untranslated type info. */ - if ((ctf_base = ctf_alloc (fp->ctf_size + increase)) == NULL) + if ((ctf_base = malloc (fp->ctf_size + increase)) == NULL) return ECTF_ZALLOC; /* Start at ctf_buf, not ctf_base, to squeeze out the original header: we @@ -613,7 +613,7 @@ upgrade_types_v1 (ctf_file_t *fp, ctf_header_t *cth) assert ((size_t) t2p - (size_t) fp->ctf_buf == cth->cth_stroff); ctf_set_version (fp, cth, CTF_VERSION_1_UPGRADED_3); - ctf_free (old_ctf_base); + free (old_ctf_base); return 0; } @@ -655,7 +655,6 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) unsigned long pop[CTF_K_MAX + 1] = { 0 }; const ctf_type_t *tp; - ctf_hash_t *hp; uint32_t id, dst; uint32_t *xp; @@ -666,6 +665,8 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) int nlstructs = 0, nlunions = 0; int err; + assert (!(fp->ctf_flags & LCTF_RDWR)); + if (_libctf_unlikely_ (fp->ctf_version == CTF_VERSION_1)) { int err; @@ -717,32 +718,37 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) /* Now that we've counted up the number of each type, we can allocate the hash tables, type translation table, and pointer table. */ - if ((fp->ctf_structs = ctf_hash_create (pop[CTF_K_STRUCT], ctf_hash_string, - ctf_hash_eq_string)) == NULL) + if ((fp->ctf_structs.ctn_readonly + = ctf_hash_create (pop[CTF_K_STRUCT], ctf_hash_string, + ctf_hash_eq_string)) == NULL) return ENOMEM; - if ((fp->ctf_unions = ctf_hash_create (pop[CTF_K_UNION], ctf_hash_string, - ctf_hash_eq_string)) == NULL) + if ((fp->ctf_unions.ctn_readonly + = ctf_hash_create (pop[CTF_K_UNION], ctf_hash_string, + ctf_hash_eq_string)) == NULL) return ENOMEM; - if ((fp->ctf_enums = ctf_hash_create (pop[CTF_K_ENUM], ctf_hash_string, - ctf_hash_eq_string)) == NULL) + if ((fp->ctf_enums.ctn_readonly + = ctf_hash_create (pop[CTF_K_ENUM], ctf_hash_string, + ctf_hash_eq_string)) == NULL) return ENOMEM; - if ((fp->ctf_names = ctf_hash_create (pop[CTF_K_INTEGER] + - pop[CTF_K_FLOAT] + - pop[CTF_K_FUNCTION] + - pop[CTF_K_TYPEDEF] + - pop[CTF_K_POINTER] + - pop[CTF_K_VOLATILE] + - pop[CTF_K_CONST] + - pop[CTF_K_RESTRICT], - ctf_hash_string, - ctf_hash_eq_string)) == NULL) + if ((fp->ctf_names.ctn_readonly + = ctf_hash_create (pop[CTF_K_INTEGER] + + pop[CTF_K_FLOAT] + + pop[CTF_K_FUNCTION] + + pop[CTF_K_TYPEDEF] + + pop[CTF_K_POINTER] + + pop[CTF_K_VOLATILE] + + pop[CTF_K_CONST] + + pop[CTF_K_RESTRICT], + ctf_hash_string, + ctf_hash_eq_string)) == NULL) return ENOMEM; - fp->ctf_txlate = ctf_alloc (sizeof (uint32_t) * (fp->ctf_typemax + 1)); - fp->ctf_ptrtab = ctf_alloc (sizeof (uint32_t) * (fp->ctf_typemax + 1)); + fp->ctf_txlate = malloc (sizeof (uint32_t) * (fp->ctf_typemax + 1)); + fp->ctf_ptrtab_len = fp->ctf_typemax + 1; + fp->ctf_ptrtab = malloc (sizeof (uint32_t) * fp->ctf_ptrtab_len); if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL) return ENOMEM; /* Memory allocation failed. */ @@ -779,10 +785,11 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) root-visible version so that we can be sure to find it when checking for conflicting definitions in ctf_add_type(). */ - if (((ctf_hash_lookup_type (fp->ctf_names, fp, name)) == 0) + if (((ctf_hash_lookup_type (fp->ctf_names.ctn_readonly, + fp, name)) == 0) || (flag & CTF_ADD_ROOT)) { - err = ctf_hash_define_type (fp->ctf_names, fp, + err = ctf_hash_define_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); if (err != 0) @@ -797,7 +804,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_FUNCTION: - err = ctf_hash_insert_type (fp->ctf_names, fp, + err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); if (err != 0) @@ -805,7 +812,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_STRUCT: - err = ctf_hash_define_type (fp->ctf_structs, fp, + err = ctf_hash_define_type (fp->ctf_structs.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); @@ -817,7 +824,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_UNION: - err = ctf_hash_define_type (fp->ctf_unions, fp, + err = ctf_hash_define_type (fp->ctf_unions.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); @@ -829,7 +836,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_ENUM: - err = ctf_hash_define_type (fp->ctf_enums, fp, + err = ctf_hash_define_type (fp->ctf_enums.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); @@ -838,7 +845,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_TYPEDEF: - err = ctf_hash_insert_type (fp->ctf_names, fp, + err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); if (err != 0) @@ -846,32 +853,20 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) break; case CTF_K_FORWARD: - /* Only insert forward tags into the given hash if the type or tag - name is not already present. */ - switch (tp->ctt_type) - { - case CTF_K_STRUCT: - hp = fp->ctf_structs; - break; - case CTF_K_UNION: - hp = fp->ctf_unions; - break; - case CTF_K_ENUM: - hp = fp->ctf_enums; - break; - default: - hp = fp->ctf_structs; - } - - if (ctf_hash_lookup_type (hp, fp, name) == 0) - { - err = ctf_hash_insert_type (hp, fp, - LCTF_INDEX_TO_TYPE (fp, id, child), - tp->ctt_name); - if (err != 0) - return err; - } - break; + { + ctf_names_t *np = ctf_name_table (fp, tp->ctt_type); + /* Only insert forward tags into the given hash if the type or tag + name is not already present. */ + if (ctf_hash_lookup_type (np->ctn_readonly, fp, name) == 0) + { + err = ctf_hash_insert_type (np->ctn_readonly, fp, + LCTF_INDEX_TO_TYPE (fp, id, child), + tp->ctt_name); + if (err != 0) + return err; + } + break; + } case CTF_K_POINTER: /* If the type referenced by the pointer is in this CTF container, @@ -886,7 +881,7 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: - err = ctf_hash_insert_type (fp->ctf_names, fp, + err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp, LCTF_INDEX_TO_TYPE (fp, id, child), tp->ctt_name); if (err != 0) @@ -903,12 +898,14 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) } ctf_dprintf ("%lu total types processed\n", fp->ctf_typemax); - ctf_dprintf ("%u enum names hashed\n", ctf_hash_size (fp->ctf_enums)); + ctf_dprintf ("%u enum names hashed\n", + ctf_hash_size (fp->ctf_enums.ctn_readonly)); ctf_dprintf ("%u struct names hashed (%d long)\n", - ctf_hash_size (fp->ctf_structs), nlstructs); + ctf_hash_size (fp->ctf_structs.ctn_readonly), nlstructs); ctf_dprintf ("%u union names hashed (%d long)\n", - ctf_hash_size (fp->ctf_unions), nlunions); - ctf_dprintf ("%u base type names hashed\n", ctf_hash_size (fp->ctf_names)); + ctf_hash_size (fp->ctf_unions.ctn_readonly), nlunions); + ctf_dprintf ("%u base type names hashed\n", + ctf_hash_size (fp->ctf_names.ctn_readonly)); /* Make an additional pass through the pointer table to find pointers that point to anonymous typedef nodes. If we find one, modify the pointer table @@ -921,11 +918,11 @@ init_types (ctf_file_t *fp, ctf_header_t *cth) { tp = LCTF_INDEX_TO_TYPEPTR (fp, id); - if (LCTF_INFO_KIND (fp, tp->ctt_info) == CTF_K_TYPEDEF && - strcmp (ctf_strptr (fp, tp->ctt_name), "") == 0 && - LCTF_TYPE_ISCHILD (fp, tp->ctt_type) == child && - LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax) - fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = dst; + if (LCTF_INFO_KIND (fp, tp->ctt_info) == CTF_K_TYPEDEF + && strcmp (ctf_strptr (fp, tp->ctt_name), "") == 0 + && LCTF_TYPE_ISCHILD (fp, tp->ctt_type) == child + && LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax) + fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = dst; } } @@ -1197,6 +1194,29 @@ flip_ctf (ctf_header_t *cth, unsigned char *buf) return flip_types (buf + cth->cth_typeoff, cth->cth_stroff - cth->cth_typeoff); } +/* Set up the ctl hashes in a ctf_file_t. Called by both writable and + non-writable dictionary initialization. */ +void ctf_set_ctl_hashes (ctf_file_t *fp) +{ + /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an + array of type name prefixes and the corresponding ctf_hash to use. */ + fp->ctf_lookups[0].ctl_prefix = "struct"; + fp->ctf_lookups[0].ctl_len = strlen (fp->ctf_lookups[0].ctl_prefix); + fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs; + fp->ctf_lookups[1].ctl_prefix = "union"; + fp->ctf_lookups[1].ctl_len = strlen (fp->ctf_lookups[1].ctl_prefix); + fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions; + fp->ctf_lookups[2].ctl_prefix = "enum"; + fp->ctf_lookups[2].ctl_len = strlen (fp->ctf_lookups[2].ctl_prefix); + fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums; + fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR; + fp->ctf_lookups[3].ctl_len = strlen (fp->ctf_lookups[3].ctl_prefix); + fp->ctf_lookups[3].ctl_hash = &fp->ctf_names; + fp->ctf_lookups[4].ctl_prefix = NULL; + fp->ctf_lookups[4].ctl_len = 0; + fp->ctf_lookups[4].ctl_hash = NULL; +} + /* Open a CTF file, mocking up a suitable ctf_sect. */ ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size, @@ -1207,7 +1227,7 @@ ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size, { return ctf_simple_open_internal (ctfsect, ctfsect_size, symsect, symsect_size, symsect_entsize, strsect, strsect_size, NULL, - errp); + 0, errp); } /* Open a CTF file, mocking up a suitable ctf_sect and overriding the external @@ -1217,7 +1237,8 @@ ctf_file_t *ctf_simple_open_internal (const char *ctfsect, size_t ctfsect_size, const char *symsect, size_t symsect_size, size_t symsect_entsize, const char *strsect, size_t strsect_size, - ctf_dynhash_t *syn_strtab, int *errp) + ctf_dynhash_t *syn_strtab, int writable, + int *errp) { ctf_sect_t skeleton; @@ -1254,7 +1275,8 @@ ctf_file_t *ctf_simple_open_internal (const char *ctfsect, size_t ctfsect_size, strsectp = &str_sect; } - return ctf_bufopen_internal (ctfsectp, symsectp, strsectp, syn_strtab, errp); + return ctf_bufopen_internal (ctfsectp, symsectp, strsectp, syn_strtab, + writable, errp); } /* Decode the specified CTF buffer and optional symbol table, and create a new @@ -1266,7 +1288,7 @@ ctf_file_t * ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, const ctf_sect_t *strsect, int *errp) { - return ctf_bufopen_internal (ctfsect, symsect, strsect, NULL, errp); + return ctf_bufopen_internal (ctfsect, symsect, strsect, NULL, 0, errp); } /* Like ctf_bufopen, but overriding the external strtab with a synthetic one. */ @@ -1274,7 +1296,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_file_t * ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, const ctf_sect_t *strsect, ctf_dynhash_t *syn_strtab, - int *errp) + int writable, int *errp) { const ctf_preamble_t *pp; size_t hdrsz = sizeof (ctf_header_t); @@ -1348,14 +1370,17 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (ctfsect->cts_size < hdrsz) return (ctf_set_open_errno (errp, ECTF_NOCTFBUF)); - if ((fp = ctf_alloc (sizeof (ctf_file_t))) == NULL) + if ((fp = malloc (sizeof (ctf_file_t))) == NULL) return (ctf_set_open_errno (errp, ENOMEM)); memset (fp, 0, sizeof (ctf_file_t)); - if ((fp->ctf_header = ctf_alloc (sizeof (struct ctf_header))) == NULL) + if (writable) + fp->ctf_flags |= LCTF_RDWR; + + if ((fp->ctf_header = malloc (sizeof (struct ctf_header))) == NULL) { - ctf_free (fp); + free (fp); return (ctf_set_open_errno (errp, ENOMEM)); } hp = fp->ctf_header; @@ -1410,7 +1435,7 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, /* We are allocating this ourselves, so we can drop the ctf header copy in favour of ctf->ctf_header. */ - if ((fp->ctf_base = ctf_alloc (fp->ctf_size)) == NULL) + if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL) { err = ECTF_ZALLOC; goto bad; @@ -1441,7 +1466,7 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, } else if (foreign_endian) { - if ((fp->ctf_base = ctf_alloc (fp->ctf_size)) == NULL) + if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL) { err = ECTF_ZALLOC; goto bad; @@ -1481,11 +1506,23 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, } if (fp->ctf_data.cts_name != NULL) - fp->ctf_data.cts_name = ctf_strdup (fp->ctf_data.cts_name); + if ((fp->ctf_data.cts_name = strdup (fp->ctf_data.cts_name)) == NULL) + { + err = ENOMEM; + goto bad; + } if (fp->ctf_symtab.cts_name != NULL) - fp->ctf_symtab.cts_name = ctf_strdup (fp->ctf_symtab.cts_name); + if ((fp->ctf_symtab.cts_name = strdup (fp->ctf_symtab.cts_name)) == NULL) + { + err = ENOMEM; + goto bad; + } if (fp->ctf_strtab.cts_name != NULL) - fp->ctf_strtab.cts_name = ctf_strdup (fp->ctf_strtab.cts_name); + if ((fp->ctf_strtab.cts_name = strdup (fp->ctf_strtab.cts_name)) == NULL) + { + err = ENOMEM; + goto bad; + } if (fp->ctf_data.cts_name == NULL) fp->ctf_data.cts_name = _CTF_NULLSTR; @@ -1505,8 +1542,8 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, (err = flip_ctf (hp, fp->ctf_buf)) != 0) { /* We can be certain that flip_ctf() will have endian-flipped everything - other than the types table when we return. In particular the header - is fine, so set it, to allow freeing to use the usual code path. */ + other than the types table when we return. In particular the header + is fine, so set it, to allow freeing to use the usual code path. */ ctf_set_base (fp, hp, fp->ctf_base); goto bad; @@ -1514,6 +1551,14 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_set_base (fp, hp, fp->ctf_base); + /* No need to do anything else for dynamic containers: they do not support + symbol lookups, and the type table is maintained in the dthashes. */ + if (fp->ctf_flags & LCTF_RDWR) + { + fp->ctf_refcnt = 1; + return fp; + } + if ((err = init_types (fp, hp)) != 0) goto bad; @@ -1525,7 +1570,7 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (symsect != NULL) { fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize; - fp->ctf_sxlate = ctf_alloc (fp->ctf_nsyms * sizeof (uint32_t)); + fp->ctf_sxlate = malloc (fp->ctf_nsyms * sizeof (uint32_t)); if (fp->ctf_sxlate == NULL) { @@ -1537,24 +1582,7 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, goto bad; } - /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an - array of type name prefixes and the corresponding ctf_hash to use. - NOTE: This code must be kept in sync with the code in ctf_update(). */ - fp->ctf_lookups[0].ctl_prefix = "struct"; - fp->ctf_lookups[0].ctl_len = strlen (fp->ctf_lookups[0].ctl_prefix); - fp->ctf_lookups[0].ctl_hash = fp->ctf_structs; - fp->ctf_lookups[1].ctl_prefix = "union"; - fp->ctf_lookups[1].ctl_len = strlen (fp->ctf_lookups[1].ctl_prefix); - fp->ctf_lookups[1].ctl_hash = fp->ctf_unions; - fp->ctf_lookups[2].ctl_prefix = "enum"; - fp->ctf_lookups[2].ctl_len = strlen (fp->ctf_lookups[2].ctl_prefix); - fp->ctf_lookups[2].ctl_hash = fp->ctf_enums; - fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR; - fp->ctf_lookups[3].ctl_len = strlen (fp->ctf_lookups[3].ctl_prefix); - fp->ctf_lookups[3].ctl_hash = fp->ctf_names; - fp->ctf_lookups[4].ctl_prefix = NULL; - fp->ctf_lookups[4].ctl_len = 0; - fp->ctf_lookups[4].ctl_hash = NULL; + ctf_set_ctl_hashes (fp); if (symsect != NULL) { @@ -1597,8 +1625,8 @@ ctf_file_close (ctf_file_t *fp) return; } - ctf_free (fp->ctf_dyncuname); - ctf_free (fp->ctf_dynparname); + free (fp->ctf_dyncuname); + free (fp->ctf_dynparname); ctf_file_close (fp->ctf_parent); for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) @@ -1607,7 +1635,20 @@ ctf_file_close (ctf_file_t *fp) ctf_dtd_delete (fp, dtd); } ctf_dynhash_destroy (fp->ctf_dthash); - ctf_dynhash_destroy (fp->ctf_dtbyname); + if (fp->ctf_flags & LCTF_RDWR) + { + ctf_dynhash_destroy (fp->ctf_structs.ctn_writable); + ctf_dynhash_destroy (fp->ctf_unions.ctn_writable); + ctf_dynhash_destroy (fp->ctf_enums.ctn_writable); + ctf_dynhash_destroy (fp->ctf_names.ctn_writable); + } + else + { + ctf_hash_destroy (fp->ctf_structs.ctn_readonly); + ctf_hash_destroy (fp->ctf_unions.ctn_readonly); + ctf_hash_destroy (fp->ctf_enums.ctn_readonly); + ctf_hash_destroy (fp->ctf_names.ctn_readonly); + } for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd) { @@ -1616,38 +1657,34 @@ ctf_file_close (ctf_file_t *fp) } ctf_dynhash_destroy (fp->ctf_dvhash); ctf_str_free_atoms (fp); - ctf_free (fp->ctf_tmp_typeslice); + free (fp->ctf_tmp_typeslice); if (fp->ctf_data.cts_name != _CTF_NULLSTR) - ctf_free ((char *) fp->ctf_data.cts_name); + free ((char *) fp->ctf_data.cts_name); if (fp->ctf_symtab.cts_name != _CTF_NULLSTR) - ctf_free ((char *) fp->ctf_symtab.cts_name); + free ((char *) fp->ctf_symtab.cts_name); if (fp->ctf_strtab.cts_name != _CTF_NULLSTR) - ctf_free ((char *) fp->ctf_strtab.cts_name); + free ((char *) fp->ctf_strtab.cts_name); else if (fp->ctf_data_mmapped) ctf_munmap (fp->ctf_data_mmapped, fp->ctf_data_mmapped_len); - ctf_free (fp->ctf_dynbase); + free (fp->ctf_dynbase); ctf_dynhash_destroy (fp->ctf_syn_ext_strtab); ctf_dynhash_destroy (fp->ctf_link_inputs); ctf_dynhash_destroy (fp->ctf_link_outputs); ctf_dynhash_destroy (fp->ctf_link_type_mapping); ctf_dynhash_destroy (fp->ctf_link_cu_mapping); + ctf_dynhash_destroy (fp->ctf_add_processing); - ctf_free (fp->ctf_sxlate); - ctf_free (fp->ctf_txlate); - ctf_free (fp->ctf_ptrtab); - - ctf_hash_destroy (fp->ctf_structs); - ctf_hash_destroy (fp->ctf_unions); - ctf_hash_destroy (fp->ctf_enums); - ctf_hash_destroy (fp->ctf_names); + free (fp->ctf_sxlate); + free (fp->ctf_txlate); + free (fp->ctf_ptrtab); - ctf_free (fp->ctf_header); - ctf_free (fp); + free (fp->ctf_header); + free (fp); } /* The converse of ctf_open(). ctf_open() disguises whatever it opens as an @@ -1670,7 +1707,7 @@ ctf_get_arc (const ctf_file_t *fp) structure, not a pointer to it, since that is likely to become a pointer to freed data before the return value is used under the expected use case of ctf_getsect()/ ctf_file_close()/free(). */ -extern ctf_sect_t +ctf_sect_t ctf_getdatasect (const ctf_file_t *fp) { return fp->ctf_data; @@ -1694,14 +1731,16 @@ ctf_parent_name (ctf_file_t *fp) /* Set the parent name. It is an error to call this routine without calling ctf_import() at some point. */ -void +int ctf_parent_name_set (ctf_file_t *fp, const char *name) { if (fp->ctf_dynparname != NULL) - ctf_free (fp->ctf_dynparname); + free (fp->ctf_dynparname); - fp->ctf_dynparname = ctf_strdup (name); + if ((fp->ctf_dynparname = strdup (name)) == NULL) + return (ctf_set_errno (fp, ENOMEM)); fp->ctf_parname = fp->ctf_dynparname; + return 0; } /* Return the name of the compilation unit this CTF file applies to. Usually @@ -1713,14 +1752,16 @@ ctf_cuname (ctf_file_t *fp) } /* Set the compilation unit name. */ -void +int ctf_cuname_set (ctf_file_t *fp, const char *name) { if (fp->ctf_dyncuname != NULL) - ctf_free (fp->ctf_dyncuname); + free (fp->ctf_dyncuname); - fp->ctf_dyncuname = ctf_strdup (name); + if ((fp->ctf_dyncuname = strdup (name)) == NULL) + return (ctf_set_errno (fp, ENOMEM)); fp->ctf_cuname = fp->ctf_dyncuname; + return 0; } /* Import the types from the specified parent container by storing a pointer @@ -1736,16 +1777,24 @@ ctf_import (ctf_file_t *fp, ctf_file_t *pfp) return (ctf_set_errno (fp, ECTF_DMODEL)); if (fp->ctf_parent != NULL) - ctf_file_close (fp->ctf_parent); + { + fp->ctf_parent->ctf_refcnt--; + ctf_file_close (fp->ctf_parent); + fp->ctf_parent = NULL; + } if (pfp != NULL) { - fp->ctf_flags |= LCTF_CHILD; - pfp->ctf_refcnt++; + int err; if (fp->ctf_parname == NULL) - ctf_parent_name_set (fp, "PARENT"); + if ((err = ctf_parent_name_set (fp, "PARENT")) < 0) + return err; + + fp->ctf_flags |= LCTF_CHILD; + pfp->ctf_refcnt++; } + fp->ctf_parent = pfp; return 0; }