aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-open.c
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2019-08-07 18:01:08 +0100
committerNick Alcock <nick.alcock@oracle.com>2019-10-03 17:04:56 +0100
commit99dc3ebdfff927b30db58117d7bd80586e273669 (patch)
tree8d96f1ae0a335ee1485e9faaaf2a570422347183 /libctf/ctf-open.c
parent676c3ecbad6e9c41b906b0f882ef2ce23f49976a (diff)
downloadgdb-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-open.c')
-rw-r--r--libctf/ctf-open.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c
index c4fca24..b698957 100644
--- a/libctf/ctf-open.c
+++ b/libctf/ctf-open.c
@@ -1665,6 +1665,7 @@ ctf_file_close (ctf_file_t *fp)
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);