diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2020-05-11 18:18:50 +0100 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2020-07-22 18:02:18 +0100 |
commit | 70447401740235d828c4b7b87e398eeae4801094 (patch) | |
tree | 2c1b446b9a7c9a71691171e60bdf851a5a077142 | |
parent | 8e795b46f58d9cd80b8831ea24f56f1433b8f50b (diff) | |
download | binutils-70447401740235d828c4b7b87e398eeae4801094.zip binutils-70447401740235d828c4b7b87e398eeae4801094.tar.gz binutils-70447401740235d828c4b7b87e398eeae4801094.tar.bz2 |
libctf, dump: fix slice dumping
Now that we can have slices of anything terminating in an int, we must
dump things accordingly, or slices of typedefs appear as
c5b: __u8 -> 16c: __u8 -> 78: short unsigned int (size 0x2)
which is unhelpful. If things *are* printed as slices, the name is
missing:
a15: [slice 0x8:0x4]-> 16c: __u8 -> 78: short unsigned int (size 0x2)
And struct members give no clue they're a slice at all, which is a shame
since bitfields are the major use of this type kind:
[0x8] (ID 0xa15) (kind 10) __u8 dst_reg
Fix things so that everything slicelike or integral gets its encoding
printed, and everything with a name gets the name printed:
a15: __u8 [slice 0x8:0x4] (size 0x1) -> 1ff: __u8 (size 0x1) -> 37: unsigned char [0x0:0x8] (size 0x1)
[0x0] (ID 0xa15) (kind 10) __u8:4 (aligned at 0x1, format 0x2, offset:bits 0x8:0x4)
Bitfield struct members get a technically redundant but much
easier-to-understand dumping now:
[0x0] (ID 0x80000005) (kind 6) struct bpf_insn (aligned at 0x1)
[0x0] (ID 0x222) (kind 10) __u8 code (aligned at 0x1)
[0x8] (ID 0x1e9e) (kind 10) __u8 dst_reg:4 (aligned at 0x1, format 0x2, offset:bits 0x8:0x4)
[0xc] (ID 0x1e46) (kind 10) __u8 src_reg:4 (aligned at 0x1, format 0x2, offset:bits 0xc:0x4)
[0x10] (ID 0xf35) (kind 10) __s16 off (aligned at 0x2)
[0x20] (ID 0x1718) (kind 10) __s32 imm (aligned at 0x4)
This also fixes one place where a failure to format a type would be
erroneously considered an out-of-memory condition.
libctf/
* ctf-dump.c (ctf_is_slice): Delete, unnecessary.
(ctf_dump_format_type): improve slice formatting. Always print
the type size, even of slices.
(ctf_dump_member): Print slices (-> bitfields) differently from
non-slices. Failure to format a type is not an OOM.
-rw-r--r-- | libctf/ChangeLog | 8 | ||||
-rw-r--r-- | libctf/ctf-dump.c | 92 |
2 files changed, 65 insertions, 35 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index b13c51c..841f146 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,5 +1,13 @@ 2020-07-22 Nick Alcock <nick.alcock@oracle.com> + * ctf-dump.c (ctf_is_slice): Delete, unnecessary. + (ctf_dump_format_type): improve slice formatting. Always print + the type size, even of slices. + (ctf_dump_member): Print slices (-> bitfields) differently from + non-slices. Failure to format a type is not an OOM. + +2020-07-22 Nick Alcock <nick.alcock@oracle.com> + * ctf-dump.c (ctf_dump_format_type): Emit a warning. (ctf_dump_label): Swallow errors from ctf_dump_format_type. (ctf_dump_objts): Likewise. diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c index 55aa496..94d6bc6 100644 --- a/libctf/ctf-dump.c +++ b/libctf/ctf-dump.c @@ -79,20 +79,6 @@ ctf_dump_free (ctf_dump_state_t *state) } } -/* Slices need special handling to distinguish them from their referenced - type. */ - -static int -ctf_is_slice (ctf_file_t *fp, ctf_id_t id, ctf_encoding_t *enc) -{ - int kind = ctf_type_kind (fp, id); - - return (((kind == CTF_K_INTEGER) || (kind == CTF_K_ENUM) - || (kind == CTF_K_FLOAT)) - && ctf_type_reference (fp, id) != CTF_ERR - && ctf_type_encoding (fp, id, enc) == 0); -} - /* Return a dump for a single type, without member info: but do show the type's references. */ @@ -129,26 +115,45 @@ ctf_dump_format_type (ctf_file_t *fp, ctf_id_t id, int flag) goto err; } - /* Slices get a different print representation. */ + if (asprintf (&bit, " %s%lx: ", nonroot_leader, id) < 0) + goto oom; + str = str_append (str, bit); + free (bit); + bit = NULL; + + if (buf[0] != '\0') + { + str = str_append (str, buf); + str = str_append (str, " "); + } + + free (buf); + buf = NULL; - if (ctf_is_slice (fp, id, &enc)) + /* Slices get a different print representation. */ + if (ctf_type_kind_unsliced (fp, id) == CTF_K_SLICE) { ctf_type_encoding (fp, id, &enc); - if (asprintf (&bit, " %s%lx: [slice 0x%x:0x%x]%s", - nonroot_leader, id, enc.cte_offset, enc.cte_bits, - nonroot_trailer) < 0) + if (asprintf (&bit, "[slice 0x%x:0x%x] ", + enc.cte_offset, enc.cte_bits) < 0) goto oom; } - else + else if (ctf_type_kind (fp, id) == CTF_K_INTEGER) { - if (asprintf (&bit, " %s%lx: %s (size 0x%lx)%s", nonroot_leader, - id, buf[0] == '\0' ? "(nameless)" : buf, - (unsigned long) ctf_type_size (fp, id), - nonroot_trailer) < 0) + ctf_type_encoding (fp, id, &enc); + if (asprintf (&bit, "[0x%x:0x%x] ", + enc.cte_offset, enc.cte_bits) < 0) goto oom; } - free (buf); - buf = NULL; + str = str_append (str, bit); + free (bit); + bit = NULL; + + if (asprintf (&bit, "(size 0x%lx)%s", + (unsigned long) ctf_type_size (fp, id), + nonroot_trailer) < 0) + goto oom; + str = str_append (str, bit); free (bit); bit = NULL; @@ -516,6 +521,7 @@ ctf_dump_member (const char *name, ctf_id_t id, unsigned long offset, char *typestr = NULL; char *bit = NULL; ctf_encoding_t ep; + int has_encoding = 0; ssize_t i; for (i = 0; i < depth; i++) @@ -535,24 +541,40 @@ ctf_dump_member (const char *name, ctf_id_t id, unsigned long offset, return 0; } - goto oom; + return -1; /* errno is set for us. */ + } + + if (ctf_type_encoding (state->cdm_fp, id, &ep) == 0) + { + has_encoding = 1; + ctf_type_encoding (state->cdm_fp, id, &ep); + + if (asprintf (&bit, " [0x%lx] (ID 0x%lx) (kind %i) %s%s%s:%i " + "(aligned at 0x%lx", offset, id, + ctf_type_kind (state->cdm_fp, id), typestr, + (name[0] != 0 && typestr[0] != 0) ? " " : "", name, + ep.cte_bits, (unsigned long) ctf_type_align (state->cdm_fp, + id)) < 0) + goto oom; + } + else + { + if (asprintf (&bit, " [0x%lx] (ID 0x%lx) (kind %i) %s%s%s " + "(aligned at 0x%lx", offset, id, + ctf_type_kind (state->cdm_fp, id), typestr, + (name[0] != 0 && typestr[0] != 0) ? " " : "", name, + (unsigned long) ctf_type_align (state->cdm_fp, id)) < 0) + goto oom; } - if (asprintf (&bit, " [0x%lx] (ID 0x%lx) (kind %i) %s %s (aligned at 0x%lx", - offset, id, ctf_type_kind (state->cdm_fp, id), typestr, name, - (unsigned long) ctf_type_align (state->cdm_fp, id)) < 0) - goto oom; *state->cdm_str = str_append (*state->cdm_str, bit); free (typestr); free (bit); typestr = NULL; bit = NULL; - if ((ctf_type_kind (state->cdm_fp, id) == CTF_K_INTEGER) - || (ctf_type_kind (state->cdm_fp, id) == CTF_K_FLOAT) - || (ctf_is_slice (state->cdm_fp, id, &ep) == CTF_K_ENUM)) + if (has_encoding) { - ctf_type_encoding (state->cdm_fp, id, &ep); if (asprintf (&bit, ", format 0x%x, offset:bits 0x%x:0x%x", ep.cte_format, ep.cte_offset, ep.cte_bits) < 0) goto oom; |