diff options
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index e036817..6e31c35 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -43,6 +43,7 @@ #include "hashtab.h" #include "elf-bfd.h" #include "bfdver.h" +#include <errno.h> #if BFD_SUPPORTS_PLUGINS #include "plugin.h" @@ -322,7 +323,7 @@ spec_match (const struct wildcard_spec *spec, const char *name) } static char * -ldirname (const char *name) +stat_ldirname (const char *name) { const char *base = lbasename (name); @@ -1266,7 +1267,7 @@ new_afile (const char *name, /* If name is a relative path, search the directory of the current linker script first. */ if (from_filename && !IS_ABSOLUTE_PATH (name)) - p->extra_search_path = ldirname (from_filename); + p->extra_search_path = stat_ldirname (from_filename); p->flags.real = true; p->flags.search_dirs = true; break; @@ -2874,7 +2875,7 @@ lang_add_section (lang_statement_list_type *ptr, /* This must happen after flags have been updated. The output section may have been created before we saw its first input section, eg. for a data statement. */ - bfd_init_private_section_data (section->owner, section, + bfd_copy_private_section_data (section->owner, section, link_info.output_bfd, output->bfd_section, &link_info); @@ -10494,7 +10495,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *p) /* Allow the BFD backend to copy any private data it understands from the input section to the output section. */ - if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) + if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection, NULL)) { err = _("failed to copy private data"); goto loser; @@ -10840,10 +10841,19 @@ cmdline_add_object_only_section (bfd_byte *contents, size_t size) fatal (_("%P: failed to finish output with object-only section\n")); } + /* ibfd needs to be closed *after* obfd, otherwise ld may crash with a + segmentation fault. */ + if (!bfd_close (ibfd)) + einfo (_("%P%F: failed to close input\n")); + /* Must be freed after bfd_close (). */ free (isympp); free (osympp); + /* Must unlink to ensure rename works on Windows. */ + if (unlink (output_filename) && errno != ENOENT) + einfo (_("%P%F: failed to unlink %s\n"), output_filename); + if (rename (ofilename, output_filename)) { unlink (ofilename); @@ -10854,10 +10864,14 @@ cmdline_add_object_only_section (bfd_byte *contents, size_t size) return; loser: - free (isympp); - free (osympp); if (obfd) bfd_close (obfd); + /* ibfd needs to be closed *after* obfd, otherwise ld may crash with a + segmentation fault. */ + if (ibfd) + bfd_close (ibfd); + free (isympp); + free (osympp); if (ofilename) { unlink (ofilename); @@ -10887,6 +10901,9 @@ cmdline_emit_object_only_section (void) lang_init (true); ldexp_init (true); + /* Allow lang_add_section to add new sections. */ + map_head_is_link_order = false; + /* Set up the object-only output. */ lang_final (); |