aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-open.c
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2024-03-25 19:07:43 +0000
committerNick Alcock <nick.alcock@oracle.com>2024-04-19 16:14:47 +0100
commitcf9da3b0b6a6ae9d71ba36898a5e39710150f85e (patch)
tree1272de5d0b2fb21374070cb4ac359c35ea37cc43 /libctf/ctf-open.c
parent149ce5c263616e657ff8d108419d2eca54532b5a (diff)
downloadgdb-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.c20
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;