aboutsummaryrefslogtreecommitdiff
path: root/libctf
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2019-07-08 13:59:15 +0100
committerNick Alcock <nick.alcock@oracle.com>2019-10-03 17:04:55 +0100
commit9b32cba44ddeb32251092a05f1238d2462eb2345 (patch)
treee313eb919ec3ae3c75c66829e290736843c8c745 /libctf
parentlibctf: allow the header to change between versions (diff)
downloadbinutils-gdb-9b32cba44ddeb32251092a05f1238d2462eb2345.tar.gz
binutils-gdb-9b32cba44ddeb32251092a05f1238d2462eb2345.tar.bz2
binutils-gdb-9b32cba44ddeb32251092a05f1238d2462eb2345.zip
libctf, binutils: dump the CTF header
The CTF header has before now been thrown away too soon to be dumped using the ctf_dump() machinery used by objdump and readelf: instead, a kludge involving debugging-priority dumps of the header offsets on every open was used. Replace this with proper first-class dumping machinery just like everything else in the CTF file, and have objdump and readelf use it. (The dumper already had an enum value in ctf_sect_names_t for this purpose, waiting to be used.) v5: fix tabdamage. libctf/ * ctf-impl.h (ctf_file_t): New field ctf_openflags. * ctf-open.c (ctf_bufopen): Set it. No longer dump header offsets. * ctf-dump.c (dump_header): New function, dump the CTF header. (ctf_dump): Call it. (ctf_dump_header_strfield): New function. (ctf_dump_header_sectfield): Likewise. binutils/ * objdump.c (dump_ctf_archive_member): Dump the CTF header. * readelf.c (dump_section_as_ctf): Likewise.
Diffstat (limited to 'libctf')
-rw-r--r--libctf/ChangeLog9
-rw-r--r--libctf/ctf-dump.c129
-rw-r--r--libctf/ctf-impl.h1
-rw-r--r--libctf/ctf-open.c7
4 files changed, 138 insertions, 8 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index 9188a25c7f2..d0d0d6785c1 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,12 @@
+2019-07-08 Nick Alcock <nick.alcock@oracle.com>
+
+ * ctf-impl.h (ctf_file_t): New field ctf_openflags.
+ * ctf-open.c (ctf_bufopen): Set it. No longer dump header offsets.
+ * ctf-dump.c (dump_header): New function, dump the CTF header.
+ (ctf_dump): Call it.
+ (ctf_dump_header_strfield): New function.
+ (ctf_dump_header_sectfield): Likewise.
+
2019-07-06 Nick Alcock <nick.alcock@oracle.com>
* ctf-impl.h (ctf_file_t): New fields ctf_header, ctf_dynbase,
diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c
index 0e8ab202dd8..acb882ba53a 100644
--- a/libctf/ctf-dump.c
+++ b/libctf/ctf-dump.c
@@ -153,6 +153,132 @@ ctf_dump_format_type (ctf_file_t *fp, ctf_id_t id)
return NULL;
}
+/* Dump one string field from the file header into the cds_items. */
+static int
+ctf_dump_header_strfield (ctf_file_t *fp, ctf_dump_state_t *state,
+ const char *name, uint32_t value)
+{
+ char *str;
+ if (value)
+ {
+ if (asprintf (&str, "%s: %s\n", name, ctf_strptr (fp, value)) < 0)
+ goto err;
+ ctf_dump_append (state, str);
+ }
+ return 0;
+
+ err:
+ return (ctf_set_errno (fp, -ENOMEM));
+}
+
+/* Dump one section-offset field from the file header into the cds_items. */
+static int
+ctf_dump_header_sectfield (ctf_file_t *fp, ctf_dump_state_t *state,
+ const char *sect, uint32_t off, uint32_t nextoff)
+{
+ char *str;
+ if (nextoff - off)
+ {
+ if (asprintf (&str, "%s:\t0x%lx -- 0x%lx (0x%lx bytes)\n", sect,
+ (unsigned long) off, (unsigned long) (nextoff - 1),
+ (unsigned long) (nextoff - off)) < 0)
+ goto err;
+ ctf_dump_append (state, str);
+ }
+ return 0;
+
+ err:
+ return (ctf_set_errno (fp, -ENOMEM));
+}
+
+/* Dump the file header into the cds_items. */
+static int
+ctf_dump_header (ctf_file_t *fp, ctf_dump_state_t *state)
+{
+ char *str;
+ const ctf_header_t *hp = fp->ctf_header;
+ const char *vertab[] =
+ {
+ NULL, "CTF_VERSION_1",
+ "CTF_VERSION_1_UPGRADED_3 (latest format, version 1 type "
+ "boundaries)",
+ "CTF_VERSION_2",
+ "CTF_VERSION_3", NULL
+ };
+ const char *verstr = NULL;
+
+ if (asprintf (&str, "Magic number: %x\n", hp->cth_magic) < 0)
+ goto err;
+ ctf_dump_append (state, str);
+
+ if (hp->cth_version <= CTF_VERSION)
+ verstr = vertab[hp->cth_version];
+
+ if (verstr == NULL)
+ verstr = "(not a valid version)";
+
+ if (asprintf (&str, "Version: %i (%s)\n", hp->cth_version,
+ verstr) < 0)
+ goto err;
+ ctf_dump_append (state, str);
+
+ /* Everything else is only printed if present. */
+
+ /* The flags are unusual in that they represent the ctf_file_t *in memory*:
+ flags representing compression, etc, are turned off as the file is
+ decompressed. So we store a copy of the flags before they are changed, for
+ the dumper. */
+
+ 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)
+ goto err;
+ ctf_dump_append (state, str);
+ }
+
+ if (ctf_dump_header_strfield (fp, state, "Parent label",
+ hp->cth_parlabel) < 0)
+ goto err;
+
+ if (ctf_dump_header_strfield (fp, state, "Parent name", hp->cth_parname) < 0)
+ goto err;
+
+ if (ctf_dump_header_strfield (fp, state, "Compilation unit name",
+ hp->cth_cuname) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "Label section", hp->cth_lbloff,
+ hp->cth_objtoff) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "Data object section",
+ hp->cth_objtoff, hp->cth_funcoff) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "Function info section",
+ hp->cth_funcoff, hp->cth_varoff) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "Variable section",
+ hp->cth_varoff, hp->cth_typeoff) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "Type section",
+ hp->cth_typeoff, hp->cth_stroff) < 0)
+ goto err;
+
+ if (ctf_dump_header_sectfield (fp, state, "String section", hp->cth_stroff,
+ hp->cth_stroff + hp->cth_strlen + 1) < 0)
+ goto err;
+
+ return 0;
+ err:
+ return (ctf_set_errno (fp, -ENOMEM));
+}
+
/* Dump a single label into the cds_items. */
static int
@@ -492,8 +618,7 @@ ctf_dump (ctf_file_t *fp, ctf_dump_state_t **statep, ctf_sect_names_t sect,
switch (sect)
{
case CTF_SECT_HEADER:
- /* Nothing doable (yet): entire header is discarded after read-phase. */
- str = strdup ("");
+ ctf_dump_header (fp, state);
break;
case CTF_SECT_LABEL:
if (ctf_label_iter (fp, ctf_dump_label, state) < 0)
diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h
index 1cfab431cac..5b331cbc6d2 100644
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -218,6 +218,7 @@ struct ctf_file
{
const ctf_fileops_t *ctf_fileops; /* Version-specific file operations. */
struct ctf_header *ctf_header; /* The header from this CTF file. */
+ unsigned char ctf_openflags; /* Flags the file had when opened. */
ctf_sect_t ctf_data; /* CTF data from object file. */
ctf_sect_t ctf_symtab; /* Symbol table from object file. */
ctf_sect_t ctf_strtab; /* String table from object file. */
diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c
index ec05ce59cd5..2979ef8d287 100644
--- a/libctf/ctf-open.c
+++ b/libctf/ctf-open.c
@@ -1323,12 +1323,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
if (foreign_endian)
flip_header (hp);
-
- ctf_dprintf ("header offsets: %x/%x/%x/%x/%x/%x/%x\n",
- hp->cth_lbloff, hp->cth_objtoff, hp->cth_funcoff,
- hp->cth_varoff, hp->cth_typeoff, hp->cth_stroff,
- hp->cth_strlen);
-
+ fp->ctf_openflags = hp->cth_flags;
fp->ctf_size = hp->cth_stroff + hp->cth_strlen;
ctf_dprintf ("ctf_bufopen: uncompressed size=%lu\n",