summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog5
-rw-r--r--binutils/objdump.c17
-rw-r--r--binutils/readelf.c23
-rw-r--r--include/ChangeLog5
-rw-r--r--include/ctf-api.h8
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/ldlang.c26
-rw-r--r--libctf/ChangeLog15
-rw-r--r--libctf/ctf-create.c2
-rw-r--r--libctf/ctf-impl.h17
-rw-r--r--libctf/ctf-inlines.h10
-rw-r--r--libctf/ctf-open.c9
-rw-r--r--libctf/ctf-subr.c93
-rw-r--r--libctf/libctf.ver1
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. */