/* SEC_MERGE support.
   Copyright (C) 2001-2025 Free Software Foundation, Inc.
   Written by Jakub Jelinek <jakub@redhat.com>.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */


/* This file contains support for merging duplicate entities within sections,
   as used in ELF SHF_MERGE.  */

#include "sysdep.h"
#include <limits.h>
#include "bfd.h"
#include "elf-bfd.h"
#include "libbfd.h"
#include "objalloc.h"
#include "libiberty.h"

/* We partition all mergable input sections into sets of similar
   characteristics.  These sets are the unit of merging.  All content
   of the input sections is scanned and inserted into a hash table.
   We also remember an input-offset to entry mapping per input section, but
   the content itself is removed.  After everything is read in we assign
   output offsets to all hash entries, and when relocations are processed we
   lookup the given input offset per input-section, get the matching entry
   and its output offset (possibly adjusted for offset pointing into the
   middle of an entry).

   The input-offset-to-entry mapping (in map_ofs/map) is sorted, so in principle
   we could binary search it, but that's not cache-friendly and it's faster
   to add another lookup structure that gets us very near the correct
   entry in just one step (that's what ofstolowbound is for) and do a linear
   search from there.  */

/* An entry in the section merge hash table.  */

struct sec_merge_hash_entry
{
  /* Length of this entry.  This includes the zero terminator.  */
  unsigned int len;
  /* Start of this string needs to be aligned to
     alignment octets (not 1 << align).  */
  unsigned int alignment;
  union
  {
    /* Index within the merged section.  */
    bfd_size_type index;
    /* Entry this is a suffix of (if alignment is 0).  */
    struct sec_merge_hash_entry *suffix;
  } u;
  /* Next entity in the hash table (in order of entering).  */
  struct sec_merge_hash_entry *next;
  char str[1];
};

/* The section merge hash table.  */

struct sec_merge_hash
{
  struct bfd_hash_table table;
  /* First entity in the SEC_MERGE sections of this type.  */
  struct sec_merge_hash_entry *first;
  /* Last entity in the SEC_MERGE sections of this type.  */
  struct sec_merge_hash_entry *last;
  /* Entity size.  */
  unsigned int entsize;
  /* Are entries fixed size or zero terminated strings?  */
  bool strings;
  /* struct-of-array variant of all entries in the hash-table: */
  unsigned int nbuckets;
  /* We keep hash-code and length of entry together in a separate
     array in such a way that it can be checked with just a single memory
     reference.  In this way we don't need indirect access to the entries
     in the normal case.  keys_lens[i] is 'hashcode << 32) | len' for entry
     i (which is pointed to be values[i]).  */
  uint64_t *key_lens;
  struct sec_merge_hash_entry **values;
};

struct sec_merge_sec_info;

/* Information per merged blob.  This is the unit of merging and is
   related to (multiple) input sections of similar characteristics
   (alignment, entity size, strings or blobs).  */
struct sec_merge_info
{
  /* Chain of sec_merge_infos.  */
  struct sec_merge_info *next;
  /* Chain of sec_merge_sec_infos.  This first one will be the representative
     section that conceptually collects all merged content.  */
  struct sec_merge_sec_info *chain;
  struct sec_merge_sec_info **last;
  /* A hash table used to hold section content.  */
  struct sec_merge_hash *htab;
};

/* Offset into input mergable sections are represented by this type.
   Note how doesn't support crazy large mergable sections.  */
typedef uint32_t mapofs_type;

/* Given a sec_merge_sec_info S this gives the input offset of the IDX's
   recorded entry.  */
#define MAP_OFS(S,IDX) (S)->map_ofs[IDX]
/* And this gives the output offset (in the merged blob representing
   this S.  */
#define MAP_IDX(S,IDX) (S)->map[IDX].idx
/* For quick lookup of output offset given an input offset we store
   an array mapping intput-offset / OFSDIV to entry index.
   16 is better than 8, 32 is roughly same as 16, but uses less memory, so
   we use that. */
#define OFSDIV 32

/* Information per input merge section.  */
struct sec_merge_sec_info
{
  /* Chain of sec_merge_sec_infos.  */
  struct sec_merge_sec_info *next;
  /* The corresponding section.  */
  asection *sec;
  /* Pointer to merge_info pointing to us.  */
  void **psecinfo;
  /* The merge entity this is a part of.  */
  struct sec_merge_info *sinfo;
  /* The section associated with sinfo (i.e. the representative section).
     Same as sinfo->chain->sec, but faster to access in the hot function.  */
  asection *reprsec;
  /* First string in this section.  */
  struct sec_merge_hash_entry *first_str;
  /* Sparse mapping from input offset to entry covering that offset:  */
  unsigned int noffsetmap;  /* Number of these mappings.  */
  mapofs_type *map_ofs;     /* Input offset.  */
  union {
      struct sec_merge_hash_entry *entry;  /* Covering hash entry ... */
      bfd_size_type idx;                   /* ... or destination offset.  */
  } *map;
  /* Quick access: index into map_ofs[].  ofstolowbound[o / OFSDIV]=I is
     such that map_ofs[I] is the smallest offset higher that
     rounddown(o, OFSDIV) (and hence I-1 is the largest entry whose offset is
     smaller or equal to o/OFSDIV*OFSDIV).  */
  unsigned int *ofstolowbound;
  int fast_state;
};


/* True when COUNT+ADDED and NBUCKETS indicate that the hash table
   needs resizing.  */

static inline bool
needs_resize (unsigned int count, unsigned int added, unsigned int nbuckets)
{
  /* This doesn't consider the possibility of "count" + "added"
     overflowing, because that can't happen given current usage.  If
     code calling this function changes then that assumption may no
     longer be correct.  Currently "added" is always 1 and "nbuckets"
     is limited to 0x80000000.  We'll attempt and fail resizing at
     "count" of 0x55555555.  */
  return count + added > nbuckets / 3 * 2;
}

/* Given a merge hash table TABLE and a number of entries to be
   ADDED, resize the table for this to fit.
   Returns false if that can't be done for whatever reason.  */

static bool
sec_merge_resize (struct sec_merge_hash *table, unsigned added)
{
  struct bfd_hash_table *bfdtab = &table->table;
  unsigned i;
  unsigned long newnb = table->nbuckets;
  struct sec_merge_hash_entry **newv;
  uint64_t *newl;
  unsigned long alloc;

  do
    {
      if (newnb >> (8 * sizeof(mapofs_type) - 1))
	return false;
      newnb *= 2;
    }
  while (needs_resize (bfdtab->count, added, newnb));

  alloc = newnb * sizeof (newl[0]);
  if (alloc / sizeof (newl[0]) != newnb)
    return false;
  newl = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
  if (newl == NULL)
    return false;
  memset (newl, 0, alloc);
  alloc = newnb * sizeof (newv[0]);
  if (alloc / sizeof (newv[0]) != newnb)
    return false;
  newv = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
  if (newv == NULL)
    return false;
  memset (newv, 0, alloc);

  for (i = 0; i < table->nbuckets; i++)
    {
      struct sec_merge_hash_entry *v = table->values[i];
      if (v)
	{
	  uint32_t thishash = table->key_lens[i] >> 32;
	  unsigned idx = thishash & (newnb - 1);
	  while (newv[idx])
	    idx = (idx + 1) & (newnb - 1);
	  newl[idx] = table->key_lens[i];
	  newv[idx] = v;
	}
    }

  table->key_lens = newl;
  table->values = newv;
  table->nbuckets = newnb;
  return true;
}

/* Insert STRING (actually a byte blob of length LEN, with pre-computed
   HASH and bucket _INDEX) into our hash TABLE.  */

static struct sec_merge_hash_entry *
sec_merge_hash_insert (struct sec_merge_hash *table,
		 const char *string,
		 uint64_t hash, unsigned int len, unsigned int _index)
{
  struct bfd_hash_table *bfdtab = &table->table;
  struct sec_merge_hash_entry *hashp;

  hashp = (struct sec_merge_hash_entry *)
      bfd_hash_allocate (bfdtab, len + sizeof (struct sec_merge_hash_entry));
  if (hashp == NULL)
    return NULL;

  memcpy (hashp->str, string, len);
  hashp->len = len;
  hashp->alignment = 0;
  hashp->u.suffix = NULL;
  hashp->next = NULL;

  if (needs_resize (bfdtab->count, 1, table->nbuckets))
    {
      if (!sec_merge_resize (table, 1))
	return NULL;
      uint64_t *key_lens = table->key_lens;
      unsigned int nbuckets = table->nbuckets;
      _index = hash & (nbuckets - 1);
      while (1)
	{
	  uint64_t candlen = key_lens[_index];
	  if (!(candlen & (uint32_t)-1))
	    break;
	  _index = (_index + 1) & (nbuckets - 1);
	}
    }

  bfdtab->count++;
  table->key_lens[_index] = (hash << 32) | (uint32_t)len;
  table->values[_index] = hashp;

  return hashp;
}

/* Read four bytes from *STR, interpret it as 32bit unsigned little
   endian value and return that.  */

static inline uint32_t
hash_read32 (const char *str)
{
  uint32_t i;
  /* All reasonable compilers will inline this memcpy and generate optimal
     code on architectures that support unaligned (4-byte) accesses.  */
  memcpy(&i, str, 4);
#ifdef WORDS_BIGENDIAN
  i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
#endif
  return i;
}

/* Calculate and return a hashvalue of the bytes at STR[0..LEN-1].
   All non-zero lengths and all alignments are supported.

   This is somewhat similar to xxh3 (of xxhash), but restricted to 32bit.
   On cc1 strings this has quite similar statistic properties, and we
   don't need to jump through hoops to get fast 64x64->128 mults,
   or 64bit arith on 32 bit hosts.  We also don't care for seeds
   or secrets.  They improve mixing very little.  */

static uint32_t
hash_blob (const char *str, unsigned int len)
{
  uint32_t ret = 0;
  uint32_t mul = (1 << 0) +  (1 << 2) + (1 << 3) + (1 << 5) + (1 << 7);
  mul += (1 << 11) + (1 << 13) + (1 << 17) + (0 << 19) + (1 << 23) + (1 << 29);
  mul += (1u << 31);
  if (len >= 8)
    {
      uint32_t acc = len * 0x9e3779b1;
      while (len >= 8)
	{
	  uint32_t i1 = hash_read32  (str) ^ (0x396cfeb8 + 1*len);
	  uint32_t i2 = hash_read32  (str + 4) ^ (0xbe4ba423 + 1*len);
	  str += 8;
	  len -= 8;
	  uint64_t m = (uint64_t)i1 * i2;
	  acc += (uint32_t)m ^ (uint32_t)(m >> 32);
	}
      acc = acc ^ (acc >> 7);
      uint64_t r = (uint64_t)mul * acc;
      ret = (uint32_t)r ^ (uint32_t)(r >> 32);
      if (len == 0)
	goto end;
    }
  if (len >= 4)
    {
      uint32_t i1 = hash_read32  (str);
      uint32_t i2 = hash_read32  (str + len - 4);
      i1 = ((i1 + len) ^ (i1 >> 7));
      i2 = i2 ^ (i2 >> 7);
      uint64_t r = (uint64_t)mul * i1 + i2;
      ret += r ^ (r >> 32);
    }
  else
    {
      /* Cleverly read in 1 to 3 bytes without further conditionals.  */
      unsigned char c1 = str[0];
      unsigned char c2 = str[len >> 1];
      unsigned char c3 = str[len - 1];
      uint32_t i1 = ((uint32_t)c1 << 16) | ((uint32_t)c2 << 24)
		     | ((uint32_t) c3) | (len << 8);
      i1 = i1 ^ (i1 >> 7);
      uint64_t r = (uint64_t)mul * i1;
      ret += r ^ (r >> 32);
    }
end:
  return ret;
}

/* Given a hash TABLE, return the hash of STRING (a blob described
   according to info in TABLE, either a character string, or some fixed
   size entity) and set *PLEN to the length of this blob.  */

static uint32_t
hashit (struct sec_merge_hash *table, const char *string, unsigned int *plen)
{
  const unsigned char *s;
  uint32_t hash;
  unsigned int len, i;

  s = (const unsigned char *) string;
  if (table->strings)
    {
      if (table->entsize == 1)
	len = strlen (string) + 1;
      else
	{
	  len = 0;
	  for (;;)
	    {
	      for (i = 0; i < table->entsize; ++i)
		if (s[i] != '\0')
		  break;
	      if (i == table->entsize)
		break;
	      s += table->entsize;
	      ++len;
	    }
	  len *= table->entsize;
	  len += table->entsize;
	}
    }
  else
    len = table->entsize;
  hash = hash_blob (string, len);
  *plen = len;
  return hash;
}

/* Lookup or insert a blob STRING (of length LEN, precomputed HASH and
   input ALIGNMENT) into TABLE.  Return the found or new hash table entry.  */

static struct sec_merge_hash_entry *
sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
		       unsigned int len, uint64_t hash,
		       unsigned int alignment)
{
  struct sec_merge_hash_entry *hashp;
  unsigned int _index;

  /*printf ("YYY insert 0x%x into %u buckets (%s)\n",
	  (unsigned)hash, (unsigned)table->nbuckets, string);*/
  uint64_t *key_lens = table->key_lens;
  struct sec_merge_hash_entry **values = table->values;
  uint64_t hlen = (hash << 32) | (uint32_t)len;
  unsigned int nbuckets = table->nbuckets;
  _index = hash & (nbuckets - 1);
  while (1)
    {
      uint64_t candlen = key_lens[_index];
      if (candlen == hlen
	  && !memcmp (values[_index]->str, string, len))
	{
	  hashp = values[_index];
	  if (hashp->alignment < alignment)
	    hashp->alignment = alignment;
	  return hashp;
	}
      if (!(candlen & (uint32_t)-1))
	break;
      _index = (_index + 1) & (nbuckets - 1);
    }

  hashp = sec_merge_hash_insert (table, string, hash, len, _index);
  if (hashp == NULL)
    return NULL;
  hashp->alignment = alignment;

  if (table->first == NULL)
    table->first = hashp;
  else
    table->last->next = hashp;
  table->last = hashp;

  return hashp;
}

/* Create a new hash table.  */

static struct sec_merge_hash *
sec_merge_init (unsigned int entsize, bool strings)
{
  struct sec_merge_hash *table;

  table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash));
  if (table == NULL)
    return NULL;

  if (! bfd_hash_table_init_n (&table->table, NULL,
			       sizeof (struct sec_merge_hash_entry), 0x2000))
    {
      free (table);
      return NULL;
    }

  table->first = NULL;
  table->last = NULL;
  table->entsize = entsize;
  table->strings = strings;

  table->nbuckets = 0x2000;
  table->key_lens = objalloc_alloc ((struct objalloc *) table->table.memory,
				table->nbuckets * sizeof (table->key_lens[0]));
  memset (table->key_lens, 0, table->nbuckets * sizeof (table->key_lens[0]));
  table->values = objalloc_alloc ((struct objalloc *) table->table.memory,
				table->nbuckets * sizeof (table->values[0]));
  memset (table->values, 0, table->nbuckets * sizeof (table->values[0]));

  return table;
}

/* Append the tuple of input-offset O corresponding
   to hash table ENTRY into SECINFO, such that we later may lookup the
   entry just by O.  */

static bool
append_offsetmap (struct sec_merge_sec_info *secinfo,
		  mapofs_type o,
		  struct sec_merge_hash_entry *entry)
{
  if ((secinfo->noffsetmap & 2047) == 0)
    {
      bfd_size_type amt;
      amt = (secinfo->noffsetmap + 2048);
      secinfo->map_ofs = bfd_realloc (secinfo->map_ofs,
				      amt * sizeof(secinfo->map_ofs[0]));
      if (!secinfo->map_ofs)
	return false;
      secinfo->map = bfd_realloc (secinfo->map, amt * sizeof(secinfo->map[0]));
      if (!secinfo->map)
	return false;
    }
  unsigned int i = secinfo->noffsetmap++;
  MAP_OFS(secinfo, i) = o;
  secinfo->map[i].entry = entry;
  return true;
}

/* Prepare the input-offset-to-entry tables after output offsets are
   determined.  */

static void
prepare_offsetmap (struct sec_merge_sec_info *secinfo)
{
  unsigned int noffsetmap = secinfo->noffsetmap;
  unsigned int i, lbi;
  bfd_size_type l, sz, amt;

  secinfo->fast_state = 1;

  for (i = 0; i < noffsetmap; i++)
    MAP_IDX(secinfo, i) = secinfo->map[i].entry->u.index;

  sz = secinfo->sec->rawsize;
  amt = (sz / OFSDIV + 1) * sizeof (secinfo->ofstolowbound[0]);
  secinfo->ofstolowbound = bfd_zmalloc (amt);
  if (!secinfo->ofstolowbound)
    return;
  for (l = lbi = 0; l < sz; l += OFSDIV)
    {
      /* No need for bounds checking on lbi, as we've added a sentinel that's
	 larger than any offset.  */
      while (MAP_OFS(secinfo, lbi) <= l)
	lbi++;
      //BFD_ASSERT ((l / OFSDIV) <= (i / OFSDIV));
      secinfo->ofstolowbound[l / OFSDIV] = lbi;
    }
  secinfo->fast_state = 2;
}

static bool
sec_merge_emit (bfd *abfd, struct sec_merge_sec_info *secinfo,
		unsigned char *contents)
{
  struct sec_merge_hash_entry *entry = secinfo->first_str;
  asection *sec = secinfo->sec;
  file_ptr offset = sec->output_offset;
  char *pad = NULL;
  bfd_size_type off = 0;
  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_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 = entry->next)
    {
      const char *str;
      bfd_size_type len;

      if (!entry->len)
	continue;
      BFD_ASSERT (entry->alignment);
      len = -off & (entry->alignment - 1);
      if (len != 0)
	{
	  BFD_ASSERT (len <= pad_len);
	  if (contents)
	    {
	      memcpy (contents + offset, pad, len);
	      offset += len;
	    }
	  else if (bfd_write (pad, len, abfd) != len)
	    goto err;
	  off += len;
	}

      str = entry->str;
      len = entry->len;

      if (contents)
	{
	  memcpy (contents + offset, str, len);
	  offset += len;
	}
      else if (bfd_write (str, len, abfd) != len)
	goto err;

      off += len;
    }
  BFD_ASSERT (!entry);

  /* Trailing alignment needed?  */
  off = sec->size - off;
  if (1 && off != 0)
    {
      BFD_ASSERT (off <= pad_len);
      if (contents)
	memcpy (contents + offset, pad, off);
      else if (bfd_write (pad, off, abfd) != off)
	goto err;
    }

  free (pad);
  return true;

 err:
  free (pad);
  return false;
}

/* Register a SEC_MERGE section as a candidate for merging.
   This function is called for all non-dynamic SEC_MERGE input sections.  */

bool
_bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
			void **psecinfo)
{
  struct sec_merge_info *sinfo;
  struct sec_merge_sec_info *secinfo;
  asection *repr;
  unsigned int alignment_power;  /* Octets.  */
  unsigned int align;            /* Octets.  */
  unsigned int opb = bfd_octets_per_byte (abfd, sec);

  if ((abfd->flags & DYNAMIC) != 0
      || (sec->flags & SEC_MERGE) == 0)
    abort ();

  if (sec->size == 0
      || (sec->flags & SEC_EXCLUDE) != 0
      || (sec->flags & SEC_HAS_CONTENTS) == 0
      || 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.  */
      return true;
    }

  if (sec->size > (mapofs_type)-1)
    {
      /* Input offsets must be representable by mapofs_type.  */
      return true;
    }

#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
  alignment_power = sec->alignment_power * opb;
  if (alignment_power >= sizeof (align) * CHAR_BIT)
    return true;

  align = 1u << alignment_power;
  if ((sec->entsize < align
       && ((sec->entsize & (sec->entsize - 1))
	   || !(sec->flags & SEC_STRINGS)))
      || (sec->entsize > align
	  && (sec->entsize & (align - 1))))
    {
      /* Sanity check.  If string character size is smaller than
	 alignment, then we require character size to be a power
	 of 2, otherwise character size must be integer multiple
	 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;
    }

  /* Initialize the descriptor for this input section.  */

  *psecinfo = secinfo = bfd_zalloc (abfd, sizeof (*secinfo));
  if (*psecinfo == NULL)
    goto error_return;

  secinfo->sec = sec;
  secinfo->psecinfo = psecinfo;

  /* Search for a matching output merged section.  */
  for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
    if (sinfo->chain
	&& (repr = sinfo->chain->sec)
	&& ! ((repr->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
	&& repr->entsize == sec->entsize
	&& repr->alignment_power == sec->alignment_power
	&& repr->output_section == sec->output_section)
      break;

  if (sinfo == NULL)
    {
      /* Initialize the information we need to keep track of.  */
      sinfo = (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;
      sinfo->chain = NULL;
      sinfo->last = &sinfo->chain;
      *psinfo = sinfo;
      sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
      if (sinfo->htab == NULL)
	goto error_return;
    }

  *sinfo->last = secinfo;
  sinfo->last = &secinfo->next;

  secinfo->sinfo = sinfo;
  secinfo->reprsec = sinfo->chain->sec;

  return true;

 error_return:
  *psecinfo = NULL;
  return false;
}

/* Record one whole input section (described by SECINFO) into the hash table
   SINFO.  Returns true when section is completely recorded, and false when
   it wasn't recorded but we can continue (e.g. by simply not deduplicating
   this section).  */

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;
  unsigned char *p, *end;
  bfd_vma mask, eltalign;
  unsigned int align;
  bfd_size_type amt;
  bfd_byte *contents;
  void *tmpptr;

  amt = sec->size;
  if (sec->flags & SEC_STRINGS)
    /* Some versions of gcc may emit a string without a zero terminator.
       See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html
       Allocate space for an extra zero.  */
    amt += sec->entsize;
  contents = bfd_malloc (amt);
  if (!contents)
    goto error_return;

  /* Slurp in all section contents (possibly decompressing it).  */
  sec->rawsize = sec->size;
  if (sec->flags & SEC_STRINGS)
    memset (contents + sec->size, 0, sec->entsize);
  if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
    goto error_return;

  /* Now populate the hash table and offset mapping.  */

  /* Walk through the contents, calculate hashes and length of all
     blobs (strings or fixed-size entries) we find and fill the
     hash and offset tables.  */
  align = sec->alignment_power;
  mask = ((bfd_vma) 1 << align) - 1;
  end = contents + sec->size;
  for (p = contents; p < end;)
    {
      unsigned len;
      uint32_t hash = hashit (sinfo->htab, (char*) p, &len);
      unsigned int ofs = p - contents;
      eltalign = ofs;
      eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
      if (!eltalign || eltalign > mask)
	eltalign = mask + 1;
      entry = sec_merge_hash_lookup (sinfo->htab, (char *) p, len, hash,
				     (unsigned) eltalign);
      if (! entry)
	goto error_return;
      if (! append_offsetmap (secinfo, ofs, entry))
	goto error_return;
      p += len;
    }

  /* Add a sentinel element that's conceptually behind all others.  */
  append_offsetmap (secinfo, sec->size, NULL);
  /* But don't count it.  */
  secinfo->noffsetmap--;

  free (contents);
  contents = NULL;

  /* We allocate the ofsmap arrays in blocks of 2048 elements.
     In case we have very many small input files/sections,
     this might waste large amounts of memory, so reallocate these
     arrays here to their true size.  */
  amt = secinfo->noffsetmap + 1;
  tmpptr = bfd_realloc (secinfo->map, amt * sizeof(secinfo->map[0]));
  if (tmpptr)
    secinfo->map = tmpptr;
  tmpptr = bfd_realloc (secinfo->map_ofs, amt * sizeof(secinfo->map_ofs[0]));
  if (tmpptr)
    secinfo->map_ofs = tmpptr;

  /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
	  (unsigned)secinfo->noffsetmap);*/

  return true;

 error_return:
  free (contents);
  contents = NULL;
  return false;
}

/* qsort comparison function.  Won't ever return zero as all entries
   differ, so there is no issue with qsort stability here.  */

static int
strrevcmp (const void *a, const void *b)
{
  struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
  struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
  unsigned int lenA = A->len;
  unsigned int lenB = B->len;
  const unsigned char *s = (const unsigned char *) A->str + lenA - 1;
  const unsigned char *t = (const unsigned char *) B->str + lenB - 1;
  int l = lenA < lenB ? lenA : lenB;

  while (l)
    {
      if (*s != *t)
	return (int) *s - (int) *t;
      s--;
      t--;
      l--;
    }
  return lenA - lenB;
}

/* Like strrevcmp, but for the case where all strings have the same
   alignment > entsize.  */

static int
strrevcmp_align (const void *a, const void *b)
{
  struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
  struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
  unsigned int lenA = A->len;
  unsigned int lenB = B->len;
  const unsigned char *s = (const unsigned char *) A->str + lenA - 1;
  const unsigned char *t = (const unsigned char *) B->str + lenB - 1;
  int l = lenA < lenB ? lenA : lenB;
  int tail_align = (lenA & (A->alignment - 1)) - (lenB & (A->alignment - 1));

  if (tail_align != 0)
    return tail_align;

  while (l)
    {
      if (*s != *t)
	return (int) *s - (int) *t;
      s--;
      t--;
      l--;
    }
  return lenA - lenB;
}

static inline int
is_suffix (const struct sec_merge_hash_entry *A,
	   const struct sec_merge_hash_entry *B)
{
  if (A->len <= B->len)
    /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
       not to be equal by the hash table.  */
    return 0;

  return memcmp (A->str + (A->len - B->len),
		 B->str, B->len) == 0;
}

/* This is a helper function for _bfd_merge_sections.  It attempts to
   merge strings matching suffixes of longer strings.  */
static struct sec_merge_sec_info *
merge_strings (struct sec_merge_info *sinfo)
{
  struct sec_merge_hash_entry **array, **a, *e;
  struct sec_merge_sec_info *secinfo;
  bfd_size_type size, amt;
  unsigned int alignment = 0;

  /* Now sort the strings */
  amt = sinfo->htab->table.count * sizeof (struct sec_merge_hash_entry *);
  array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
  if (array == NULL)
    return NULL;

  for (e = sinfo->htab->first, a = array; e; e = e->next)
    if (e->alignment)
      {
	*a++ = e;
	/* Adjust the length to not include the zero terminator.  */
	e->len -= sinfo->htab->entsize;
	if (alignment != e->alignment)
	  {
	    if (alignment == 0)
	      alignment = e->alignment;
	    else
	      alignment = (unsigned) -1;
	  }
      }

  size_t asize = a - array;
  if (asize != 0)
    {
      qsort (array, asize,
	     sizeof (struct sec_merge_hash_entry *),
	     (alignment != (unsigned) -1 && alignment > sinfo->htab->entsize
	      ? strrevcmp_align : strrevcmp));

      /* Loop over the sorted array and merge suffixes */
      e = *--a;
      e->len += sinfo->htab->entsize;
      while (--a >= array)
	{
	  struct sec_merge_hash_entry *cmp = *a;

	  cmp->len += sinfo->htab->entsize;
	  if (e->alignment >= cmp->alignment
	      && !((e->len - cmp->len) & (cmp->alignment - 1))
	      && is_suffix (e, cmp))
	    {
	      cmp->u.suffix = e;
	      cmp->alignment = 0;
	    }
	  else
	    e = cmp;
	}
    }

  free (array);

  /* Now assign positions to the strings we want to keep.  */
  size = 0;
  secinfo = sinfo->chain;
  for (e = sinfo->htab->first; e; e = e->next)
    {
      if (e->alignment)
	{
	  size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
	  e->u.index = size;
	  size += e->len;
	}
    }
  secinfo->sec->size = size;

  /* And now adjust the rest, removing them from the chain (but not hashtable)
     at the same time.  */
  for (a = &sinfo->htab->first, e = *a; e; e = e->next)
    if (e->alignment)
      a = &e->next;
    else
      {
	*a = e->next;
	if (e->len)
	  {
	    e->alignment = e->u.suffix->alignment;
	    e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
	  }
      }

  BFD_ASSERT (!secinfo->first_str);
  secinfo->first_str = sinfo->htab->first;

  return secinfo;
}

/* This function is called once after all SEC_MERGE sections are registered
   with _bfd_merge_section.  */

bool
_bfd_merge_sections (bfd *abfd,
		     struct bfd_link_info *info ATTRIBUTE_UNUSED,
		     void *xsinfo,
		     void (*remove_hook) (bfd *, asection *))
{
  struct sec_merge_info *sinfo;

  for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
    {
      struct sec_merge_sec_info *secinfo;
      bfd_size_type align;  /* Bytes.  */

      if (! sinfo->chain)
	continue;

      /* Record the sections into the hash table.  */
      align = 1;
      for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
	if (secinfo->sec->flags & SEC_EXCLUDE
	    || !record_section (sinfo, secinfo))
	  {
	    *secinfo->psecinfo = NULL;
	    if (remove_hook)
	      (*remove_hook) (abfd, secinfo->sec);
	  }
	else 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 / opb) & (align - 1)) != 0)
	      align = 0;
	  }

      if (sinfo->htab->first == NULL)
	continue;

      if (sinfo->htab->strings)
	{
	  secinfo = merge_strings (sinfo);
	  if (!secinfo)
	    return false;
	}
      else
	{
	  struct sec_merge_hash_entry *e = sinfo->htab->first;
	  bfd_size_type size = 0;  /* Octets.  */

	  /* Things are much simpler for non-strings.
	     Just assign them slots in the section.  */
	  secinfo = sinfo->chain;
	  BFD_ASSERT (!secinfo->first_str);
	  secinfo->first_str = e;
	  for (e = sinfo->htab->first; e; e = e->next)
	    {
	      if (e->alignment)
		{
		  size = (size + e->alignment - 1)
			 & ~((bfd_vma) e->alignment - 1);
		  e->u.index = size;
		  size += e->len;
		}
	    }
	  secinfo->sec->size = size;
	}

      /* If the input sections were padded according to their alignments,
	 then pad the output too.  */
      if (align)
	secinfo->sec->size = (secinfo->sec->size + align - 1) & -align;

      /* Finally remove all input sections which have not made it into
	 the hash table at all.  */
      for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
	if (secinfo->first_str == NULL
	    && secinfo->sec->sec_info_type == SEC_INFO_TYPE_MERGE)
	  secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP;
    }

  return true;
}

/* Write out the merged section.  */

bool
_bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
{
  struct sec_merge_sec_info *secinfo;
  file_ptr pos;
  unsigned char *contents;
  Elf_Internal_Shdr *hdr;

  secinfo = (struct sec_merge_sec_info *) psecinfo;

  if (!secinfo)
    return false;

  if (secinfo->first_str == NULL)
    return true;

  /* FIXME: octets_per_byte.  */
  hdr = &elf_section_data (sec->output_section)->this_hdr;
  if (hdr->sh_offset == (file_ptr) -1)
    {
      /* We must compress this section.  Write output to the
	 buffer.  */
      contents = hdr->contents;
      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;
    }

  BFD_ASSERT (sec == secinfo->sec);
  BFD_ASSERT (secinfo == secinfo->sinfo->chain);
  if (! sec_merge_emit (output_bfd, secinfo, contents))
    return false;

  return true;
}

/* Adjust an address in the SEC_MERGE section.  Given OFFSET within
   *PSEC, this returns the new offset in the adjusted SEC_MERGE
   section and writes the new section back into *PSEC.  */

bfd_vma
_bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
			    void *psecinfo, bfd_vma offset)
{
  struct sec_merge_sec_info *secinfo;
  asection *sec = *psec;

  secinfo = (struct sec_merge_sec_info *) psecinfo;

  if (!secinfo)
    return offset;

  if (offset >= sec->rawsize)
    {
      if (offset > sec->rawsize)
	_bfd_error_handler
	  /* xgettext:c-format */
	  (_("%pB: access beyond end of merged section (%" PRId64 ")"),
	   sec->owner, (int64_t) offset);
      return secinfo->first_str ? sec->size : 0;
    }

  if (secinfo->fast_state != 2)
    {
      if (!secinfo->fast_state)
	prepare_offsetmap (secinfo);
      if (secinfo->fast_state != 2)
	return offset;
    }

  long lb = secinfo->ofstolowbound[offset / OFSDIV];
  *psec = secinfo->reprsec;

  /* No need for bounds checking on lb, as we've added a sentinel that's
     larger than any offset.  */
  while (MAP_OFS(secinfo, lb) <= offset)
    lb++;
  lb--;

  /*printf ("YYY (%s:%s):%u -> (%s):%u\n",
	  sec->owner->filename, sec->name, (unsigned)offset,
	  (*psec)->name, (unsigned)lb);*/
  return MAP_IDX(secinfo, lb) + offset - MAP_OFS(secinfo, lb);
}

/* Tidy up when done.  */

void
_bfd_merge_sections_free (void *xsinfo)
{
  struct sec_merge_info *sinfo;

  for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
    {
      struct sec_merge_sec_info *secinfo;
      for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
	{
	  free (secinfo->ofstolowbound);
	  free (secinfo->map);
	  free (secinfo->map_ofs);
	}
      bfd_hash_table_free (&sinfo->htab->table);
      free (sinfo->htab);
    }
}
