aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libctf/ChangeLog9
-rw-r--r--libctf/ctf-dump.c210
2 files changed, 88 insertions, 131 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index 8f2fb48..e81db2c 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,14 @@
2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+ * ctf-dump.c (ctf_dump_header): Dump the new flags bits and the index
+ section lengths.
+ (ctf_dump_objts): Report indexed sections. Also dump functions. Use
+ ctf_symbol_next, not manual looping.
+ (ctf_dump_funcs): Delete.
+ (ctf_dump): Use ctf_dump_objts, not ctf_dump_funcs.
+
+2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+
* ctf-impl.h (CTF_INDEX_PAD_THRESHOLD): New.
(_libctf_nonnull_): Likewise.
(ctf_in_flight_dynsym_t): New.
diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c
index ced6917..ccf4b3c 100644
--- a/libctf/ctf-dump.c
+++ b/libctf/ctf-dump.c
@@ -224,6 +224,7 @@ static int
ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
{
char *str;
+ char *flagstr = NULL;
const ctf_header_t *hp = fp->ctf_header;
const char *vertab[] =
{
@@ -259,10 +260,29 @@ ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
if (fp->ctf_openflags > 0)
{
- if (fp->ctf_openflags)
- if (asprintf (&str, "Flags: 0x%x (%s)", fp->ctf_openflags,
- fp->ctf_openflags & CTF_F_COMPRESS ? "CTF_F_COMPRESS"
- : "") < 0)
+ if (asprintf (&flagstr, "%s%s%s%s%s%s%s",
+ fp->ctf_openflags & CTF_F_COMPRESS
+ ? "CTF_F_COMPRESS": "",
+ (fp->ctf_openflags & CTF_F_COMPRESS)
+ && (fp->ctf_openflags & ~CTF_F_COMPRESS)
+ ? ", " : "",
+ fp->ctf_openflags & CTF_F_NEWFUNCINFO
+ ? "CTF_F_NEWFUNCINFO" : "",
+ (fp->ctf_openflags & (CTF_F_COMPRESS | CTF_F_NEWFUNCINFO))
+ && (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO))
+ ? ", " : "",
+ fp->ctf_openflags & CTF_F_IDXSORTED
+ ? "CTF_F_IDXSORTED" : "",
+ fp->ctf_openflags & (CTF_F_COMPRESS | CTF_F_NEWFUNCINFO
+ | CTF_F_IDXSORTED)
+ && (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO
+ | CTF_F_IDXSORTED))
+ ? ", " : "",
+ fp->ctf_openflags & CTF_F_DYNSTR
+ ? "CTF_F_DYNSTR" : "") < 0)
+ goto err;
+
+ if (asprintf (&str, "Flags: 0x%x (%s)", fp->ctf_openflags, flagstr) < 0)
goto err;
ctf_dump_append (state, str);
}
@@ -287,7 +307,15 @@ ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
goto err;
if (ctf_dump_header_sectfield (fp, state, "Function info section",
- hp->cth_funcoff, hp->cth_varoff) < 0)
+ hp->cth_funcoff, hp->cth_objtidxoff) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "Object index section",
+ hp->cth_objtidxoff, hp->cth_funcidxoff) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "Function index section",
+ hp->cth_funcidxoff, hp->cth_varoff) < 0)
goto err;
if (ctf_dump_header_sectfield (fp, state, "Variable section",
@@ -304,6 +332,7 @@ ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
return 0;
err:
+ free (flagstr);
return (ctf_set_errno (fp, errno));
}
@@ -334,149 +363,68 @@ ctf_dump_label (const char *name, const ctf_lblinfo_t *info,
return 0;
}
-/* Dump all the object entries into the cds_items. (There is no iterator for
- this section, so we just do it in a loop, and this function handles all of
- them, rather than only one. */
+/* Dump all the object or function entries into the cds_items. */
static int
-ctf_dump_objts (ctf_dict_t *fp, ctf_dump_state_t *state)
+ctf_dump_objts (ctf_dict_t *fp, ctf_dump_state_t *state, int functions)
{
- size_t i;
-
- for (i = 0; i < fp->ctf_nsyms; i++)
+ const char *name;
+ ctf_id_t id;
+ ctf_next_t *i = NULL;
+ char *str = NULL;
+
+ if ((functions && fp->ctf_funcidx_names)
+ || (!functions && fp->ctf_objtidx_names))
+ str = str_append (str, _("Section is indexed.\n"));
+ else if (fp->ctf_symtab.cts_data == NULL)
+ str = str_append (str, _("No symbol table.\n"));
+
+ while ((id = ctf_symbol_next (fp, &i, &name, functions)) != CTF_ERR)
{
- char *str;
- char *typestr;
- const char *sym_name;
- ctf_id_t type;
-
- if ((type = ctf_lookup_by_symbol (state->cds_fp, i)) == CTF_ERR)
- switch (ctf_errno (state->cds_fp))
- {
- /* Most errors are just an indication that this symbol is not a data
- symbol, but this one indicates that we were called wrong, on a
- CTF file with no associated symbol table. */
- case ECTF_NOSYMTAB:
- return -1;
- case ECTF_NOTDATA:
- case ECTF_NOTYPEDAT:
- continue;
- }
-
- /* Variable name. */
- sym_name = ctf_lookup_symbol_name (fp, i);
- if (sym_name[0] == '\0')
- {
- if (asprintf (&str, "%lx -> ", (unsigned long) i) < 0)
- return (ctf_set_errno (fp, errno));
- }
- else
- {
- if (asprintf (&str, "%s (%lx) -> ", sym_name, (unsigned long) i) < 0)
- return (ctf_set_errno (fp, errno));
- }
+ char *typestr = NULL;
+ int err = 0;
- /* Variable type. */
- if ((typestr = ctf_dump_format_type (state->cds_fp, type,
- CTF_ADD_ROOT)) == NULL)
+ /* Emit the name, if we know it. */
+ if (name)
{
- free (str);
- return 0; /* Swallow the error. */
+ if (asprintf (&str, "%s -> ", name) < 0)
+ goto oom;
}
+ else
+ str = xstrdup ("");
- str = str_append (str, typestr);
- free (typestr);
-
- ctf_dump_append (state, str);
- }
- return 0;
-}
-
-/* Dump all the function entries into the cds_items. (As above, there is no
- iterator for this section.) */
-
-static int
-ctf_dump_funcs (ctf_dict_t *fp, ctf_dump_state_t *state)
-{
- size_t i;
-
- for (i = 0; i < fp->ctf_nsyms; i++)
- {
- char *str;
- char *bit = NULL;
- const char *sym_name;
- ctf_funcinfo_t fi;
- ctf_id_t type;
-
- if ((type = ctf_func_info (state->cds_fp, i, &fi)) == CTF_ERR)
- switch (ctf_errno (state->cds_fp))
- {
- /* Most errors are just an indication that this symbol is not a data
- symbol, but this one indicates that we were called wrong, on a
- CTF file with no associated symbol table. */
- case ECTF_NOSYMTAB:
- return -1;
- case ECTF_NOTDATA:
- case ECTF_NOTFUNC:
- case ECTF_NOFUNCDAT:
- continue;
- }
-
- /* Return type and all args. */
- if ((bit = ctf_type_aname (state->cds_fp, type)) == NULL)
+ if ((typestr = ctf_type_aname (fp, id)) == NULL)
{
- ctf_err_warn (fp, 1, ctf_errno (state->cds_fp),
- _("cannot look up return type dumping function type "
- "for symbol 0x%li"), (unsigned long) i);
- free (bit);
- return -1; /* errno is set for us. */
- }
-
- /* Replace in the returned string, dropping in the function name. */
+ if (id == 0 || ctf_errno (fp) == ECTF_NONREPRESENTABLE)
+ {
+ if (asprintf (&typestr, " (%s)", _("type not represented in CTF")) < 0)
+ goto oom;
- sym_name = ctf_lookup_symbol_name (fp, i);
- if (sym_name[0] != '\0')
- {
- char *retstar;
- char *new_bit;
- char *walk;
+ goto out;
+ }
- new_bit = malloc (strlen (bit) + 1 + strlen (sym_name));
- if (!new_bit)
+ if (asprintf (&typestr, ctf_errmsg (ctf_errno (fp))) < 0)
goto oom;
- /* See ctf_type_aname. */
- retstar = strstr (bit, "(*) (");
- if (!ctf_assert (fp, retstar))
- goto assert_err;
- retstar += 2; /* After the '*' */
-
- /* C is not good at search-and-replace. */
- walk = new_bit;
- memcpy (walk, bit, retstar - bit);
- walk += (retstar - bit);
- strcpy (walk, sym_name);
- walk += strlen (sym_name);
- strcpy (walk, retstar);
-
- free (bit);
- bit = new_bit;
+ err = -1;
+ goto out;
}
- if (asprintf (&str, "Symbol 0x%lx: %s", (unsigned long) i, bit) < 0)
- goto oom;
- free (bit);
-
+ str = str_append (str, typestr);
+ str = str_append (str, "\n");
ctf_dump_append (state, str);
continue;
oom:
- free (bit);
- return (ctf_set_errno (fp, errno));
-
- assert_err:
- free (bit);
- return -1; /* errno is set for us. */
+ ctf_set_errno (fp, ENOMEM);
+ ctf_next_destroy (i);
+ return -1;
+ out:
+ str = str_append (str, typestr);
+ free (typestr);
+ ctf_dump_append (state, str);
+ ctf_next_destroy (i);
+ return err; /* errno is set for us. */
}
return 0;
}
@@ -697,11 +645,11 @@ ctf_dump (ctf_dict_t *fp, ctf_dump_state_t **statep, ctf_sect_names_t sect,
}
break;
case CTF_SECT_OBJT:
- if (ctf_dump_objts (fp, state) < 0)
+ if (ctf_dump_objts (fp, state, 0) < 0)
goto end; /* errno is set for us. */
break;
case CTF_SECT_FUNC:
- if (ctf_dump_funcs (fp, state) < 0)
+ if (ctf_dump_objts (fp, state, 1) < 0)
goto end; /* errno is set for us. */
break;
case CTF_SECT_VAR: