X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=libctf%2Fctf-dump.c;h=b8a81bc1ccf7e8b6f35f6d009c64f4e65d3e92c6;hb=3922b302645fda04da42a5279399578ae2f6206c;hp=2a888e136396c6af74564c8053d35ad976b799a5;hpb=d18f9f16299170e94a3d2e8a45aa349a25278aa3;p=deliverable%2Fbinutils-gdb.git diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c index 2a888e1363..b8a81bc1cc 100644 --- a/libctf/ctf-dump.c +++ b/libctf/ctf-dump.c @@ -1,5 +1,5 @@ /* Textual dumping of CTF data. - Copyright (C) 2019 Free Software Foundation, Inc. + Copyright (C) 2019-2020 Free Software Foundation, Inc. This file is part of libctf. @@ -20,6 +20,8 @@ #include #include +#define str_append(s, a) ctf_str_append_noerr (s, a) + /* One item to be dumped, in string form. */ typedef struct ctf_dump_item @@ -52,7 +54,7 @@ ctf_dump_append (ctf_dump_state_t *state, char *str) { ctf_dump_item_t *cdi; - if ((cdi = ctf_alloc (sizeof (struct ctf_dump_item))) == NULL) + if ((cdi = malloc (sizeof (struct ctf_dump_item))) == NULL) return (ctf_set_errno (state->cds_fp, ENOMEM)); cdi->cdi_item = str; @@ -73,7 +75,7 @@ ctf_dump_free (ctf_dump_state_t *state) { free (cdi->cdi_item); next_cdi = ctf_list_next (cdi); - ctf_free (cdi); + free (cdi); } } @@ -116,7 +118,16 @@ ctf_dump_format_type (ctf_file_t *fp, ctf_id_t id, int flag) buf = ctf_type_aname (fp, id); if (!buf) - goto oom; + { + if (id == 0 || ctf_errno (fp) == ECTF_NONREPRESENTABLE) + { + str = str_append (str, " (type not represented in CTF)"); + ctf_set_errno (fp, ECTF_NOTREF); + break; + } + + goto err; + } /* Slices get a different print representation. */ @@ -138,13 +149,13 @@ ctf_dump_format_type (ctf_file_t *fp, ctf_id_t id, int flag) } free (buf); buf = NULL; - str = ctf_str_append (str, bit); + str = str_append (str, bit); free (bit); bit = NULL; new_id = ctf_type_reference (fp, id); if (new_id != CTF_ERR) - str = ctf_str_append (str, " ->"); + str = str_append (str, " ->"); } while (new_id != CTF_ERR); if (ctf_errno (fp) != ECTF_NOTREF) @@ -156,10 +167,11 @@ ctf_dump_format_type (ctf_file_t *fp, ctf_id_t id, int flag) return str; oom: + ctf_set_errno (fp, errno); + err: free (buf); free (str); free (bit); - ctf_set_errno (fp, ENOMEM); return NULL; } @@ -178,7 +190,7 @@ ctf_dump_header_strfield (ctf_file_t *fp, ctf_dump_state_t *state, return 0; err: - return (ctf_set_errno (fp, -ENOMEM)); + return (ctf_set_errno (fp, errno)); } /* Dump one section-offset field from the file header into the cds_items. */ @@ -198,7 +210,7 @@ ctf_dump_header_sectfield (ctf_file_t *fp, ctf_dump_state_t *state, return 0; err: - return (ctf_set_errno (fp, -ENOMEM)); + return (ctf_set_errno (fp, errno)); } /* Dump the file header into the cds_items. */ @@ -286,7 +298,7 @@ ctf_dump_header (ctf_file_t *fp, ctf_dump_state_t *state) return 0; err: - return (ctf_set_errno (fp, -ENOMEM)); + return (ctf_set_errno (fp, errno)); } /* Dump a single label into the cds_items. */ @@ -300,7 +312,7 @@ ctf_dump_label (const char *name, const ctf_lblinfo_t *info, ctf_dump_state_t *state = arg; if (asprintf (&str, "%s -> ", name) < 0) - return (ctf_set_errno (state->cds_fp, ENOMEM)); + return (ctf_set_errno (state->cds_fp, errno)); if ((typestr = ctf_dump_format_type (state->cds_fp, info->ctb_type, CTF_ADD_ROOT)) == NULL) @@ -309,7 +321,7 @@ ctf_dump_label (const char *name, const ctf_lblinfo_t *info, return -1; /* errno is set for us. */ } - str = ctf_str_append (str, typestr); + str = str_append (str, typestr); free (typestr); ctf_dump_append (state, str); @@ -350,12 +362,12 @@ ctf_dump_objts (ctf_file_t *fp, ctf_dump_state_t *state) if (sym_name[0] == '\0') { if (asprintf (&str, "%lx -> ", (unsigned long) i) < 0) - return (ctf_set_errno (fp, ENOMEM)); + return (ctf_set_errno (fp, errno)); } else { if (asprintf (&str, "%s (%lx) -> ", sym_name, (unsigned long) i) < 0) - return (ctf_set_errno (fp, ENOMEM)); + return (ctf_set_errno (fp, errno)); } /* Variable type. */ @@ -366,7 +378,7 @@ ctf_dump_objts (ctf_file_t *fp, ctf_dump_state_t *state) return -1; /* errno is set for us. */ } - str = ctf_str_append (str, typestr); + str = str_append (str, typestr); free (typestr); ctf_dump_append (state, str); @@ -384,8 +396,9 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state) for (i = 0; i < fp->ctf_nsyms; i++) { - char *str ; + char *str; char *bit; + const char *err; const char *sym_name; ctf_funcinfo_t fi; ctf_id_t type; @@ -410,9 +423,12 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state) /* Return type. */ if ((str = ctf_type_aname (state->cds_fp, type)) == NULL) - goto err; + { + err = "look up return type"; + goto err; + } - str = ctf_str_append (str, " "); + str = str_append (str, " "); /* Function name. */ @@ -427,28 +443,34 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state) if (asprintf (&bit, "%s (0x%lx) ", sym_name, (unsigned long) i) < 0) goto oom; } - str = ctf_str_append (str, bit); - str = ctf_str_append (str, " ("); + str = str_append (str, bit); + str = str_append (str, " ("); free (bit); /* Function arguments. */ if (ctf_func_args (state->cds_fp, i, fi.ctc_argc, args) < 0) - goto err; + { + err = "look up argument type"; + goto err; + } for (j = 0; j < fi.ctc_argc; j++) { if ((bit = ctf_type_aname (state->cds_fp, args[j])) == NULL) - goto err; - str = ctf_str_append (str, bit); + { + err = "look up argument type name"; + goto err; + } + str = str_append (str, bit); if ((j < fi.ctc_argc - 1) || (fi.ctc_flags & CTF_FUNC_VARARG)) - str = ctf_str_append (str, ", "); + str = str_append (str, ", "); free (bit); } if (fi.ctc_flags & CTF_FUNC_VARARG) - str = ctf_str_append (str, "..."); - str = ctf_str_append (str, ")"); + str = str_append (str, "..."); + str = str_append (str, ")"); free (args); ctf_dump_append (state, str); @@ -457,8 +479,11 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state) oom: free (args); free (str); - return (ctf_set_errno (fp, ENOMEM)); + return (ctf_set_errno (fp, errno)); err: + ctf_dprintf ("Cannot %s dumping function type for symbol 0x%li: %s\n", + err, (unsigned long) i, + ctf_errmsg (ctf_errno (state->cds_fp))); free (args); free (str); return -1; /* errno is set for us. */ @@ -475,7 +500,7 @@ ctf_dump_var (const char *name, ctf_id_t type, void *arg) ctf_dump_state_t *state = arg; if (asprintf (&str, "%s -> ", name) < 0) - return (ctf_set_errno (state->cds_fp, ENOMEM)); + return (ctf_set_errno (state->cds_fp, errno)); if ((typestr = ctf_dump_format_type (state->cds_fp, type, CTF_ADD_ROOT)) == NULL) @@ -484,7 +509,7 @@ ctf_dump_var (const char *name, ctf_id_t type, void *arg) return -1; /* errno is set for us. */ } - str = ctf_str_append (str, typestr); + str = str_append (str, typestr); free (typestr); ctf_dump_append (state, str); @@ -503,16 +528,30 @@ ctf_dump_member (const char *name, ctf_id_t id, unsigned long offset, ssize_t i; for (i = 0; i < depth; i++) - *state->cdm_str = ctf_str_append (*state->cdm_str, " "); + *state->cdm_str = str_append (*state->cdm_str, " "); if ((typestr = ctf_type_aname (state->cdm_fp, id)) == NULL) - goto oom; + { + if (id == 0 || ctf_errno (state->cdm_fp) == ECTF_NONREPRESENTABLE) + { + if (asprintf (&bit, " [0x%lx] (type not represented in CTF)", + offset) < 0) + goto oom; + + *state->cdm_str = str_append (*state->cdm_str, bit); + free (typestr); + free (bit); + return 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 = ctf_str_append (*state->cdm_str, bit); + *state->cdm_str = str_append (*state->cdm_str, bit); free (typestr); free (bit); typestr = NULL; @@ -526,36 +565,47 @@ ctf_dump_member (const char *name, ctf_id_t id, unsigned long offset, if (asprintf (&bit, ", format 0x%x, offset:bits 0x%x:0x%x", ep.cte_format, ep.cte_offset, ep.cte_bits) < 0) goto oom; - *state->cdm_str = ctf_str_append (*state->cdm_str, bit); + *state->cdm_str = str_append (*state->cdm_str, bit); free (bit); bit = NULL; } - *state->cdm_str = ctf_str_append (*state->cdm_str, ")\n"); + *state->cdm_str = str_append (*state->cdm_str, ")\n"); return 0; oom: free (typestr); free (bit); - return (ctf_set_errno (state->cdm_fp, ENOMEM)); + return (ctf_set_errno (state->cdm_fp, errno)); } /* Dump a single type into the cds_items. */ - static int ctf_dump_type (ctf_id_t id, int flag, void *arg) { char *str; + const char *err; ctf_dump_state_t *state = arg; ctf_dump_membstate_t membstate = { &str, state->cds_fp }; size_t len; if ((str = ctf_dump_format_type (state->cds_fp, id, flag)) == NULL) - goto err; + { + err = "format type"; + goto err; + } - str = ctf_str_append (str, "\n"); + str = str_append (str, "\n"); if ((ctf_type_visit (state->cds_fp, id, ctf_dump_member, &membstate)) < 0) - goto err; + { + if (id == 0 || ctf_errno (state->cds_fp) == ECTF_NONREPRESENTABLE) + { + ctf_dump_append (state, str); + return 0; + } + err = "visit members"; + goto err; + } /* Trim off the last linefeed added by ctf_dump_member(). */ len = strlen (str); @@ -566,6 +616,8 @@ ctf_dump_type (ctf_id_t id, int flag, void *arg) return 0; err: + ctf_dprintf ("Cannot %s dumping type 0x%lx: %s\n", err, id, + ctf_errmsg (ctf_errno (state->cds_fp))); free (str); return -1; /* errno is set for us. */ } @@ -584,7 +636,7 @@ ctf_dump_str (ctf_file_t *fp, ctf_dump_state_t *state) if (asprintf (&str, "%lx: %s", (unsigned long) (s - fp->ctf_str[CTF_STRTAB_0].cts_strs), s) < 0) - return (ctf_set_errno (fp, ENOMEM)); + return (ctf_set_errno (fp, errno)); ctf_dump_append (state, str); s += strlen (s) + 1; } @@ -618,7 +670,7 @@ ctf_dump (ctf_file_t *fp, ctf_dump_state_t **statep, ctf_sect_names_t sect, by bit. The first call will take (much) longer than otherwise, but the amortized time needed is the same. */ - if ((*statep = ctf_alloc (sizeof (struct ctf_dump_state))) == NULL) + if ((*statep = malloc (sizeof (struct ctf_dump_state))) == NULL) { ctf_set_errno (fp, ENOMEM); goto end; @@ -702,8 +754,8 @@ ctf_dump (ctf_file_t *fp, ctf_dump_state_t **statep, ctf_sect_names_t sect, nline[0] = '\0'; ret = func (sect, line, arg); - str = ctf_str_append (str, ret); - str = ctf_str_append (str, "\n"); + str = str_append (str, ret); + str = str_append (str, "\n"); if (ret != line) free (ret); @@ -722,14 +774,21 @@ ctf_dump (ctf_file_t *fp, ctf_dump_state_t **statep, ctf_sect_names_t sect, str[len-1] = '\0'; } else - str = strdup (state->cds_current->cdi_item); + { + str = strdup (state->cds_current->cdi_item); + if (!str) + { + ctf_set_errno (fp, ENOMEM); + return str; + } + } ctf_set_errno (fp, 0); return str; end: ctf_dump_free (state); - ctf_free (state); + free (state); ctf_set_errno (fp, 0); *statep = NULL; return NULL;