From a65b844aed9153789356e098984452df2f5d9058 Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Tue, 4 Aug 2015 12:53:11 +0200 Subject: [PATCH] Check to see if the input BFD actually contains any sections. --- bfd/ChangeLog.ARC | 9 ++++++ bfd/elf32-arc.c | 70 +++++++++++++++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/bfd/ChangeLog.ARC b/bfd/ChangeLog.ARC index 25b77ad29e0..35af0ea02f7 100644 --- a/bfd/ChangeLog.ARC +++ b/bfd/ChangeLog.ARC @@ -1,3 +1,12 @@ +2015-08-04 Claudiu Zissulescu + + * elf32-arc.c (arc_elf_merge_private_bfd_data): Check to see + if the input BFD actually contains any sections. If not, its + flags may not have been initialised either, but it cannot + actually cause any incompatiblity. Do not short-circuit + dynamic objects; their section list may be emptied by + elf_link_add_object_symbols. + 2015-06-08 Andrew Burgess * elf32-arc.c (arc_relocation_byte_alignment): New function. diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index 38f72b4064b..76bac6cc5e3 100644 --- a/bfd/elf32-arc.c +++ b/bfd/elf32-arc.c @@ -881,44 +881,68 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { unsigned short mach_ibfd; static unsigned short mach_obfd = EM_NONE; - flagword old_flags; - flagword new_flags; + flagword out_flags; + flagword in_flags; + asection *sec; + + /* Check if we have the same endianess. */ + if (! _bfd_generic_verify_endian_match (ibfd, obfd)) + { + _bfd_error_handler ( + _("ERROR: Endian Match failed . Attempting to link %B with binary %s \ +of opposite endian-ness"), + ibfd, bfd_get_filename (obfd)); + return FALSE; + } /* Collect ELF flags. */ - new_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK; - old_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK; + in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK; + out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK; #if DEBUG - (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s", - old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no", + (*_bfd_error_handler) ("out_flags = 0x%.8lx, in_flags = 0x%.8lx, init = %s, filename = %s", + out_flags, in_flags, elf_flags_init (obfd) ? "yes" : "no", bfd_get_filename (ibfd)); #endif if (!elf_flags_init (obfd)) /* First call, no flags set. */ { elf_flags_init (obfd) = TRUE; - old_flags = new_flags; + out_flags = in_flags; } if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return TRUE; - if (bfd_count_sections (ibfd) == 0) - return TRUE ; /* For the case of empty archive files */ + /* Check to see if the input BFD actually contains any sections. If + not, its flags may not have been initialised either, but it + cannot actually cause any incompatiblity. Do not short-circuit + dynamic objects; their section list may be emptied by + elf_link_add_object_symbols. */ + if (!(ibfd->flags & DYNAMIC)) + { + bfd_boolean null_input_bfd = TRUE; + bfd_boolean only_data_sections = TRUE; - mach_ibfd = elf_elfheader (ibfd)->e_machine; + for (sec = ibfd->sections; sec != NULL; sec = sec->next) + { + if ((bfd_get_section_flags (ibfd, sec) + & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)) + == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)) + only_data_sections = FALSE; - /* Check if we have the same endianess. */ - if (! _bfd_generic_verify_endian_match (ibfd, obfd)) - { - _bfd_error_handler (_("\ -ERROR: Endian Match failed . Attempting to link %B with binary %s \ -of opposite endian-ness"), - ibfd, bfd_get_filename (obfd)); - return FALSE; + null_input_bfd = FALSE; + break; + } + + if (null_input_bfd || only_data_sections) + return TRUE; } + + /* Complain about various flag/architecture mismatches. */ + mach_ibfd = elf_elfheader (ibfd)->e_machine; if (mach_obfd == EM_NONE) { mach_obfd = mach_ibfd; @@ -932,23 +956,23 @@ with a binary %s of different architecture"), ibfd, bfd_get_filename (obfd)); return FALSE; } - else if (new_flags != old_flags) + else if (in_flags != out_flags) { /* Warn if different flags. */ (*_bfd_error_handler) (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"), - bfd_get_filename (ibfd), (long)new_flags, (long)old_flags); - if (new_flags && old_flags) + bfd_get_filename (ibfd), (long)in_flags, (long)out_flags); + if (in_flags && out_flags) return FALSE; /* MWDT doesnt set the eflags hence make sure we choose the eflags set by gcc. */ - new_flags = new_flags > old_flags ? new_flags : old_flags; + in_flags = in_flags > out_flags ? in_flags : out_flags; } } /* Update the flags. */ - elf_elfheader (obfd)->e_flags = new_flags; + elf_elfheader (obfd)->e_flags = in_flags; if (bfd_get_mach (obfd) < bfd_get_mach (ibfd)) {