Skip to content

Commit

Permalink
Check to see if the input BFD actually contains any sections.
Browse files Browse the repository at this point in the history
  • Loading branch information
claziss committed Aug 4, 2015
1 parent a6014a9 commit a65b844
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 23 deletions.
9 changes: 9 additions & 0 deletions bfd/ChangeLog.ARC
@@ -1,3 +1,12 @@
2015-08-04 Claudiu Zissulescu <claziss@synopsys.com>

* 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 <andrew.burgess@embecosm.com>

* elf32-arc.c (arc_relocation_byte_alignment): New function.
Expand Down
70 changes: 47 additions & 23 deletions bfd/elf32-arc.c
Expand Up @@ -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;
Expand All @@ -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))
{
Expand Down

0 comments on commit a65b844

Please sign in to comment.