mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 09:38:57 +00:00
libctf: create, lookup: delete DVDs; ctf_lookup_by_kind
Variable handling in BTF and CTFv4 works quite differently from in CTFv3. Rather than a separate section containing sorted, bsearchable variables, they are simply named entities like types, stored in CTF_K_VARs. As a first stage towards migrating to this, delete most references to the ctf_varent_t and ctf_dvdef_t, including the DVD lookup code, all the linking code, and quite a lot of the serialization code. Note: CTF_LINK_OMIT_VARIABLES_SECTION, and the whole "delete variables that already exist in the symtypetabs section" stuff, has yet to be reimplemented. We can implement CTF_LINK_OMIT_VARIABLES_SECTION by simply excising all CTF_K_VARs at deduplication time if requested. (Note: symtypetabs should still point directly at the type, not at the CTF_K_VAR.) (Symtypetabs in general need a bit more thought -- perhaps we can now store them in a separate .ctf.symtypetab section with its own little four-entry header for the symtypetabs and their indexes, making .ctf even more like .BTF; the only difference would then be that .ctf could include prefix types, CTF_K_FLOAT, and external string refs. For later discussion.) We also add ctf_lookup_by_kind() at this stage (because it is hopelessly diff-entangled with ctf_lookup_variable): this looks up a type of a particular kind, without needing a per-kind lookup function for it, nor needing to hack around adding string prefixes (so you can do ctf_lookup_by_kind (fp, CTF_K_STRUCT, "foo") rather than having to do ctf_lookup_by_name (fp, "struct foo"): often this is more convenient, and anything that reduces string buffer manipulation in C is good.)
This commit is contained in:
@@ -571,6 +571,14 @@ extern ctf_id_t ctf_lookup_variable (ctf_dict_t *, const char *);
|
||||
extern ctf_id_t ctf_lookup_enumerator (ctf_dict_t *, const char *,
|
||||
int64_t *enum_value);
|
||||
|
||||
/* Look up a type of a given kind by name. This serves to look up kinds in
|
||||
their own namespaces which do not have explicit lookup functions above:
|
||||
datasecs. The only kinds you can't look up with this function are
|
||||
CTF_K_TYPE_TAG and CTF_K_DECL_TAG, since they may be associated with many
|
||||
types: use ctf_tag_next. */
|
||||
|
||||
extern ctf_id_t ctf_lookup_by_kind (ctf_dict_t *, int kind, const char *);
|
||||
|
||||
/* Type lookup functions. */
|
||||
|
||||
/* Strip qualifiers and typedefs off a type, returning the base type.
|
||||
|
||||
@@ -364,38 +364,10 @@ ctf_static_type (const ctf_dict_t *fp, ctf_id_t type)
|
||||
return ((unsigned long) idx <= fp->ctf_stypes);
|
||||
}
|
||||
|
||||
int
|
||||
ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
|
||||
{
|
||||
if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
|
||||
return ctf_set_errno (fp, ENOMEM);
|
||||
ctf_list_append (&fp->ctf_dvdefs, dvd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ctf_dvd_delete (ctf_dict_t *fp, ctf_dvdef_t *dvd)
|
||||
{
|
||||
ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
|
||||
free (dvd->dvd_name);
|
||||
|
||||
ctf_list_delete (&fp->ctf_dvdefs, dvd);
|
||||
free (dvd);
|
||||
}
|
||||
|
||||
ctf_dvdef_t *
|
||||
ctf_dvd_lookup (const ctf_dict_t *fp, const char *name)
|
||||
{
|
||||
return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
|
||||
}
|
||||
|
||||
/* Discard all of the dynamic type definitions and variable definitions that
|
||||
have been added to the dict since the last call to ctf_update(). We locate
|
||||
such types by scanning the dtd list and deleting elements that have type IDs
|
||||
greater than ctf_dtoldid, which is set by ctf_update(), above, and by
|
||||
scanning the variable list and deleting elements that have update IDs equal
|
||||
to the current value of the last-update snapshot count (indicating that they
|
||||
were added after the most recent call to ctf_update()). */
|
||||
/* Discard all of the dynamic type definitions that have been added to the dict
|
||||
since the last call to ctf_update(). We locate such types by scanning the
|
||||
dtd list and deleting elements that have indexes greater than ctf_dtoldid,
|
||||
which is set by ctf_update(), above. */
|
||||
int
|
||||
ctf_discard (ctf_dict_t *fp)
|
||||
{
|
||||
@@ -420,7 +392,6 @@ int
|
||||
ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
|
||||
{
|
||||
ctf_dtdef_t *dtd, *ntd;
|
||||
ctf_dvdef_t *dvd, *nvd;
|
||||
|
||||
if (fp->ctf_flags & LCTF_NO_STR)
|
||||
return (ctf_set_errno (fp, ECTF_NOPARENT));
|
||||
@@ -454,16 +425,6 @@ ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
|
||||
ctf_dtd_delete (fp, dtd);
|
||||
}
|
||||
|
||||
for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
|
||||
{
|
||||
nvd = ctf_list_next (dvd);
|
||||
|
||||
if (dvd->dvd_snapshots <= id.snapshot_id)
|
||||
continue;
|
||||
|
||||
ctf_dvd_delete (fp, dvd);
|
||||
}
|
||||
|
||||
fp->ctf_typemax = id.dtd_id;
|
||||
fp->ctf_snapshots = id.snapshot_id;
|
||||
|
||||
|
||||
@@ -193,14 +193,6 @@ typedef struct ctf_dtdef
|
||||
int dtd_flags; /* Some of the DTD_F_ flags. */
|
||||
} ctf_dtdef_t;
|
||||
|
||||
typedef struct ctf_dvdef
|
||||
{
|
||||
ctf_list_t dvd_list; /* List forward/back pointers. */
|
||||
char *dvd_name; /* Name associated with variable. */
|
||||
ctf_id_t dvd_type; /* Type of variable. */
|
||||
unsigned long dvd_snapshots; /* Snapshot count when inserted. */
|
||||
} ctf_dvdef_t;
|
||||
|
||||
typedef struct ctf_err_warning
|
||||
{
|
||||
ctf_list_t cew_list; /* List forward/back pointers. */
|
||||
@@ -410,7 +402,6 @@ struct ctf_dict
|
||||
size_t ctf_size; /* Size of CTF header + uncompressed data. */
|
||||
unsigned char *ctf_serializing_buf; /* CTF buffer in mid-serialization. */
|
||||
size_t ctf_serializing_buf_size; /* Length of that buffer. */
|
||||
ctf_varent_t *ctf_serializing_vars; /* Unsorted vars in mid-serialization. */
|
||||
size_t ctf_serializing_nvars; /* Number of those vars. */
|
||||
uint32_t *ctf_sxlate; /* Translation table for unindexed symtypetab
|
||||
entries. */
|
||||
@@ -462,8 +453,6 @@ struct ctf_dict
|
||||
int ctf_version; /* CTF data version. */
|
||||
ctf_dynhash_t *ctf_dthash; /* Hash of dynamic type definitions. */
|
||||
ctf_list_t ctf_dtdefs; /* List of dynamic type definitions. */
|
||||
ctf_dynhash_t *ctf_dvhash; /* Hash of dynamic variable mappings. */
|
||||
ctf_list_t ctf_dvdefs; /* List of dynamic variable definitions. */
|
||||
unsigned long ctf_dtoldid; /* Oldest id that has been committed. */
|
||||
unsigned long ctf_snapshots; /* ctf_snapshot() plus ctf_update() count. */
|
||||
unsigned long ctf_snapshot_lu; /* ctf_snapshot() call count at last update. */
|
||||
@@ -750,10 +739,6 @@ extern void ctf_dtd_delete (ctf_dict_t *, ctf_dtdef_t *);
|
||||
extern ctf_dtdef_t *ctf_dtd_lookup (const ctf_dict_t *, ctf_id_t);
|
||||
extern ctf_dtdef_t *ctf_dynamic_type (const ctf_dict_t *, ctf_id_t);
|
||||
|
||||
extern int ctf_dvd_insert (ctf_dict_t *, ctf_dvdef_t *);
|
||||
extern void ctf_dvd_delete (ctf_dict_t *, ctf_dvdef_t *);
|
||||
extern ctf_dvdef_t *ctf_dvd_lookup (const ctf_dict_t *, const char *);
|
||||
|
||||
extern ctf_id_t ctf_add_encoded (ctf_dict_t *, uint32_t, const char *,
|
||||
const ctf_encoding_t *, uint32_t kind);
|
||||
extern ctf_id_t ctf_add_reftype (ctf_dict_t *, uint32_t, ctf_id_t,
|
||||
|
||||
@@ -493,114 +493,6 @@ ctf_link_set_variable_filter (ctf_dict_t *fp, ctf_link_variable_filter_f *filter
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if we can safely add a variable with the given type to this dict. */
|
||||
|
||||
static int
|
||||
check_variable (const char *name, ctf_dict_t *fp, ctf_id_t type,
|
||||
ctf_dvdef_t **out_dvd)
|
||||
{
|
||||
ctf_dvdef_t *dvd;
|
||||
|
||||
dvd = ctf_dynhash_lookup (fp->ctf_dvhash, name);
|
||||
*out_dvd = dvd;
|
||||
if (!dvd)
|
||||
return 1;
|
||||
|
||||
if (dvd->dvd_type != type)
|
||||
{
|
||||
/* Variable here. Wrong type: cannot add. Just skip it, because there is
|
||||
no way to express this in CTF. Don't even warn: this case is too
|
||||
common. (This might be the parent, in which case we'll try adding in
|
||||
the child first, and only then give up.) */
|
||||
ctf_dprintf ("Inexpressible duplicate variable %s skipped.\n", name);
|
||||
}
|
||||
|
||||
return 0; /* Already exists. */
|
||||
}
|
||||
|
||||
/* Link one variable named NAME of type TYPE found in IN_FP into FP. */
|
||||
|
||||
static int
|
||||
ctf_link_one_variable (ctf_dict_t *fp, ctf_dict_t *in_fp, const char *name,
|
||||
ctf_id_t type, int cu_mapped)
|
||||
{
|
||||
ctf_dict_t *per_cu_out_fp;
|
||||
ctf_id_t dst_type = 0;
|
||||
ctf_dvdef_t *dvd;
|
||||
|
||||
/* See if this variable is filtered out. */
|
||||
|
||||
if (fp->ctf_link_variable_filter)
|
||||
{
|
||||
void *farg = fp->ctf_link_variable_filter_arg;
|
||||
if (fp->ctf_link_variable_filter (in_fp, name, type, farg))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If this type is mapped to a type in the parent dict, we want to try to add
|
||||
to that first: if it reports a duplicate, or if the type is in a child
|
||||
already, add straight to the child. */
|
||||
|
||||
if ((dst_type = ctf_dedup_type_mapping (fp, in_fp, type)) == CTF_ERR)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
if (dst_type != 0)
|
||||
{
|
||||
if (!ctf_assert (fp, ctf_type_isparent (fp, dst_type)))
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
if (check_variable (name, fp, dst_type, &dvd))
|
||||
{
|
||||
/* No variable here: we can add it. */
|
||||
if (ctf_add_variable (fp, name, dst_type) < 0)
|
||||
return -1; /* errno is set for us. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Already present? Nothing to do. */
|
||||
if (dvd && dvd->dvd_type == dst_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Can't add to the parent due to a name clash, or because it references a
|
||||
type only present in the child. Try adding to the child, creating if need
|
||||
be. If we can't do that, skip it. Don't add to a child if we're doing a
|
||||
CU-mapped link, since that has only one output. */
|
||||
|
||||
if (cu_mapped)
|
||||
{
|
||||
ctf_dprintf ("Variable %s in input file %s depends on a type %lx hidden "
|
||||
"due to conflicts: skipped.\n", name,
|
||||
ctf_unnamed_cuname (in_fp), type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((per_cu_out_fp = ctf_create_per_cu (fp, in_fp, NULL)) == NULL)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
/* If the type was not found, check for it in the child too. */
|
||||
if (dst_type == 0)
|
||||
{
|
||||
if ((dst_type = ctf_dedup_type_mapping (per_cu_out_fp,
|
||||
in_fp, type)) == CTF_ERR)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
if (dst_type == 0)
|
||||
{
|
||||
ctf_err_warn (fp, 1, 0, _("type %lx for variable %s in input file %s "
|
||||
"not found: skipped"), type, name,
|
||||
ctf_unnamed_cuname (in_fp));
|
||||
/* Do not terminate the link: just skip the variable. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_variable (name, per_cu_out_fp, dst_type, &dvd))
|
||||
if (ctf_add_variable (per_cu_out_fp, name, dst_type) < 0)
|
||||
return (ctf_set_errno (fp, ctf_errno (per_cu_out_fp)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct link_sort_inputs_cb_arg
|
||||
{
|
||||
int is_cu_mapped;
|
||||
@@ -934,72 +826,9 @@ ctf_link_deduplicating_close_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do a deduplicating link of all variables in the inputs.
|
||||
|
||||
Also, if we are not omitting the variable section, integrate all symbols from
|
||||
the symtypetabs into the variable section too. (Duplication with the
|
||||
symtypetab section in the output will be eliminated at serialization time.) */
|
||||
|
||||
static int
|
||||
ctf_link_deduplicating_variables (ctf_dict_t *fp, ctf_dict_t **inputs,
|
||||
size_t ninputs, int cu_mapped)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ninputs; i++)
|
||||
{
|
||||
ctf_next_t *it = NULL;
|
||||
ctf_id_t type;
|
||||
const char *name;
|
||||
|
||||
/* First the variables on the inputs. */
|
||||
|
||||
while ((type = ctf_variable_next (inputs[i], &it, &name)) != CTF_ERR)
|
||||
{
|
||||
if (ctf_link_one_variable (fp, inputs[i], name, type, cu_mapped) < 0)
|
||||
{
|
||||
ctf_next_destroy (it);
|
||||
return -1; /* errno is set for us. */
|
||||
}
|
||||
}
|
||||
if (ctf_errno (inputs[i]) != ECTF_NEXT_END)
|
||||
return ctf_set_errno (fp, ctf_errno (inputs[i]));
|
||||
|
||||
/* Next the symbols. We integrate data symbols even though the compiler
|
||||
is currently doing the same, to allow the compiler to stop in
|
||||
future. */
|
||||
|
||||
while ((type = ctf_symbol_next (inputs[i], &it, &name, 0)) != CTF_ERR)
|
||||
{
|
||||
if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0)
|
||||
{
|
||||
ctf_next_destroy (it);
|
||||
return -1; /* errno is set for us. */
|
||||
}
|
||||
}
|
||||
if (ctf_errno (inputs[i]) != ECTF_NEXT_END)
|
||||
return ctf_set_errno (fp, ctf_errno (inputs[i]));
|
||||
|
||||
/* Finally the function symbols. */
|
||||
|
||||
while ((type = ctf_symbol_next (inputs[i], &it, &name, 1)) != CTF_ERR)
|
||||
{
|
||||
if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0)
|
||||
{
|
||||
ctf_next_destroy (it);
|
||||
return -1; /* errno is set for us. */
|
||||
}
|
||||
}
|
||||
if (ctf_errno (inputs[i]) != ECTF_NEXT_END)
|
||||
return ctf_set_errno (fp, ctf_errno (inputs[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for symbol conflicts during linking. Three possibilities: already
|
||||
exists, conflicting, or nonexistent. We don't have a dvd structure we can
|
||||
use as a flag like check_variable does, so we use a tristate return
|
||||
value instead: -1: conflicting; 1: nonexistent: 0: already exists. */
|
||||
/* Check for symbol conflicts during linking. Three possibilities: already exists,
|
||||
conflicting, or nonexistent. We use a tristate return value: -1: conflicting; 1:
|
||||
nonexistent: 0: already exists. */
|
||||
|
||||
static int
|
||||
check_sym (ctf_dict_t *fp, const char *name, ctf_id_t type, int functions)
|
||||
@@ -1306,15 +1135,6 @@ ctf_link_deduplicating_per_cu (ctf_dict_t *fp)
|
||||
goto err_inputs_outputs;
|
||||
}
|
||||
|
||||
if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION)
|
||||
&& ctf_link_deduplicating_variables (out, inputs, ninputs, 1) < 0)
|
||||
{
|
||||
ctf_set_errno (fp, ctf_errno (out));
|
||||
ctf_err_warn (fp, 0, 0, _("CU-mapped deduplicating link variable "
|
||||
"emission failed for %s"), out_name);
|
||||
goto err_inputs_outputs;
|
||||
}
|
||||
|
||||
ctf_dedup_fini (out, outputs, noutputs);
|
||||
|
||||
/* For now, we omit symbol section linking for CU-mapped links, until it
|
||||
@@ -1492,13 +1312,8 @@ ctf_link_deduplicating (ctf_dict_t *fp)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION)
|
||||
&& ctf_link_deduplicating_variables (fp, inputs, ninputs, 0) < 0)
|
||||
{
|
||||
ctf_err_warn (fp, 0, 0, _("deduplicating link variable emission failed for "
|
||||
"%s"), ctf_link_input_name (fp));
|
||||
goto err_clean_outputs;
|
||||
}
|
||||
/* UPTODO: variable section omission, possible integration of symtypetabs (?) et
|
||||
al */
|
||||
|
||||
if (ctf_link_deduplicating_syms (fp, inputs, ninputs, 0) < 0)
|
||||
{
|
||||
|
||||
@@ -449,64 +449,28 @@ typedef struct ctf_lookup_idx_key
|
||||
uint32_t *clik_names;
|
||||
} ctf_lookup_idx_key_t;
|
||||
|
||||
/* A bsearch function for variable names. */
|
||||
|
||||
static int
|
||||
ctf_lookup_var (const void *key_, const void *lookup_)
|
||||
{
|
||||
const ctf_lookup_idx_key_t *key = key_;
|
||||
const ctf_varent_t *lookup = lookup_;
|
||||
|
||||
return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name)));
|
||||
}
|
||||
|
||||
/* Given a variable name, return the type of the variable with that name.
|
||||
Look only in this dict, not in the parent. */
|
||||
/* Look up some kind of thing in the name tables. */
|
||||
|
||||
ctf_id_t
|
||||
ctf_lookup_variable_here (ctf_dict_t *fp, const char *name)
|
||||
{
|
||||
ctf_dvdef_t *dvd = ctf_dvd_lookup (fp, name);
|
||||
ctf_varent_t *ent;
|
||||
ctf_lookup_idx_key_t key = { fp, name, NULL };
|
||||
|
||||
if (dvd != NULL)
|
||||
return dvd->dvd_type;
|
||||
|
||||
/* This array is sorted, so we can bsearch for it. */
|
||||
|
||||
ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t),
|
||||
ctf_lookup_var);
|
||||
|
||||
if (ent == NULL)
|
||||
return (ctf_set_typed_errno (fp, ECTF_NOTYPEDAT));
|
||||
|
||||
return ent->ctv_type;
|
||||
}
|
||||
|
||||
/* As above, but look in the parent too. */
|
||||
|
||||
ctf_id_t
|
||||
ctf_lookup_variable (ctf_dict_t *fp, const char *name)
|
||||
ctf_lookup_by_kind (ctf_dict_t *fp, int kind, const char *name)
|
||||
{
|
||||
ctf_id_t type;
|
||||
|
||||
if (fp->ctf_flags & LCTF_NO_STR)
|
||||
return (ctf_set_typed_errno (fp, ECTF_NOPARENT));
|
||||
if (kind == CTF_K_TYPE_TAG || kind == CTF_K_DECL_TAG)
|
||||
return (ctf_set_typed_errno (fp, ECTF_NEVERTAG));
|
||||
|
||||
if ((type = ctf_lookup_variable_here (fp, name)) == CTF_ERR)
|
||||
{
|
||||
if (ctf_errno (fp) == ECTF_NOTYPEDAT && fp->ctf_parent != NULL)
|
||||
{
|
||||
if ((type = ctf_lookup_variable_here (fp->ctf_parent, name)) != CTF_ERR)
|
||||
return type;
|
||||
return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent)));
|
||||
}
|
||||
if ((type = ctf_dynhash_lookup_type (ctf_name_table (fp, kind),
|
||||
name)) != CTF_ERR)
|
||||
return type;
|
||||
|
||||
return -1; /* errno is set for us. */
|
||||
}
|
||||
if (fp->ctf_parent
|
||||
&& (type = ctf_dynhash_lookup_type (ctf_name_table (fp->ctf_parent, kind),
|
||||
name)) != CTF_ERR)
|
||||
return type;
|
||||
|
||||
return ctf_set_typed_errno (fp, ECTF_NOTYPE);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Look up a single enumerator by enumeration constant name. Returns the ID of
|
||||
|
||||
@@ -2223,8 +2223,6 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
|
||||
|
||||
fp->ctf_dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
|
||||
NULL, NULL);
|
||||
fp->ctf_dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
|
||||
NULL, NULL);
|
||||
fp->ctf_snapshots = 1;
|
||||
|
||||
fp->ctf_objthash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
|
||||
@@ -2232,8 +2230,8 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
|
||||
fp->ctf_funchash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
|
||||
free, NULL);
|
||||
|
||||
if (!fp->ctf_dthash || !fp->ctf_dvhash || !fp->ctf_snapshots ||
|
||||
!fp->ctf_objthash || !fp->ctf_funchash)
|
||||
if (!fp->ctf_dthash || !fp->ctf_snapshots || !fp->ctf_objthash
|
||||
|| !fp->ctf_funchash)
|
||||
{
|
||||
err = ENOMEM;
|
||||
goto bad;
|
||||
@@ -2334,7 +2332,6 @@ void
|
||||
ctf_dict_close (ctf_dict_t *fp)
|
||||
{
|
||||
ctf_dtdef_t *dtd, *ntd;
|
||||
ctf_dvdef_t *dvd, *nvd;
|
||||
ctf_in_flight_dynsym_t *did, *nid;
|
||||
ctf_err_warning_t *err, *nerr;
|
||||
|
||||
@@ -2375,13 +2372,6 @@ ctf_dict_close (ctf_dict_t *fp)
|
||||
ctf_dynhash_destroy (fp->ctf_datasecs);
|
||||
ctf_dynhash_destroy (fp->ctf_tags);
|
||||
ctf_dynhash_destroy (fp->ctf_names);
|
||||
|
||||
for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
|
||||
{
|
||||
nvd = ctf_list_next (dvd);
|
||||
ctf_dvd_delete (fp, dvd);
|
||||
}
|
||||
ctf_dynhash_destroy (fp->ctf_dvhash);
|
||||
ctf_dynhash_destroy (fp->ctf_var_datasecs);
|
||||
|
||||
ctf_dynhash_destroy (fp->ctf_symhash_func);
|
||||
|
||||
@@ -497,33 +497,6 @@ emit_symtypetab_index (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Delete variables with the same name as symbols that have been reported by
|
||||
the linker from the variable section. Must be called from within
|
||||
ctf_serialize, because that is the only place you can safely delete
|
||||
variables without messing up ctf_rollback. */
|
||||
|
||||
static int
|
||||
symtypetab_delete_nonstatics (ctf_dict_t *fp, ctf_dict_t *symfp)
|
||||
{
|
||||
ctf_dvdef_t *dvd, *nvd;
|
||||
ctf_id_t type;
|
||||
|
||||
for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
|
||||
{
|
||||
nvd = ctf_list_next (dvd);
|
||||
|
||||
if ((((type = (ctf_id_t) (uintptr_t)
|
||||
ctf_dynhash_lookup (fp->ctf_objthash, dvd->dvd_name)) > 0)
|
||||
|| (type = (ctf_id_t) (uintptr_t)
|
||||
ctf_dynhash_lookup (fp->ctf_funchash, dvd->dvd_name)) > 0)
|
||||
&& ctf_dynhash_lookup (symfp->ctf_dynsyms, dvd->dvd_name) != NULL
|
||||
&& type == dvd->dvd_type)
|
||||
ctf_dvd_delete (fp, dvd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Figure out the sizes of the symtypetab sections, their indexed state,
|
||||
etc.
|
||||
|
||||
@@ -540,13 +513,13 @@ ctf_symtypetab_sect_sizes (ctf_dict_t *fp, emit_symtypetab_state_t *s,
|
||||
size_t objt_unpadsize, func_unpadsize, objt_padsize, func_padsize;
|
||||
|
||||
/* If doing a writeout as part of linking, and the link flags request it,
|
||||
filter out reported symbols from the variable section, and filter out all
|
||||
other symbols from the symtypetab sections. (If we are not linking, the
|
||||
symbols are sorted; if we are linking, don't bother sorting if we are not
|
||||
filtering out reported symbols: this is almost certainly an ld -r and only
|
||||
the linker is likely to consume these symtypetabs again. The linker
|
||||
doesn't care what order the symtypetab entries are in, since it only
|
||||
iterates over symbols and does not use the ctf_lookup_by_symbol* API.) */
|
||||
filter out all unreported symbols from the symtypetab sections. (If we are
|
||||
not linking, the symbols are sorted; if we are linking, don't bother
|
||||
sorting if we are not filtering out reported symbols: this is almost
|
||||
certainly an ld -r and only the linker is likely to consume these
|
||||
symtypetabs again. The linker doesn't care what order the symtypetab
|
||||
entries are in, since it only iterates over symbols and does not use the
|
||||
ctf_lookup_by_symbol* API.) */
|
||||
|
||||
s->sort_syms = 1;
|
||||
if (fp->ctf_flags & LCTF_LINKING)
|
||||
@@ -631,16 +604,6 @@ ctf_symtypetab_sect_sizes (ctf_dict_t *fp, emit_symtypetab_state_t *s,
|
||||
*funcidx_size = 0;
|
||||
}
|
||||
|
||||
/* If we are filtering symbols out, those symbols that the linker has not
|
||||
reported have now been removed from the ctf_objthash and ctf_funchash.
|
||||
Delete entries from the variable section that duplicate newly-added
|
||||
symbols. There's no need to migrate new ones in: we do that (if necessary)
|
||||
in ctf_link_deduplicating_variables. */
|
||||
|
||||
if (s->filter_syms && s->symfp->ctf_dynsyms &&
|
||||
symtypetab_delete_nonstatics (fp, s->symfp) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1052,27 +1015,6 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Variable section. */
|
||||
|
||||
/* Sort a newly-constructed static variable array. */
|
||||
|
||||
typedef struct ctf_sort_var_arg_cb
|
||||
{
|
||||
ctf_dict_t *fp;
|
||||
ctf_strs_t *strtab;
|
||||
} ctf_sort_var_arg_cb_t;
|
||||
|
||||
static int
|
||||
ctf_sort_var (const void *one_, const void *two_, void *arg_)
|
||||
{
|
||||
const ctf_varent_t *one = one_;
|
||||
const ctf_varent_t *two = two_;
|
||||
ctf_sort_var_arg_cb_t *arg = arg_;
|
||||
|
||||
return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab),
|
||||
ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab)));
|
||||
}
|
||||
|
||||
/* Overall serialization. */
|
||||
|
||||
/* Do all aspects of serialization up to strtab writeout and variable table
|
||||
@@ -1393,13 +1335,6 @@ ctf_serialize (ctf_dict_t *fp, size_t *bufsiz)
|
||||
if (strtab == NULL)
|
||||
goto err;
|
||||
|
||||
/* Now the string table is constructed and all the refs updated, we can sort
|
||||
the buffer of ctf_varent_t's. */
|
||||
|
||||
ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) strtab };
|
||||
ctf_qsort_r (fp->ctf_serializing_vars, fp->ctf_serializing_nvars,
|
||||
sizeof (ctf_varent_t), ctf_sort_var, &sort_var_arg);
|
||||
|
||||
if ((newbuf = realloc (fp->ctf_serializing_buf, fp->ctf_serializing_buf_size
|
||||
+ strtab->cts_len)) == NULL)
|
||||
goto oom;
|
||||
|
||||
@@ -57,6 +57,7 @@ LIBCTF_2.0 {
|
||||
|
||||
ctf_lookup_by_name;
|
||||
ctf_lookup_by_symbol;
|
||||
ctf_lookup_by_kind;
|
||||
ctf_symbol_next;
|
||||
ctf_lookup_by_symbol_name;
|
||||
ctf_arc_lookup_symbol;
|
||||
|
||||
Reference in New Issue
Block a user