}
#ifdef ENABLE_LIBCTF
+/* Emit CTF errors and warnings. fp can be NULL to report errors/warnings
+ that happened specifically at CTF open time. */
+static void
+lang_ctf_errs_warnings (ctf_file_t *fp)
+{
+ ctf_next_t *i = NULL;
+ char *text;
+ int is_warning;
+ int err;
+
+ while ((text = ctf_errwarning_next (fp, &i, &is_warning, &err)) != NULL)
+ {
+ einfo (_("%s: %s\n"), is_warning ? _("CTF warning"): _("CTF error"),
+ text);
+ free (text);
+ }
+ if (err != ECTF_NEXT_END)
+ {
+ einfo (_("CTF error: cannot get CTF errors: `%s'\n"),
+ ctf_errmsg (err));
+ }
+
+ /* `err' returns errors from the error/warning iterator in particular.
+ These never assert. But if we have an fp, that could have recorded
+ an assertion failure: assert if it has done so. */
+ ASSERT (!fp || ctf_errno (fp) != ECTF_INTERNAL);
+}
+
/* Open the CTF sections in the input files with libctf: if any were opened,
create a fake input file that we'll write the merged CTF data to later
on. */
if ((file->the_ctf = ctf_bfdopen (file->the_bfd, &err)) == NULL)
{
if (err != ECTF_NOCTFDATA)
- einfo (_("%P: warning: CTF section in %pB not loaded; "
- "its types will be discarded: `%s'\n"), file->the_bfd,
+ {
+ lang_ctf_errs_warnings (NULL);
+ einfo (_("%P: warning: CTF section in %pB not loaded; "
+ "its types will be discarded: %s\n"), file->the_bfd,
ctf_errmsg (err));
+ }
continue;
}
/* Prevent the contents of this section from being written, while
- requiring the section itself to be duplicated in the output. */
+ requiring the section itself to be duplicated in the output, but only
+ once. */
/* This section must exist if ctf_bfdopen() succeeded. */
sect = bfd_get_section_by_name (file->the_bfd, ".ctf");
sect->size = 0;
sect->flags |= SEC_NEVER_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED;
+ if (any_ctf)
+ sect->flags |= SEC_EXCLUDE;
any_ctf = 1;
}
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. */
lang_merge_ctf (void)
{
asection *output_sect;
+ int flags = 0;
if (!ctf_output)
return;
}
}
- if (ctf_link (ctf_output, CTF_LINK_SHARE_UNCONFLICTED) < 0)
+ if (!config.ctf_share_duplicated)
+ flags = CTF_LINK_SHARE_UNCONFLICTED;
+ else
+ flags = CTF_LINK_SHARE_DUPLICATED;
+ if (!config.ctf_variables)
+ flags |= CTF_LINK_OMIT_VARIABLES_SECTION;
+
+ if (ctf_link (ctf_output, flags) < 0)
{
+ lang_ctf_errs_warnings (ctf_output);
einfo (_("%P: warning: CTF linking failed; "
- "output will have no CTF section: `%s'\n"),
+ "output will have no CTF section: %s\n"),
ctf_errmsg (ctf_errno (ctf_output)));
if (output_sect)
{
output_sect->flags |= SEC_EXCLUDE;
}
}
+ /* Output any lingering errors that didn't come from ctf_link. */
lang_ctf_errs_warnings (ctf_output);
}
output_sect->size = output_size;
output_sect->flags |= SEC_IN_MEMORY | SEC_KEEP;
+ lang_ctf_errs_warnings (ctf_output);
if (!output_sect->contents)
{
einfo (_("%P: warning: CTF section emission failed; "
- "output will have no CTF section: `%s'\n"),
+ "output will have no CTF section: %s\n"),
ctf_errmsg (ctf_errno (ctf_output)));
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. */
input format may not have equivalent representations in
the output format (and besides BFD does not translate
relocs for other link purposes than a final link). */
- if ((bfd_link_relocatable (&link_info)
- || link_info.emitrelocations)
+ if (!file->flags.just_syms
+ && (bfd_link_relocatable (&link_info)
+ || link_info.emitrelocations)
&& (compatible == NULL
|| (bfd_get_flavour (input_bfd)
!= bfd_get_flavour (link_info.output_bfd)))
/* If the input bfd has no contents, it shouldn't set the
private data of the output bfd. */
- else if ((input_bfd->flags & DYNAMIC) != 0
- || bfd_count_sections (input_bfd) != 0)
+ else if (!file->flags.just_syms
+ && ((input_bfd->flags & DYNAMIC) != 0
+ || bfd_count_sections (input_bfd) != 0))
{
bfd_error_handler_type pfn = NULL;