/* SEC_MERGE support.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
Written by Jakub Jelinek <jakub@redhat.com>.
This file is part of BFD, the Binary File Descriptor library.
subclass. */
if (entry == NULL)
entry = (struct bfd_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry));
+ bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry));
if (entry == NULL)
return NULL;
char *pad = NULL;
bfd_size_type off = 0;
int alignment_power = sec->output_section->alignment_power;
+ bfd_size_type pad_len;
- if (alignment_power)
- {
- pad = (char *) bfd_zmalloc ((bfd_size_type) 1 << alignment_power);
- if (pad == NULL)
- return FALSE;
- }
+ /* FIXME: If alignment_power is 0 then really we should scan the
+ entry list for the largest required alignment and use that. */
+ pad_len = alignment_power ? ((bfd_size_type) 1 << alignment_power) : 16;
+
+ pad = (char *) bfd_zmalloc (pad_len);
+ if (pad == NULL)
+ return FALSE;
for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
{
len = -off & (entry->alignment - 1);
if (len != 0)
{
+ BFD_ASSERT (len <= pad_len);
if (contents)
{
memcpy (contents + offset, pad, len);
off = sec->size - off;
if (off != 0)
{
+ BFD_ASSERT (off <= pad_len);
if (contents)
memcpy (contents + offset, pad, off);
else if (bfd_bwrite (pad, off, abfd) != off)
goto err;
}
- if (pad != NULL)
- free (pad);
+ free (pad);
return TRUE;
err:
- if (pad != NULL)
- free (pad);
+ free (pad);
return FALSE;
}
|| sec->entsize == 0)
return TRUE;
+ if (sec->size % sec->entsize != 0)
+ return TRUE;
+
if ((sec->flags & SEC_RELOC) != 0)
{
/* We aren't prepared to handle relocations in merged sections. */
{
/* Initialize the information we need to keep track of. */
sinfo = (struct sec_merge_info *)
- bfd_alloc (abfd, sizeof (struct sec_merge_info));
+ bfd_alloc (abfd, sizeof (struct sec_merge_info));
if (sinfo == NULL)
goto error_return;
sinfo->next = (struct sec_merge_info *) *psinfo;
/* This is a helper function for _bfd_merge_sections. It attempts to
merge strings matching suffixes of longer strings. */
-static void
+static bfd_boolean
merge_strings (struct sec_merge_info *sinfo)
{
struct sec_merge_hash_entry **array, **a, *e;
amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
if (array == NULL)
- goto alloc_failure;
+ return FALSE;
for (e = sinfo->htab->first, a = array; e; e = e->next)
if (e->alignment)
}
}
-alloc_failure:
- if (array)
- free (array);
+ free (array);
/* Now assign positions to the strings we want to keep. */
size = 0;
e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
}
}
+ return TRUE;
}
/* This function is called once after all SEC_MERGE sections are registered
(*remove_hook) (abfd, secinfo->sec);
}
else if (! record_section (sinfo, secinfo))
- break;
+ return FALSE;
if (secinfo)
continue;
continue;
if (sinfo->htab->strings)
- merge_strings (sinfo);
+ {
+ if (!merge_strings (sinfo))
+ return FALSE;
+ }
else
{
struct sec_merge_hash_entry *e;
if (offset > sec->rawsize)
_bfd_error_handler
/* xgettext:c-format */
- (_("%s: access beyond end of merged section (%ld)"),
- bfd_get_filename (sec->owner), (long) offset);
+ (_("%pB: access beyond end of merged section (%" PRId64 ")"),
+ sec->owner, (int64_t) offset);
return secinfo->first_str ? sec->size : 0;
}