• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修訂dde074f887ff9f45dec8155aefcba7054c98f5b6 (tree)
時間2019-09-24 22:06:32
作者Nick Alcock <nick.alcock@orac...>
CommiterNick Alcock

Log Message

libctf: properly handle ctf_add_type of forwards and self-reffing structs

The code to handle structures (and unions) that refer to themselves in
ctf_add_type is extremely dodgy. It works by looking through the list
of not-yet-committed types for a structure with the same name as the
structure in question and assuming, if it finds it, that this must be a
reference to the same type. This is a linear search that gets ever
slower as the dictionary grows, requiring you to call ctf_update at
intervals to keep performance tolerable: but if you do that, you run
into the problem that if a forward declared before the ctf_update is
changed to a structure afterwards, ctf_update explodes.

The last commit fixed most of this: this commit can use it, adding a new
ctf_add_processing hash that tracks source type IDs that are currently
being processed and uses it to avoid infinite recursion rather than the
dynamic type list: we split ctf_add_type into a ctf_add_type_internal,
so that ctf_add_type itself can become a wrapper that empties out this
being-processed hash once the entire recursive type addition is over.
Structure additions themselves avoid adding their dependent types
quite so much by checking the type mapping and avoiding re-adding types
we already know we have added.

We also add support for adding forwards to dictionaries that already
contain the thing they are a forward to: we just silently return the
original type.

v4: return existing struct/union/enum types properly, rather than using

an uninitialized variable: shrinks sizes of CTF sections back down
to roughly where they were in v1/v2 of this patch series.

libctf/
* ctf-impl.h (ctf_file_t) <ctf_add_processing>: New.
* ctf-open.c (ctf_file_close): Free it.
* ctf-create.c (ctf_serialize): Adjust.
(membcmp): When reporting a conflict due to an error, report the
error.
(ctf_add_type): Turn into a ctf_add_processing wrapper. Rename to...
(ctf_add_type_internal): ... this. Hand back types we are already
in the middle of adding immediately. Hand back structs/unions with
the same number of members immediately. Do not walk the dynamic
list. Call ctf_add_type_internal, not ctf_add_type. Handle
forwards promoted to other types and the inverse case identically.
Add structs to the mapping as soon as we intern them, before they
gain any members.

Change Summary

差異

--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,19 @@
1+2019-08-07 Nick Alcock <nick.alcock@oracle.com>
2+
3+ * ctf-impl.h (ctf_file_t) <ctf_add_processing>: New.
4+ * ctf-open.c (ctf_file_close): Free it.
5+ * ctf-create.c (ctf_serialize): Adjust.
6+ (membcmp): When reporting a conflict due to an error, report the
7+ error.
8+ (ctf_add_type): Turn into a ctf_add_processing wrapper. Rename to...
9+ (ctf_add_type_internal): ... this. Hand back types we are already
10+ in the middle of adding immediately. Hand back structs/unions with
11+ the same number of members immediately. Do not walk the dynamic
12+ list. Call ctf_add_type_internal, not ctf_add_type. Handle
13+ forwards promoted to other types and the inverse case identically.
14+ Add structs to the mapping as soon as we intern them, before they
15+ gain any members.
16+
117 2019-08-09 Nick Alcock <nick.alcock@oracle.com>
218
319 * ctf-impl.h (ctf_names_t): New.
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -525,6 +525,7 @@ ctf_serialize (ctf_file_t *fp)
525525 nfp->ctf_dvhash = fp->ctf_dvhash;
526526 nfp->ctf_dvdefs = fp->ctf_dvdefs;
527527 nfp->ctf_dtoldid = fp->ctf_dtoldid;
528+ nfp->ctf_add_processing = fp->ctf_add_processing;
528529 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
529530 nfp->ctf_specific = fp->ctf_specific;
530531 nfp->ctf_ptrtab = fp->ctf_ptrtab;
@@ -553,6 +554,7 @@ ctf_serialize (ctf_file_t *fp)
553554 fp->ctf_str_atoms = NULL;
554555 fp->ctf_prov_strtab = NULL;
555556 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
557+ fp->ctf_add_processing = NULL;
556558 fp->ctf_ptrtab = NULL;
557559 fp->ctf_link_inputs = NULL;
558560 fp->ctf_link_outputs = NULL;
@@ -1527,7 +1529,8 @@ enumcmp (const char *name, int value, void *arg)
15271529
15281530 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
15291531 {
1530- ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1532+ ctf_dprintf ("Conflict due to member %s iteration error: %s.\n", name,
1533+ ctf_errmsg (ctf_errno (ctb->ctb_file)));
15311534 return 1;
15321535 }
15331536 if (value != bvalue)
@@ -1557,7 +1560,8 @@ membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
15571560
15581561 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
15591562 {
1560- ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1563+ ctf_dprintf ("Conflict due to member %s iteration error: %s.\n", name,
1564+ ctf_errmsg (ctf_errno (ctb->ctb_file)));
15611565 return 1;
15621566 }
15631567 if (ctm.ctm_offset != offset)
@@ -1603,11 +1607,13 @@ membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
16031607 following the source type's links and embedded member types. If the
16041608 destination container already contains a named type which has the same
16051609 attributes, then we succeed and return this type but no changes occur. */
1606-ctf_id_t
1607-ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1610+static ctf_id_t
1611+ctf_add_type_internal (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type,
1612+ ctf_file_t *proc_tracking_fp)
16081613 {
16091614 ctf_id_t dst_type = CTF_ERR;
16101615 uint32_t dst_kind = CTF_K_UNKNOWN;
1616+ ctf_file_t *tmp_fp = dst_fp;
16111617 ctf_id_t tmp;
16121618
16131619 const char *name;
@@ -1618,7 +1624,6 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
16181624 ctf_encoding_t src_en, dst_en;
16191625 ctf_arinfo_t src_ar, dst_ar;
16201626
1621- ctf_dtdef_t *dtd;
16221627 ctf_funcinfo_t ctc;
16231628
16241629 ctf_id_t orig_src_type = src_type;
@@ -1638,6 +1643,33 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
16381643 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
16391644 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
16401645
1646+ /* If this is a type we are currently in the middle of adding, hand it
1647+ straight back. (This lets us handle self-referential structures without
1648+ considering forwards and empty structures the same as their completed
1649+ forms.) */
1650+
1651+ tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
1652+
1653+ if (tmp != 0)
1654+ {
1655+ if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
1656+ (void *) (uintptr_t) src_type))
1657+ return tmp;
1658+
1659+ /* If this type has already been added from this container, and is the same
1660+ kind and (if a struct or union) has the same number of members, hand it
1661+ straight back. */
1662+
1663+ if ((ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
1664+ && (kind == CTF_K_STRUCT || kind == CTF_K_UNION
1665+ || kind == CTF_K_ENUM))
1666+ {
1667+ if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
1668+ if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
1669+ return tmp;
1670+ }
1671+ }
1672+
16411673 forward_kind = kind;
16421674 if (kind == CTF_K_FORWARD)
16431675 forward_kind = src_tp->ctt_type;
@@ -1697,6 +1729,9 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
16971729 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
16981730 return CTF_ERR;
16991731
1732+ if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1733+ return CTF_ERR; /* errno set for us. */
1734+
17001735 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
17011736 {
17021737 /* The type that we found in the hash is also root-visible. If
@@ -1705,9 +1740,6 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
17051740 even if there is no conflict: we must check the contained type
17061741 too. */
17071742
1708- if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1709- return CTF_ERR; /* errno set for us. */
1710-
17111743 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
17121744 {
17131745 if (kind != CTF_K_SLICE)
@@ -1723,71 +1755,17 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
17231755 }
17241756 else
17251757 {
1726- /* We found a non-root-visible type in the hash. We reset
1727- dst_type to ensure that we continue to look for a possible
1728- conflict in the pending list. */
1729-
1730- dst_type = CTF_ERR;
1731- }
1732- }
1733- }
1734-
1735- /* If the non-empty name was not found in the appropriate hash, search
1736- the list of pending dynamic definitions that are not yet committed.
1737- If a matching name and kind are found, assume this is the type that
1738- we are looking for. This is necessary to permit ctf_add_type() to
1739- operate recursively on entities such as a struct that contains a
1740- pointer member that refers to the same struct type. */
1741-
1742- if (dst_type == CTF_ERR && name[0] != '\0')
1743- {
1744- for (dtd = ctf_list_prev (&dst_fp->ctf_dtdefs); dtd != NULL
1745- && LCTF_TYPE_TO_INDEX (src_fp, dtd->dtd_type) > dst_fp->ctf_dtoldid;
1746- dtd = ctf_list_prev (dtd))
1747- {
1748- const char *ctt_name;
1749-
1750- if (LCTF_INFO_KIND (src_fp, dtd->dtd_data.ctt_info) == kind
1751- && dtd->dtd_data.ctt_name
1752- && ((ctt_name = ctf_strraw (src_fp, dtd->dtd_data.ctt_name)) != NULL)
1753- && strcmp (ctt_name, name) == 0)
1754- {
1755- int sroot; /* Is the src root-visible? */
1756- int droot; /* Is the dst root-visible? */
1757- int match; /* Do the encodings match? */
1758-
1759- if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
1760- {
1761- ctf_add_type_mapping (src_fp, src_type, dst_fp, dtd->dtd_type);
1762- return dtd->dtd_type;
1763- }
1764-
1765- sroot = (flag & CTF_ADD_ROOT);
1766- droot = (LCTF_INFO_ISROOT (dst_fp,
1767- dtd->dtd_data.
1768- ctt_info) & CTF_ADD_ROOT);
1758+ /* We found a non-root-visible type in the hash. If its encoding
1759+ is the same, we can reuse it, unless it is a slice. */
17691760
1770- match = (memcmp (&src_en, &dtd->dtd_u.dtu_enc,
1771- sizeof (ctf_encoding_t)) == 0);
1772-
1773- /* If the types share the same encoding then return the id of the
1774- first unless one type is root-visible and the other is not; in
1775- that case the new type must get a new id if a match is never
1776- found. Note: slices are not certain to match even if there is
1777- no conflict: we must check the contained type too. */
1778-
1779- if (match && sroot == droot)
1761+ if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
17801762 {
17811763 if (kind != CTF_K_SLICE)
17821764 {
1783- ctf_add_type_mapping (src_fp, src_type, dst_fp, dtd->dtd_type);
1784- return dtd->dtd_type;
1765+ ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1766+ return dst_type;
17851767 }
17861768 }
1787- else if (!match && sroot && droot)
1788- {
1789- return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1790- }
17911769 }
17921770 }
17931771 }
@@ -1800,10 +1778,18 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
18001778 dst.ctb_type = dst_type;
18011779 dst.ctb_dtd = NULL;
18021780
1803- /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1804- we add a new type with the same properties as src_type to dst_fp.
1805- If dst_type is not CTF_ERR, then we verify that dst_type has the
1806- same attributes as src_type. We recurse for embedded references. */
1781+ /* Now perform kind-specific processing. If dst_type is CTF_ERR, then we add
1782+ a new type with the same properties as src_type to dst_fp. If dst_type is
1783+ not CTF_ERR, then we verify that dst_type has the same attributes as
1784+ src_type. We recurse for embedded references. Before we start, we note
1785+ that we are processing this type, to prevent infinite recursion: we do not
1786+ re-process any type that appears in this list. The list is emptied
1787+ wholesale at the end of processing everything in this recursive stack. */
1788+
1789+ if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
1790+ (void *) (uintptr_t) src_type, (void *) 1) < 0)
1791+ return ctf_set_errno (dst_fp, ENOMEM);
1792+
18071793 switch (kind)
18081794 {
18091795 case CTF_K_INTEGER:
@@ -1822,7 +1808,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
18221808 /* We have checked for conflicting encodings: now try to add the
18231809 contained type. */
18241810 src_type = ctf_type_reference (src_fp, src_type);
1825- dst_type = ctf_add_type (dst_fp, src_fp, src_type);
1811+ src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1812+ proc_tracking_fp);
18261813
18271814 if (src_type == CTF_ERR)
18281815 return CTF_ERR; /* errno is set for us. */
@@ -1835,7 +1822,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
18351822 case CTF_K_CONST:
18361823 case CTF_K_RESTRICT:
18371824 src_type = ctf_type_reference (src_fp, src_type);
1838- src_type = ctf_add_type (dst_fp, src_fp, src_type);
1825+ src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1826+ proc_tracking_fp);
18391827
18401828 if (src_type == CTF_ERR)
18411829 return CTF_ERR; /* errno is set for us. */
@@ -1848,8 +1836,11 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
18481836 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
18491837
18501838 src_ar.ctr_contents =
1851- ctf_add_type (dst_fp, src_fp, src_ar.ctr_contents);
1852- src_ar.ctr_index = ctf_add_type (dst_fp, src_fp, src_ar.ctr_index);
1839+ ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
1840+ proc_tracking_fp);
1841+ src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
1842+ src_ar.ctr_index,
1843+ proc_tracking_fp);
18531844 src_ar.ctr_nelems = src_ar.ctr_nelems;
18541845
18551846 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
@@ -1876,7 +1867,9 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
18761867 break;
18771868
18781869 case CTF_K_FUNCTION:
1879- ctc.ctc_return = ctf_add_type (dst_fp, src_fp, src_tp->ctt_type);
1870+ ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
1871+ src_tp->ctt_type,
1872+ proc_tracking_fp);
18801873 ctc.ctc_argc = 0;
18811874 ctc.ctc_flags = 0;
18821875
@@ -1893,6 +1886,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
18931886 int errs = 0;
18941887 size_t size;
18951888 ssize_t ssize;
1889+ ctf_dtdef_t *dtd;
18961890
18971891 /* Technically to match a struct or union we need to check both
18981892 ways (src members vs. dst, dst members vs. src) but we make
@@ -1902,7 +1896,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
19021896 This optimization can be defeated for unions, but is so
19031897 pathological as to render it irrelevant for our purposes. */
19041898
1905- if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1899+ if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1900+ && dst_kind != CTF_K_FORWARD)
19061901 {
19071902 if (ctf_type_size (src_fp, src_type) !=
19081903 ctf_type_size (dst_fp, dst_type))
@@ -1936,6 +1931,10 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
19361931 dst.ctb_type = dst_type;
19371932 dst.ctb_dtd = dtd;
19381933
1934+ /* Pre-emptively add this struct to the type mapping so that
1935+ structures that refer to themselves work. */
1936+ ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1937+
19391938 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
19401939 errs++; /* Increment errs and fail at bottom of case. */
19411940
@@ -1963,12 +1962,22 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
19631962 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
19641963 dmd != NULL; dmd = ctf_list_next (dmd))
19651964 {
1966- if ((dmd->dmd_type = ctf_add_type (dst_fp, src_fp,
1967- dmd->dmd_type)) == CTF_ERR)
1968- {
1969- if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
1970- errs++;
1971- }
1965+ ctf_file_t *dst = dst_fp;
1966+ ctf_id_t memb_type;
1967+
1968+ memb_type = ctf_type_mapping (src_fp, dmd->dmd_type, &dst);
1969+ if (memb_type == 0)
1970+ {
1971+ if ((dmd->dmd_type =
1972+ ctf_add_type_internal (dst_fp, src_fp, dmd->dmd_type,
1973+ proc_tracking_fp)) == CTF_ERR)
1974+ {
1975+ if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
1976+ errs++;
1977+ }
1978+ }
1979+ else
1980+ dmd->dmd_type = memb_type;
19721981 }
19731982
19741983 if (errs)
@@ -1977,7 +1986,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
19771986 }
19781987
19791988 case CTF_K_ENUM:
1980- if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1989+ if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1990+ && dst_kind != CTF_K_FORWARD)
19811991 {
19821992 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
19831993 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
@@ -2003,7 +2013,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
20032013
20042014 case CTF_K_TYPEDEF:
20052015 src_type = ctf_type_reference (src_fp, src_type);
2006- src_type = ctf_add_type (dst_fp, src_fp, src_type);
2016+ src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
2017+ proc_tracking_fp);
20072018
20082019 if (src_type == CTF_ERR)
20092020 return CTF_ERR; /* errno is set for us. */
@@ -2017,9 +2028,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
20172028 equivalent. */
20182029
20192030 if (dst_type == CTF_ERR)
2020- {
20212031 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
2022- }
2032+
20232033 break;
20242034
20252035 default:
@@ -2031,6 +2041,27 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
20312041 return dst_type;
20322042 }
20332043
2044+ctf_id_t
2045+ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
2046+{
2047+ ctf_id_t id;
2048+
2049+ if (!src_fp->ctf_add_processing)
2050+ src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
2051+ ctf_hash_eq_integer,
2052+ NULL, NULL);
2053+
2054+ /* We store the hash on the source, because it contains only source type IDs:
2055+ but callers will invariably expect errors to appear on the dest. */
2056+ if (!src_fp->ctf_add_processing)
2057+ return (ctf_set_errno (dst_fp, ENOMEM));
2058+
2059+ id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
2060+ ctf_dynhash_empty (src_fp->ctf_add_processing);
2061+
2062+ return id;
2063+}
2064+
20342065 /* Write the compressed CTF data stream to the specified gzFile descriptor. */
20352066 int
20362067 ctf_gzwrite (ctf_file_t *fp, gzFile fd)
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -294,6 +294,7 @@ struct ctf_file
294294 /* Allow the caller to Change the name of link archive members. */
295295 ctf_link_memb_name_changer_f *ctf_link_memb_name_changer;
296296 void *ctf_link_memb_name_changer_arg; /* Argument for it. */
297+ ctf_dynhash_t *ctf_add_processing; /* Types ctf_add_type is working on now. */
297298 char *ctf_tmp_typeslice; /* Storage for slicing up type names. */
298299 size_t ctf_tmp_typeslicelen; /* Size of the typeslice. */
299300 void *ctf_specific; /* Data for ctf_get/setspecific(). */
--- a/libctf/ctf-open.c
+++ b/libctf/ctf-open.c
@@ -1665,6 +1665,7 @@ ctf_file_close (ctf_file_t *fp)
16651665 ctf_dynhash_destroy (fp->ctf_link_outputs);
16661666 ctf_dynhash_destroy (fp->ctf_link_type_mapping);
16671667 ctf_dynhash_destroy (fp->ctf_link_cu_mapping);
1668+ ctf_dynhash_destroy (fp->ctf_add_processing);
16681669
16691670 ctf_free (fp->ctf_sxlate);
16701671 ctf_free (fp->ctf_txlate);