diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2024-03-25 19:07:43 +0000 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2024-04-19 16:14:47 +0100 |
commit | cf9da3b0b6a6ae9d71ba36898a5e39710150f85e (patch) | |
tree | 1272de5d0b2fb21374070cb4ac359c35ea37cc43 /libctf/ctf-open.c | |
parent | 149ce5c263616e657ff8d108419d2eca54532b5a (diff) | |
download | gdb-cf9da3b0b6a6ae9d71ba36898a5e39710150f85e.zip gdb-cf9da3b0b6a6ae9d71ba36898a5e39710150f85e.tar.gz gdb-cf9da3b0b6a6ae9d71ba36898a5e39710150f85e.tar.bz2 |
libctf: rethink strtab writeout
This commit finally adjusts strtab writeout so that repeated writeouts, or
writeouts of a dict that was read in earlier, only sorts the portion of the
strtab that was newly added.
There are three intertwined changes here:
- pull the contents of strtabs from newly ctf_bufopened dicts into the
atoms table, so that future additions will reuse the existing offset etc
rather than adding new identical strings
- allow the internal ctf_bufopen done by serialization to contribute its
existing atoms table, so that existing atoms can be used for the
remainder of the open process (like name table construction): this atoms
table currente gets thrown away in the mass reassignment done later in
ctf_serialize in any case, but it needs to be there during the open.
- rewrite ctf_str_write_strtab so that a) it uses iterators rather than
ctf_*_iter, reducing pointless structures which serve no other purpose
than to implement ordinary variable scope, but more clunkily, and b)
retains the existing strtab on the front of the new one, with its sort
retained, rather than resorting, so all existing already-written strtab
offsets remain valid across the call.
This latter change finally permits repeated serializations, and
reserializations of ctf_open()ed dicts, to work, but for now we keep the
code that prevents that because serialization is about to change again in a
way that will make it more obvious that doing such things is safe, and we
can take it out then.
(There are also some smaller changes like moving the purge of the refs table
into ctf_str_write_strtab(), since that's where the changes happen that
invalidate it, rather than doing it in ctf_serialize(). We also prohibit
something that has never worked, opening a dict and then reporting symbols
to it via ctf_link_add_strtab() et al: you must do that to newly-created
dicts which have had stuff ctf_link()ed into them. This is very unlikely
ever to be a problem in practice: linkers just don't do that sort of thing.)
libctf/
* ctf-create.c (ctf_create): Add (temporary) atoms arg.
* ctf-impl.h (struct ctf_dict.ctf_dynstrtab): New.
(ctf_str_create_atoms): Adjust.
(ctf_str_write_strtab): Likewise.
(ctf_simple_open_internal): Likewise.
* ctf-open.c (ctf_simple_open_internal): Add atoms arg.
(ctf_bufopen): Likewise.
(ctf_bufopen_internal): Initialize just enough of an
atoms table: pre-init from the atoms arg if supplied.
(ctf_simple_open): Adjust.
* ctf-serialize.c (ctf_serialize): Constify the strtab.
Move ref list purging into ctf_str_write_strtab.
Initialize the new dict with the old dict's atoms table.
Accept the new strtab from ctf_str_write_strtab.
Adjust for addition of ctf_dynstrtab.
* ctf-string.c (ctf_strraw_explicit): Improve comments.
(ctf_str_create_atoms): Prepopulate from an existing atoms table,
or alternatively pull in all strings from the strtab and turn
them into atoms.
(ctf_str_free_atoms): Free the dynstrtab and its strtab.
(struct ctf_strtab_write_state): Remove.
(ctf_str_count_strtab): Fold this...
(ctf_str_populate_sorttab): ... and this...
(ctf_str_write_strtab): ... into this. Prepend existing strings
to the strtab rather than resorting them (and wrecking their
offsets). Keep the dynstrtab updated. Update refs for all
atoms with refs, whether or not they are strings newly added
to the strtab.
Diffstat (limited to 'libctf/ctf-open.c')
-rw-r--r-- | libctf/ctf-open.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 2247546..6d7a276 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -1290,7 +1290,7 @@ ctf_dict_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); + NULL, errp); } /* Open a CTF file, mocking up a suitable ctf_sect and overriding the external @@ -1300,7 +1300,8 @@ ctf_dict_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, + ctf_dynhash_t *atoms, int *errp) { ctf_sect_t skeleton; @@ -1338,7 +1339,7 @@ ctf_dict_t *ctf_simple_open_internal (const char *ctfsect, size_t ctfsect_size, } return ctf_bufopen_internal (ctfsectp, symsectp, strsectp, syn_strtab, - errp); + atoms, errp); } /* Decode the specified CTF buffer and optional symbol table, and create a new @@ -1350,7 +1351,7 @@ ctf_dict_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, NULL, errp); } /* Like ctf_bufopen, but overriding the external strtab with a synthetic one. */ @@ -1358,7 +1359,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_dict_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) + ctf_dynhash_t *atoms, int *errp) { const ctf_preamble_t *pp; size_t hdrsz = sizeof (ctf_header_t); @@ -1615,7 +1616,14 @@ ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_set_base(). */ ctf_set_version (fp, hp, hp->cth_version); - if (ctf_str_create_atoms (fp) < 0) + + /* Temporary assignment, just enough to be able to initialize + the atoms table. */ + + fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *) fp->ctf_buf + + hp->cth_stroff; + fp->ctf_str[CTF_STRTAB_0].cts_len = hp->cth_strlen; + if (ctf_str_create_atoms (fp, atoms) < 0) { err = ENOMEM; goto bad; |