/* SEC_MERGE support.
- Copyright (C) 2001-2020 Free Software Foundation, Inc.
+ Copyright (C) 2001-2023 Free Software Foundation, Inc.
Written by Jakub Jelinek <jakub@redhat.com>.
This file is part of BFD, the Binary File Descriptor library.
/* Entity size. */
unsigned int entsize;
/* Are entries fixed size or zero terminated strings? */
- bfd_boolean strings;
+ bool strings;
};
struct sec_merge_info
static struct sec_merge_hash_entry *
sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
- unsigned int alignment, bfd_boolean create)
+ unsigned int alignment, bool create)
{
const unsigned char *s;
unsigned long hash;
/* Create a new hash table. */
static struct sec_merge_hash *
-sec_merge_init (unsigned int entsize, bfd_boolean strings)
+sec_merge_init (unsigned int entsize, bool strings)
{
struct sec_merge_hash *table;
{
struct sec_merge_hash_entry *entry;
- entry = sec_merge_hash_lookup (tab, str, alignment, TRUE);
+ entry = sec_merge_hash_lookup (tab, str, alignment, true);
if (entry == NULL)
return NULL;
return entry;
}
-static bfd_boolean
+static bool
sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
unsigned char *contents, file_ptr offset)
{
asection *sec = secinfo->sec;
char *pad = NULL;
bfd_size_type off = 0;
- int alignment_power = sec->output_section->alignment_power;
- bfd_size_type pad_len;
+ unsigned int opb = bfd_octets_per_byte (abfd, sec);
+ int alignment_power = sec->output_section->alignment_power * opb;
+ bfd_size_type pad_len; /* Octets. */
/* FIXME: If alignment_power is 0 then really we should scan the
entry list for the largest required alignment and use that. */
pad = (char *) bfd_zmalloc (pad_len);
if (pad == NULL)
- return FALSE;
+ return false;
for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
{
}
free (pad);
- return TRUE;
+ return true;
err:
free (pad);
- return FALSE;
+ return false;
}
/* Register a SEC_MERGE section as a candidate for merging.
This function is called for all non-dynamic SEC_MERGE input sections. */
-bfd_boolean
+bool
_bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
void **psecinfo)
{
struct sec_merge_info *sinfo;
struct sec_merge_sec_info *secinfo;
- unsigned int align;
+ unsigned int alignment_power; /* Octets. */
+ unsigned int align; /* Octets. */
bfd_size_type amt;
bfd_byte *contents;
+ unsigned int opb = bfd_octets_per_byte (abfd, sec);
if ((abfd->flags & DYNAMIC) != 0
|| (sec->flags & SEC_MERGE) == 0)
if (sec->size == 0
|| (sec->flags & SEC_EXCLUDE) != 0
|| sec->entsize == 0)
- return TRUE;
+ return true;
if (sec->size % sec->entsize != 0)
- return TRUE;
+ return true;
if ((sec->flags & SEC_RELOC) != 0)
{
/* We aren't prepared to handle relocations in merged sections. */
- return TRUE;
+ return true;
}
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
- if (sec->alignment_power >= sizeof (align) * CHAR_BIT)
- return TRUE;
+ alignment_power = sec->alignment_power * opb;
+ if (alignment_power >= sizeof (align) * CHAR_BIT)
+ return true;
- align = 1u << sec->alignment_power;
+ align = 1u << alignment_power;
if ((sec->entsize < align
&& ((sec->entsize & (sec->entsize - 1))
|| !(sec->flags & SEC_STRINGS)))
of alignment. For non-string constants, alignment must
be smaller than or equal to entity size and entity size
must be integer multiple of alignment. */
- return TRUE;
+ return true;
}
for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
goto error_return;
- return TRUE;
+ return true;
error_return:
*psecinfo = NULL;
- return FALSE;
+ return false;
}
/* Record one section into the hash table. */
-static bfd_boolean
+static bool
record_section (struct sec_merge_info *sinfo,
struct sec_merge_sec_info *secinfo)
{
asection *sec = secinfo->sec;
struct sec_merge_hash_entry *entry;
- bfd_boolean nul;
+ bool nul;
unsigned char *p, *end;
bfd_vma mask, eltalign;
unsigned int align, i;
align = sec->alignment_power;
end = secinfo->contents + sec->size;
- nul = FALSE;
+ nul = false;
mask = ((bfd_vma) 1 << align) - 1;
if (sec->flags & SEC_STRINGS)
{
{
if (!nul && !((p - secinfo->contents) & mask))
{
- nul = TRUE;
+ nul = true;
entry = sec_merge_add (sinfo->htab, "",
(unsigned) mask + 1, secinfo);
if (! entry)
break;
if (!nul && !((p - secinfo->contents) & mask))
{
- nul = TRUE;
+ nul = true;
entry = sec_merge_add (sinfo->htab, (char *) p,
(unsigned) mask + 1, secinfo);
if (! entry)
}
}
- return TRUE;
+ return true;
-error_return:
+ error_return:
for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
*secinfo->psecinfo = NULL;
- return FALSE;
+ return false;
}
/* qsort comparison function. Won't ever return zero as all entries
/* This function is called once after all SEC_MERGE sections are registered
with _bfd_merge_section. */
-bfd_boolean
+bool
_bfd_merge_sections (bfd *abfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
void *xsinfo,
for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
{
struct sec_merge_sec_info *secinfo;
- bfd_size_type align;
+ bfd_size_type align; /* Bytes. */
if (! sinfo->chain)
continue;
else
{
if (!record_section (sinfo, secinfo))
- return FALSE;
+ return false;
if (align)
{
+ unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
+
align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
- if ((secinfo->sec->size & (align - 1)) != 0)
+ if (((secinfo->sec->size / opb) & (align - 1)) != 0)
align = 0;
}
}
{
secinfo = merge_strings (sinfo);
if (!secinfo)
- return FALSE;
+ return false;
}
else
{
struct sec_merge_hash_entry *e;
- bfd_size_type size = 0;
+ bfd_size_type size = 0; /* Octets. */
/* Things are much simpler for non-strings.
Just assign them slots in the section. */
secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP;
}
- return TRUE;
+ return true;
}
/* Write out the merged section. */
-bfd_boolean
+bool
_bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
{
struct sec_merge_sec_info *secinfo;
secinfo = (struct sec_merge_sec_info *) psecinfo;
if (!secinfo)
- return FALSE;
+ return false;
if (secinfo->first_str == NULL)
- return TRUE;
+ return true;
/* FIXME: octets_per_byte. */
hdr = &elf_section_data (sec->output_section)->this_hdr;
/* We must compress this section. Write output to the
buffer. */
contents = hdr->contents;
- if ((sec->output_section->flags & SEC_ELF_COMPRESS) == 0
- || contents == NULL)
+ if (contents == NULL)
abort ();
}
else
contents = NULL;
pos = sec->output_section->filepos + sec->output_offset;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
- return FALSE;
+ return false;
}
if (! sec_merge_emit (output_bfd, secinfo->first_str, contents,
sec->output_offset))
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
/* Adjust an address in the SEC_MERGE section. Given OFFSET within
{
p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
}
- entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, 0, FALSE);
+ entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, 0, false);
if (!entry)
{
if (! secinfo->htab->strings)