diff options
-rw-r--r-- | binutils/ChangeLog | 5 | ||||
-rw-r--r-- | binutils/objdump.c | 17 | ||||
-rw-r--r-- | binutils/readelf.c | 23 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/ctf-api.h | 8 | ||||
-rw-r--r-- | ld/ChangeLog | 7 | ||||
-rw-r--r-- | ld/ldlang.c | 26 | ||||
-rw-r--r-- | libctf/ChangeLog | 15 | ||||
-rw-r--r-- | libctf/ctf-create.c | 2 | ||||
-rw-r--r-- | libctf/ctf-impl.h | 17 | ||||
-rw-r--r-- | libctf/ctf-inlines.h | 10 | ||||
-rw-r--r-- | libctf/ctf-open.c | 9 | ||||
-rw-r--r-- | libctf/ctf-subr.c | 93 | ||||
-rw-r--r-- | libctf/libctf.ver | 1 |
14 files changed, 235 insertions, 3 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 7aead1a6609..716950977a6 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2020-07-22 Nick Alcock <nick.alcock@oracle.com> + + * objdump.c (ctf_archive_member): Print CTF errors and warnings. + * readelf.c (dump_ctf_archive_member): Likewise. + 2020-07-22 Nick Clifton <nickc@redhat.com> * readelf.c (parse_args): Silence potential warnings about a diff --git a/binutils/objdump.c b/binutils/objdump.c index 93508e2a348..8d4b1b6ba94 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -4081,6 +4081,9 @@ dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg) "Function objects", "Variables", "Types", "Strings", ""}; const char **thing; + ctf_next_t *it = NULL; + char *errtext; + int is_warning; size_t i; /* Only print out the name of non-default-named archive members. @@ -4117,6 +4120,20 @@ dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg) break; } } + + /* Dump accumulated errors and warnings. */ + while ((errtext = ctf_errwarning_next (ctf, &it, &is_warning)) != NULL) + { + non_fatal (_("%s: `%s'"), is_warning ? _("warning"): _("error"), + errtext); + free (errtext); + } + if (ctf_errno (ctf) != ECTF_NEXT_END) + { + non_fatal (_("CTF error: cannot get CTF errors: `%s'"), + ctf_errmsg (ctf_errno (ctf))); + } + return 0; } diff --git a/binutils/readelf.c b/binutils/readelf.c index c3cbd2cb235..421992d12d9 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -14215,7 +14215,11 @@ dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg) "Function objects", "Variables", "Types", "Strings", ""}; const char **thing; + ctf_next_t *it = NULL; + char *errtext; + int is_warning; size_t i; + int err = 0; /* Only print out the name of non-default-named archive members. The name .ctf appears everywhere, even for things that aren't @@ -14248,10 +14252,25 @@ dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg) { error (_("Iteration failed: %s, %s\n"), *thing, ctf_errmsg (ctf_errno (ctf))); - return 1; + err = 1; + goto out; } } - return 0; + + out: + /* Dump accumulated errors and warnings. */ + while ((errtext = ctf_errwarning_next (ctf, &it, &is_warning)) != NULL) + { + error (_("%s: `%s'\n"), is_warning ? _("warning"): _("error"), + errtext); + free (errtext); + } + if (ctf_errno (ctf) != ECTF_NEXT_END) + { + error (_("CTF error: cannot get CTF errors: `%s'\n"), + ctf_errmsg (ctf_errno (ctf))); + } + return err; } static bfd_boolean diff --git a/include/ChangeLog b/include/ChangeLog index 8a48d009a69..d76ac8fbffc 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,5 +1,10 @@ 2020-07-22 Nick Alcock <nick.alcock@oracle.com> + * ctf-api.h (ECTF_INTERNAL): Adjust error text. + (ctf_errwarning_next): New. + +2020-07-22 Nick Alcock <nick.alcock@oracle.com> + * ctf-api.h (ECTF_FLAGS): New. (ECTF_NERR): Adjust. * ctf.h (CTF_F_MAX): New. diff --git a/include/ctf-api.h b/include/ctf-api.h index 760b1e46dc6..e061b7022b6 100644 --- a/include/ctf-api.h +++ b/include/ctf-api.h @@ -203,7 +203,7 @@ enum ECTF_DUMPSECTUNKNOWN, /* Unknown section number in dump. */ ECTF_DUMPSECTCHANGED, /* Section changed in middle of dump. */ ECTF_NOTYET, /* Feature not yet implemented. */ - ECTF_INTERNAL, /* Internal error in link. */ + ECTF_INTERNAL, /* Internal error: assertion failure. */ ECTF_NONREPRESENTABLE, /* Type not representable in CTF. */ ECTF_NEXT_END, /* End of iteration. */ ECTF_NEXT_WRONGFUN, /* Wrong iteration function called. */ @@ -396,6 +396,12 @@ extern char *ctf_dump (ctf_file_t *, ctf_dump_state_t **state, ctf_sect_names_t sect, ctf_dump_decorate_f *, void *arg); +/* Error-warning reporting: an 'iterator' that returns errors and warnings from + the error/warning list, in order of emission. Errors and warnings are popped + after return: the caller must free the returned error-text pointer. */ +extern char *ctf_errwarning_next (ctf_file_t *, ctf_next_t **, + int *is_warning); + extern ctf_id_t ctf_add_array (ctf_file_t *, uint32_t, const ctf_arinfo_t *); extern ctf_id_t ctf_add_const (ctf_file_t *, uint32_t, ctf_id_t); diff --git a/ld/ChangeLog b/ld/ChangeLog index aef3d97f87f..69272878842 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2020-07-22 Nick Alcock <nick.alcock@oracle.com> + + * ldlang.c (lang_ctf_errs_warnings): New, print CTF errors + and warnings. Assert when libctf asserts. + (lang_merge_ctf): Call it. + (land_write_ctf): Likewise. + 2020-07-22 H.J. Lu <hongjiu.lu@intel.com> PR ld/26262 diff --git a/ld/ldlang.c b/ld/ldlang.c index d3ed5d461e3..cc64e7a987a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -3725,6 +3725,29 @@ ldlang_open_ctf (void) ctf_close (errfile->the_ctf); } +/* Emit CTF errors and warnings. */ +static void +lang_ctf_errs_warnings (ctf_file_t *fp) +{ + ctf_next_t *i = NULL; + char *text; + int is_warning; + + while ((text = ctf_errwarning_next (fp, &i, &is_warning)) != NULL) + { + einfo (_("%s: `%s'\n"), is_warning ? _("CTF warning"): _("CTF error"), + text); + free (text); + } + if (ctf_errno (fp) != ECTF_NEXT_END) + { + einfo (_("CTF error: cannot get CTF errors: `%s'\n"), + ctf_errmsg (ctf_errno (fp))); + } + + ASSERT (ctf_errno (fp) != ECTF_INTERNAL); +} + /* Merge together CTF sections. After this, only the symtab-dependent function and data object sections need adjustment. */ @@ -3778,6 +3801,7 @@ lang_merge_ctf (void) output_sect->flags |= SEC_EXCLUDE; } } + lang_ctf_errs_warnings (ctf_output); } /* Let the emulation examine the symbol table and strtab to help it optimize the @@ -3831,6 +3855,8 @@ lang_write_ctf (int late) output_sect->size = 0; output_sect->flags |= SEC_EXCLUDE; } + + lang_ctf_errs_warnings (ctf_output); } /* This also closes every CTF input file used in the link. */ diff --git a/libctf/ChangeLog b/libctf/ChangeLog index f3ac4cc91e7..114d4e6c9a0 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,18 @@ +2020-07-22 Nick Alcock <nick.alcock@oracle.com> + + * ctf-impl.h (ctf_assert): New. + (ctf_err_warning_t): Likewise. + (ctf_file_t) <ctf_errs_warnings>: Likewise. + (ctf_err_warn): New prototype. + (ctf_assert_fail_internal): Likewise. + * ctf-inlines.h (ctf_assert_internal): Likewise. + * ctf-open.c (ctf_file_close): Free ctf_errs_warnings. + * ctf-create.c (ctf_serialize): Copy it on serialization. + * ctf-subr.c (ctf_err_warn): New, add an error/warning. + (ctf_errwarning_next): New iterator, free and pass back + errors/warnings in succession. + * libctf.ver (ctf_errwarning_next): Add. + 2020-07-22 Egeyar Bagcioglu <egeyar.bagcioglu@oracle.com> * ctf-types.c (ctf_variable_iter): Fix error return. diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index d50367d6de3..a538b2d5603 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -534,6 +534,7 @@ ctf_serialize (ctf_file_t *fp) nfp->ctf_ptrtab_len = fp->ctf_ptrtab_len; nfp->ctf_link_inputs = fp->ctf_link_inputs; nfp->ctf_link_outputs = fp->ctf_link_outputs; + nfp->ctf_errs_warnings = fp->ctf_errs_warnings; nfp->ctf_str_prov_offset = fp->ctf_str_prov_offset; nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab; nfp->ctf_link_cu_mapping = fp->ctf_link_cu_mapping; @@ -556,6 +557,7 @@ ctf_serialize (ctf_file_t *fp) fp->ctf_str_atoms = NULL; fp->ctf_prov_strtab = NULL; memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t)); + memset (&fp->ctf_errs_warnings, 0, sizeof (ctf_list_t)); fp->ctf_add_processing = NULL; fp->ctf_ptrtab = NULL; fp->ctf_link_inputs = NULL; diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index eea5204c51d..47a392723e9 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -70,6 +70,10 @@ extern "C" #endif +#define ctf_assert(fp, expr) \ + _libctf_unlikely_ (ctf_assert_internal (fp, __FILE__, __LINE__, \ + #expr, !!(expr))) + /* libctf in-memory state. */ typedef struct ctf_fixed_hash ctf_hash_t; /* Private to ctf-hash.c. */ @@ -195,6 +199,13 @@ typedef struct ctf_bundle ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any). */ } ctf_bundle_t; +typedef struct ctf_err_warning +{ + ctf_list_t cew_list; /* List forward/back pointers. */ + int cew_is_warning; /* 1 if warning, 0 if error. */ + char *cew_text; /* Error/warning text. */ +} ctf_err_warning_t; + /* Atoms associate strings with a list of the CTF items that reference that string, so that ctf_update() can instantiate all the strings using the ctf_str_atoms and then reassociate them with the real string later. @@ -297,6 +308,7 @@ struct ctf_file unsigned long ctf_snapshots; /* ctf_snapshot() plus ctf_update() count. */ unsigned long ctf_snapshot_lu; /* ctf_snapshot() call count at last update. */ ctf_archive_t *ctf_archive; /* Archive this ctf_file_t came from. */ + ctf_list_t ctf_errs_warnings; /* CTF errors and warnings. */ ctf_dynhash_t *ctf_link_inputs; /* Inputs to this link. */ ctf_dynhash_t *ctf_link_outputs; /* Additional outputs from this link. */ ctf_dynhash_t *ctf_link_type_mapping; /* Map input types to output types. */ @@ -543,6 +555,11 @@ _libctf_printflike_ (1, 2) extern void ctf_dprintf (const char *, ...); extern void libctf_init_debug (void); +_libctf_printflike_ (3, 4) +extern void ctf_err_warn (ctf_file_t *, int is_warning, const char *, ...); +extern void ctf_assert_fail_internal (ctf_file_t *, const char *, + size_t, const char *); + extern Elf64_Sym *ctf_sym_to_elf64 (const Elf32_Sym *src, Elf64_Sym *dst); extern const char *ctf_lookup_symbol_name (ctf_file_t *fp, unsigned long symidx); diff --git a/libctf/ctf-inlines.h b/libctf/ctf-inlines.h index a35b6cd5a77..affc9f91374 100644 --- a/libctf/ctf-inlines.h +++ b/libctf/ctf-inlines.h @@ -80,6 +80,16 @@ ctf_dynset_cinsert (ctf_dynset_t *h, const void *k) return ctf_dynset_insert (h, (void *) k); } +static inline int +ctf_assert_internal (ctf_file_t *fp, const char *file, size_t line, + const char *exprstr, int expr) +{ + if (_libctf_unlikely_ (!expr)) + ctf_assert_fail_internal (fp, file, line, exprstr); + + return expr; +} + #ifdef __cplusplus } #endif diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index f8eeaab0168..24899f08e20 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -1644,6 +1644,7 @@ ctf_file_close (ctf_file_t *fp) { ctf_dtdef_t *dtd, *ntd; ctf_dvdef_t *dvd, *nvd; + ctf_err_warning_t *err, *nerr; if (fp == NULL) return; /* Allow ctf_file_close(NULL) to simplify caller code. */ @@ -1710,6 +1711,14 @@ ctf_file_close (ctf_file_t *fp) ctf_dynhash_destroy (fp->ctf_link_cu_mapping); ctf_dynhash_destroy (fp->ctf_add_processing); + for (err = ctf_list_next (&fp->ctf_errs_warnings); err != NULL; err = nerr) + { + nerr = ctf_list_next (err); + ctf_list_delete (&fp->ctf_errs_warnings, err); + free (err->cew_text); + free (err); + } + free (fp->ctf_sxlate); free (fp->ctf_txlate); free (fp->ctf_ptrtab); diff --git a/libctf/ctf-subr.c b/libctf/ctf-subr.c index a5cde9d6f20..0b49ae9fca8 100644 --- a/libctf/ctf-subr.c +++ b/libctf/ctf-subr.c @@ -194,3 +194,96 @@ void ctf_dprintf (const char *format, ...) va_end (alist); } } + +/* Errors and warnings. */ +_libctf_printflike_ (3, 4) +extern void +ctf_err_warn (ctf_file_t *fp, int is_warning, const char *format, ...) +{ + va_list alist; + ctf_err_warning_t *cew; + + /* Don't bother reporting errors here: we can't do much about them if they + happen. If we're so short of memory that a tiny malloc doesn't work, a + vfprintf isn't going to work either and the caller will have to rely on the + ENOMEM return they'll be getting in short order anyway. */ + + if ((cew = malloc (sizeof (ctf_err_warning_t))) == NULL) + return; + + cew->cew_is_warning = is_warning; + va_start (alist, format); + if (vasprintf (&cew->cew_text, format, alist) < 0) + { + free (cew); + va_end (alist); + return; + } + va_end (alist); + + ctf_dprintf ("%s: %s\n", is_warning ? "error" : "warning", cew->cew_text); + + ctf_list_append (&fp->ctf_errs_warnings, cew); +} + +/* Error-warning reporting: an 'iterator' that returns errors and warnings from + the error/warning list, in order of emission. Errors and warnings are popped + after return: the caller must free the returned error-text pointer. */ +char * +ctf_errwarning_next (ctf_file_t *fp, ctf_next_t **it, int *is_warning) +{ + ctf_next_t *i = *it; + char *ret; + ctf_err_warning_t *cew; + + if (!i) + { + if ((i = ctf_next_create ()) == NULL) + { + ctf_set_errno (fp, ENOMEM); + return NULL; + } + + i->cu.ctn_fp = fp; + i->ctn_iter_fun = (void (*) (void)) ctf_errwarning_next; + *it = i; + } + + if ((void (*) (void)) ctf_errwarning_next != i->ctn_iter_fun) + { + ctf_set_errno (fp, ECTF_NEXT_WRONGFUN); + return NULL; + } + + if (fp != i->cu.ctn_fp) + { + ctf_set_errno (fp, ECTF_NEXT_WRONGFP); + return NULL; + } + + cew = ctf_list_next (&fp->ctf_errs_warnings); + + if (!cew) + { + ctf_next_destroy (i); + *it = NULL; + ctf_set_errno (fp, ECTF_NEXT_END); + return NULL; + } + + if (is_warning) + *is_warning = cew->cew_is_warning; + ret = cew->cew_text; + ctf_list_delete (&fp->ctf_errs_warnings, cew); + free (cew); + return ret; +} + +void +ctf_assert_fail_internal (ctf_file_t *fp, const char *file, size_t line, + const char *exprstr) +{ + ctf_err_warn (fp, 0, "%s: %lu: libctf assertion failed: %s", file, + (long unsigned int) line, exprstr); + ctf_set_errno (fp, ECTF_INTERNAL); +} diff --git a/libctf/libctf.ver b/libctf/libctf.ver index e99f890e0e1..f1c9b2bf003 100644 --- a/libctf/libctf.ver +++ b/libctf/libctf.ver @@ -154,6 +154,7 @@ LIBCTF_1.0 { ctf_setdebug; ctf_getdebug; + ctf_errwarning_next; /* Not yet part of the stable API. */ |