diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2019-08-07 18:01:08 +0100 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2019-10-03 17:04:56 +0100 |
commit | 99dc3ebdfff927b30db58117d7bd80586e273669 (patch) | |
tree | 8d96f1ae0a335ee1485e9faaaf2a570422347183 /libctf/ctf-impl.h | |
parent | 676c3ecbad6e9c41b906b0f882ef2ce23f49976a (diff) | |
download | gdb-99dc3ebdfff927b30db58117d7bd80586e273669.zip gdb-99dc3ebdfff927b30db58117d7bd80586e273669.tar.gz gdb-99dc3ebdfff927b30db58117d7bd80586e273669.tar.bz2 |
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.
v5: fix tabdamage.
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.
Diffstat (limited to 'libctf/ctf-impl.h')
-rw-r--r-- | libctf/ctf-impl.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index d284717..f8e9a77 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -294,6 +294,7 @@ struct ctf_file /* Allow the caller to Change the name of link archive members. */ ctf_link_memb_name_changer_f *ctf_link_memb_name_changer; void *ctf_link_memb_name_changer_arg; /* Argument for it. */ + ctf_dynhash_t *ctf_add_processing; /* Types ctf_add_type is working on now. */ char *ctf_tmp_typeslice; /* Storage for slicing up type names. */ size_t ctf_tmp_typeslicelen; /* Size of the typeslice. */ void *ctf_specific; /* Data for ctf_get/setspecific(). */ |