Home | History | Annotate | Download | only in bfd
      1 /* SEC_MERGE support.
      2    Copyright (C) 2001-2014 Free Software Foundation, Inc.
      3    Written by Jakub Jelinek <jakub (at) redhat.com>.
      4 
      5    This file is part of BFD, the Binary File Descriptor library.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 
     23 /* This file contains support for merging duplicate entities within sections,
     24    as used in ELF SHF_MERGE.  */
     25 
     26 #include "sysdep.h"
     27 #include "bfd.h"
     28 #include "libbfd.h"
     29 #include "hashtab.h"
     30 #include "libiberty.h"
     31 
     32 struct sec_merge_sec_info;
     33 
     34 /* An entry in the section merge hash table.  */
     35 
     36 struct sec_merge_hash_entry
     37 {
     38   struct bfd_hash_entry root;
     39   /* Length of this entry.  This includes the zero terminator.  */
     40   unsigned int len;
     41   /* Start of this string needs to be aligned to
     42      alignment octets (not 1 << align).  */
     43   unsigned int alignment;
     44   union
     45   {
     46     /* Index within the merged section.  */
     47     bfd_size_type index;
     48     /* Entry this is a suffix of (if alignment is 0).  */
     49     struct sec_merge_hash_entry *suffix;
     50   } u;
     51   /* Which section is it in.  */
     52   struct sec_merge_sec_info *secinfo;
     53   /* Next entity in the hash table.  */
     54   struct sec_merge_hash_entry *next;
     55 };
     56 
     57 /* The section merge hash table.  */
     58 
     59 struct sec_merge_hash
     60 {
     61   struct bfd_hash_table table;
     62   /* Next available index.  */
     63   bfd_size_type size;
     64   /* First entity in the SEC_MERGE sections of this type.  */
     65   struct sec_merge_hash_entry *first;
     66   /* Last entity in the SEC_MERGE sections of this type.  */
     67   struct sec_merge_hash_entry *last;
     68   /* Entity size.  */
     69   unsigned int entsize;
     70   /* Are entries fixed size or zero terminated strings?  */
     71   bfd_boolean strings;
     72 };
     73 
     74 struct sec_merge_info
     75 {
     76   /* Chain of sec_merge_infos.  */
     77   struct sec_merge_info *next;
     78   /* Chain of sec_merge_sec_infos.  */
     79   struct sec_merge_sec_info *chain;
     80   /* A hash table used to hold section content.  */
     81   struct sec_merge_hash *htab;
     82 };
     83 
     84 struct sec_merge_sec_info
     85 {
     86   /* Chain of sec_merge_sec_infos.  */
     87   struct sec_merge_sec_info *next;
     88   /* The corresponding section.  */
     89   asection *sec;
     90   /* Pointer to merge_info pointing to us.  */
     91   void **psecinfo;
     92   /* A hash table used to hold section content.  */
     93   struct sec_merge_hash *htab;
     94   /* First string in this section.  */
     95   struct sec_merge_hash_entry *first_str;
     96   /* Original section content.  */
     97   unsigned char contents[1];
     98 };
     99 
    100 
    101 /* Routine to create an entry in a section merge hashtab.  */
    102 
    103 static struct bfd_hash_entry *
    104 sec_merge_hash_newfunc (struct bfd_hash_entry *entry,
    105 			struct bfd_hash_table *table, const char *string)
    106 {
    107   /* Allocate the structure if it has not already been allocated by a
    108      subclass.  */
    109   if (entry == NULL)
    110     entry = (struct bfd_hash_entry *)
    111         bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry));
    112   if (entry == NULL)
    113     return NULL;
    114 
    115   /* Call the allocation method of the superclass.  */
    116   entry = bfd_hash_newfunc (entry, table, string);
    117 
    118   if (entry != NULL)
    119     {
    120       /* Initialize the local fields.  */
    121       struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry;
    122 
    123       ret->u.suffix = NULL;
    124       ret->alignment = 0;
    125       ret->secinfo = NULL;
    126       ret->next = NULL;
    127     }
    128 
    129   return entry;
    130 }
    131 
    132 /* Look up an entry in a section merge hash table.  */
    133 
    134 static struct sec_merge_hash_entry *
    135 sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
    136 		       unsigned int alignment, bfd_boolean create)
    137 {
    138   const unsigned char *s;
    139   unsigned long hash;
    140   unsigned int c;
    141   struct sec_merge_hash_entry *hashp;
    142   unsigned int len, i;
    143   unsigned int _index;
    144 
    145   hash = 0;
    146   len = 0;
    147   s = (const unsigned char *) string;
    148   if (table->strings)
    149     {
    150       if (table->entsize == 1)
    151 	{
    152 	  while ((c = *s++) != '\0')
    153 	    {
    154 	      hash += c + (c << 17);
    155 	      hash ^= hash >> 2;
    156 	      ++len;
    157 	    }
    158 	  hash += len + (len << 17);
    159 	}
    160       else
    161 	{
    162 	  for (;;)
    163 	    {
    164 	      for (i = 0; i < table->entsize; ++i)
    165 		if (s[i] != '\0')
    166 		  break;
    167 	      if (i == table->entsize)
    168 		break;
    169 	      for (i = 0; i < table->entsize; ++i)
    170 		{
    171 		  c = *s++;
    172 		  hash += c + (c << 17);
    173 		  hash ^= hash >> 2;
    174 		}
    175 	      ++len;
    176 	    }
    177 	  hash += len + (len << 17);
    178 	  len *= table->entsize;
    179 	}
    180       hash ^= hash >> 2;
    181       len += table->entsize;
    182     }
    183   else
    184     {
    185       for (i = 0; i < table->entsize; ++i)
    186 	{
    187 	  c = *s++;
    188 	  hash += c + (c << 17);
    189 	  hash ^= hash >> 2;
    190 	}
    191       len = table->entsize;
    192     }
    193 
    194   _index = hash % table->table.size;
    195   for (hashp = (struct sec_merge_hash_entry *) table->table.table[_index];
    196        hashp != NULL;
    197        hashp = (struct sec_merge_hash_entry *) hashp->root.next)
    198     {
    199       if (hashp->root.hash == hash
    200 	  && len == hashp->len
    201 	  && memcmp (hashp->root.string, string, len) == 0)
    202 	{
    203 	  /* If the string we found does not have at least the required
    204 	     alignment, we need to insert another copy.  */
    205 	  if (hashp->alignment < alignment)
    206 	    {
    207 	      if (create)
    208 		{
    209 		  /*  Mark the less aligned copy as deleted.  */
    210 		  hashp->len = 0;
    211 		  hashp->alignment = 0;
    212 		}
    213 	      break;
    214 	    }
    215 	  return hashp;
    216 	}
    217     }
    218 
    219   if (! create)
    220     return NULL;
    221 
    222   hashp = ((struct sec_merge_hash_entry *)
    223 	   bfd_hash_insert (&table->table, string, hash));
    224   if (hashp == NULL)
    225     return NULL;
    226   hashp->len = len;
    227   hashp->alignment = alignment;
    228   return hashp;
    229 }
    230 
    231 /* Create a new hash table.  */
    232 
    233 static struct sec_merge_hash *
    234 sec_merge_init (unsigned int entsize, bfd_boolean strings)
    235 {
    236   struct sec_merge_hash *table;
    237 
    238   table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash));
    239   if (table == NULL)
    240     return NULL;
    241 
    242   if (! bfd_hash_table_init_n (&table->table, sec_merge_hash_newfunc,
    243 			       sizeof (struct sec_merge_hash_entry), 16699))
    244     {
    245       free (table);
    246       return NULL;
    247     }
    248 
    249   table->size = 0;
    250   table->first = NULL;
    251   table->last = NULL;
    252   table->entsize = entsize;
    253   table->strings = strings;
    254 
    255   return table;
    256 }
    257 
    258 /* Get the index of an entity in a hash table, adding it if it is not
    259    already present.  */
    260 
    261 static struct sec_merge_hash_entry *
    262 sec_merge_add (struct sec_merge_hash *tab, const char *str,
    263 	       unsigned int alignment, struct sec_merge_sec_info *secinfo)
    264 {
    265   struct sec_merge_hash_entry *entry;
    266 
    267   entry = sec_merge_hash_lookup (tab, str, alignment, TRUE);
    268   if (entry == NULL)
    269     return NULL;
    270 
    271   if (entry->secinfo == NULL)
    272     {
    273       tab->size++;
    274       entry->secinfo = secinfo;
    275       if (tab->first == NULL)
    276 	tab->first = entry;
    277       else
    278 	tab->last->next = entry;
    279       tab->last = entry;
    280     }
    281 
    282   return entry;
    283 }
    284 
    285 static bfd_boolean
    286 sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
    287 {
    288   struct sec_merge_sec_info *secinfo = entry->secinfo;
    289   asection *sec = secinfo->sec;
    290   char *pad = NULL;
    291   bfd_size_type off = 0;
    292   int alignment_power = sec->output_section->alignment_power;
    293 
    294   if (alignment_power)
    295     {
    296       pad = (char *) bfd_zmalloc ((bfd_size_type) 1 << alignment_power);
    297       if (pad == NULL)
    298 	return FALSE;
    299     }
    300 
    301   for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
    302     {
    303       const char *str;
    304       bfd_size_type len;
    305 
    306       len = -off & (entry->alignment - 1);
    307       if (len != 0)
    308 	{
    309 	  if (bfd_bwrite (pad, len, abfd) != len)
    310 	    goto err;
    311 	  off += len;
    312 	}
    313 
    314       str = entry->root.string;
    315       len = entry->len;
    316 
    317       if (bfd_bwrite (str, len, abfd) != len)
    318 	goto err;
    319 
    320       off += len;
    321     }
    322 
    323   /* Trailing alignment needed?  */
    324   off = sec->size - off;
    325   if (off != 0
    326       && bfd_bwrite (pad, off, abfd) != off)
    327     goto err;
    328 
    329   if (pad != NULL)
    330     free (pad);
    331   return TRUE;
    332 
    333  err:
    334   if (pad != NULL)
    335     free (pad);
    336   return FALSE;
    337 }
    338 
    339 /* Register a SEC_MERGE section as a candidate for merging.
    340    This function is called for all non-dynamic SEC_MERGE input sections.  */
    341 
    342 bfd_boolean
    343 _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
    344 			void **psecinfo)
    345 {
    346   struct sec_merge_info *sinfo;
    347   struct sec_merge_sec_info *secinfo;
    348   unsigned int align;
    349   bfd_size_type amt;
    350   bfd_byte *contents;
    351 
    352   if ((abfd->flags & DYNAMIC) != 0
    353       || (sec->flags & SEC_MERGE) == 0)
    354     abort ();
    355 
    356   if (sec->size == 0
    357       || (sec->flags & SEC_EXCLUDE) != 0
    358       || sec->entsize == 0)
    359     return TRUE;
    360 
    361   if ((sec->flags & SEC_RELOC) != 0)
    362     {
    363       /* We aren't prepared to handle relocations in merged sections.  */
    364       return TRUE;
    365     }
    366 
    367   align = sec->alignment_power;
    368   if ((sec->entsize < (unsigned) 1 << align
    369        && ((sec->entsize & (sec->entsize - 1))
    370 	   || !(sec->flags & SEC_STRINGS)))
    371       || (sec->entsize > (unsigned) 1 << align
    372 	  && (sec->entsize & (((unsigned) 1 << align) - 1))))
    373     {
    374       /* Sanity check.  If string character size is smaller than
    375 	 alignment, then we require character size to be a power
    376 	 of 2, otherwise character size must be integer multiple
    377 	 of alignment.  For non-string constants, alignment must
    378 	 be smaller than or equal to entity size and entity size
    379 	 must be integer multiple of alignment.  */
    380       return TRUE;
    381     }
    382 
    383   for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
    384     if ((secinfo = sinfo->chain)
    385 	&& ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
    386 	&& secinfo->sec->entsize == sec->entsize
    387 	&& secinfo->sec->alignment_power == sec->alignment_power
    388 	&& secinfo->sec->output_section == sec->output_section)
    389       break;
    390 
    391   if (sinfo == NULL)
    392     {
    393       /* Initialize the information we need to keep track of.  */
    394       sinfo = (struct sec_merge_info *)
    395           bfd_alloc (abfd, sizeof (struct sec_merge_info));
    396       if (sinfo == NULL)
    397 	goto error_return;
    398       sinfo->next = (struct sec_merge_info *) *psinfo;
    399       sinfo->chain = NULL;
    400       *psinfo = sinfo;
    401       sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
    402       if (sinfo->htab == NULL)
    403 	goto error_return;
    404     }
    405 
    406   /* Read the section from abfd.  */
    407 
    408   amt = sizeof (struct sec_merge_sec_info) - 1 + sec->size;
    409   if (sec->flags & SEC_STRINGS)
    410     /* Some versions of gcc may emit a string without a zero terminator.
    411        See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html
    412        Allocate space for an extra zero.  */
    413     amt += sec->entsize;
    414   *psecinfo = bfd_alloc (abfd, amt);
    415   if (*psecinfo == NULL)
    416     goto error_return;
    417 
    418   secinfo = (struct sec_merge_sec_info *) *psecinfo;
    419   if (sinfo->chain)
    420     {
    421       secinfo->next = sinfo->chain->next;
    422       sinfo->chain->next = secinfo;
    423     }
    424   else
    425     secinfo->next = secinfo;
    426   sinfo->chain = secinfo;
    427   secinfo->sec = sec;
    428   secinfo->psecinfo = psecinfo;
    429   secinfo->htab = sinfo->htab;
    430   secinfo->first_str = NULL;
    431 
    432   sec->rawsize = sec->size;
    433   if (sec->flags & SEC_STRINGS)
    434     memset (secinfo->contents + sec->size, 0, sec->entsize);
    435   contents = secinfo->contents;
    436   if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
    437     goto error_return;
    438 
    439   return TRUE;
    440 
    441  error_return:
    442   *psecinfo = NULL;
    443   return FALSE;
    444 }
    445 
    446 /* Record one section into the hash table.  */
    447 static bfd_boolean
    448 record_section (struct sec_merge_info *sinfo,
    449 		struct sec_merge_sec_info *secinfo)
    450 {
    451   asection *sec = secinfo->sec;
    452   struct sec_merge_hash_entry *entry;
    453   bfd_boolean nul;
    454   unsigned char *p, *end;
    455   bfd_vma mask, eltalign;
    456   unsigned int align, i;
    457 
    458   align = sec->alignment_power;
    459   end = secinfo->contents + sec->size;
    460   nul = FALSE;
    461   mask = ((bfd_vma) 1 << align) - 1;
    462   if (sec->flags & SEC_STRINGS)
    463     {
    464       for (p = secinfo->contents; p < end; )
    465 	{
    466 	  eltalign = p - secinfo->contents;
    467 	  eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
    468 	  if (!eltalign || eltalign > mask)
    469 	    eltalign = mask + 1;
    470 	  entry = sec_merge_add (sinfo->htab, (char *) p, (unsigned) eltalign,
    471 				 secinfo);
    472 	  if (! entry)
    473 	    goto error_return;
    474 	  p += entry->len;
    475 	  if (sec->entsize == 1)
    476 	    {
    477 	      while (p < end && *p == 0)
    478 		{
    479 		  if (!nul && !((p - secinfo->contents) & mask))
    480 		    {
    481 		      nul = TRUE;
    482 		      entry = sec_merge_add (sinfo->htab, "",
    483 					     (unsigned) mask + 1, secinfo);
    484 		      if (! entry)
    485 			goto error_return;
    486 		    }
    487 		  p++;
    488 		}
    489 	    }
    490 	  else
    491 	    {
    492 	      while (p < end)
    493 		{
    494 		  for (i = 0; i < sec->entsize; i++)
    495 		    if (p[i] != '\0')
    496 		      break;
    497 		  if (i != sec->entsize)
    498 		    break;
    499 		  if (!nul && !((p - secinfo->contents) & mask))
    500 		    {
    501 		      nul = TRUE;
    502 		      entry = sec_merge_add (sinfo->htab, (char *) p,
    503 					     (unsigned) mask + 1, secinfo);
    504 		      if (! entry)
    505 			goto error_return;
    506 		    }
    507 		  p += sec->entsize;
    508 		}
    509 	    }
    510 	}
    511     }
    512   else
    513     {
    514       for (p = secinfo->contents; p < end; p += sec->entsize)
    515 	{
    516 	  entry = sec_merge_add (sinfo->htab, (char *) p, 1, secinfo);
    517 	  if (! entry)
    518 	    goto error_return;
    519 	}
    520     }
    521 
    522   return TRUE;
    523 
    524 error_return:
    525   for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
    526     *secinfo->psecinfo = NULL;
    527   return FALSE;
    528 }
    529 
    530 static int
    531 strrevcmp (const void *a, const void *b)
    532 {
    533   struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
    534   struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
    535   unsigned int lenA = A->len;
    536   unsigned int lenB = B->len;
    537   const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1;
    538   const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1;
    539   int l = lenA < lenB ? lenA : lenB;
    540 
    541   while (l)
    542     {
    543       if (*s != *t)
    544 	return (int) *s - (int) *t;
    545       s--;
    546       t--;
    547       l--;
    548     }
    549   return lenA - lenB;
    550 }
    551 
    552 /* Like strrevcmp, but for the case where all strings have the same
    553    alignment > entsize.  */
    554 
    555 static int
    556 strrevcmp_align (const void *a, const void *b)
    557 {
    558   struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
    559   struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
    560   unsigned int lenA = A->len;
    561   unsigned int lenB = B->len;
    562   const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1;
    563   const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1;
    564   int l = lenA < lenB ? lenA : lenB;
    565   int tail_align = (lenA & (A->alignment - 1)) - (lenB & (A->alignment - 1));
    566 
    567   if (tail_align != 0)
    568     return tail_align;
    569 
    570   while (l)
    571     {
    572       if (*s != *t)
    573 	return (int) *s - (int) *t;
    574       s--;
    575       t--;
    576       l--;
    577     }
    578   return lenA - lenB;
    579 }
    580 
    581 static inline int
    582 is_suffix (const struct sec_merge_hash_entry *A,
    583 	   const struct sec_merge_hash_entry *B)
    584 {
    585   if (A->len <= B->len)
    586     /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
    587        not to be equal by the hash table.  */
    588     return 0;
    589 
    590   return memcmp (A->root.string + (A->len - B->len),
    591 		 B->root.string, B->len) == 0;
    592 }
    593 
    594 /* This is a helper function for _bfd_merge_sections.  It attempts to
    595    merge strings matching suffixes of longer strings.  */
    596 static void
    597 merge_strings (struct sec_merge_info *sinfo)
    598 {
    599   struct sec_merge_hash_entry **array, **a, *e;
    600   struct sec_merge_sec_info *secinfo;
    601   bfd_size_type size, amt;
    602   unsigned int alignment = 0;
    603 
    604   /* Now sort the strings */
    605   amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
    606   array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
    607   if (array == NULL)
    608     goto alloc_failure;
    609 
    610   for (e = sinfo->htab->first, a = array; e; e = e->next)
    611     if (e->alignment)
    612       {
    613 	*a++ = e;
    614 	/* Adjust the length to not include the zero terminator.  */
    615 	e->len -= sinfo->htab->entsize;
    616 	if (alignment != e->alignment)
    617 	  {
    618 	    if (alignment == 0)
    619 	      alignment = e->alignment;
    620 	    else
    621 	      alignment = (unsigned) -1;
    622 	  }
    623       }
    624 
    625   sinfo->htab->size = a - array;
    626   if (sinfo->htab->size != 0)
    627     {
    628       qsort (array, (size_t) sinfo->htab->size,
    629 	     sizeof (struct sec_merge_hash_entry *),
    630 	     (alignment != (unsigned) -1 && alignment > sinfo->htab->entsize
    631 	      ? strrevcmp_align : strrevcmp));
    632 
    633       /* Loop over the sorted array and merge suffixes */
    634       e = *--a;
    635       e->len += sinfo->htab->entsize;
    636       while (--a >= array)
    637 	{
    638 	  struct sec_merge_hash_entry *cmp = *a;
    639 
    640 	  cmp->len += sinfo->htab->entsize;
    641 	  if (e->alignment >= cmp->alignment
    642 	      && !((e->len - cmp->len) & (cmp->alignment - 1))
    643 	      && is_suffix (e, cmp))
    644 	    {
    645 	      cmp->u.suffix = e;
    646 	      cmp->alignment = 0;
    647 	    }
    648 	  else
    649 	    e = cmp;
    650 	}
    651     }
    652 
    653 alloc_failure:
    654   if (array)
    655     free (array);
    656 
    657   /* Now assign positions to the strings we want to keep.  */
    658   size = 0;
    659   secinfo = sinfo->htab->first->secinfo;
    660   for (e = sinfo->htab->first; e; e = e->next)
    661     {
    662       if (e->secinfo != secinfo)
    663 	{
    664 	  secinfo->sec->size = size;
    665 	  secinfo = e->secinfo;
    666 	}
    667       if (e->alignment)
    668 	{
    669 	  if (e->secinfo->first_str == NULL)
    670 	    {
    671 	      e->secinfo->first_str = e;
    672 	      size = 0;
    673 	    }
    674 	  size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
    675 	  e->u.index = size;
    676 	  size += e->len;
    677 	}
    678     }
    679   secinfo->sec->size = size;
    680   if (secinfo->sec->alignment_power != 0)
    681     {
    682       bfd_size_type align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
    683       secinfo->sec->size = (secinfo->sec->size + align - 1) & -align;
    684     }
    685 
    686   /* And now adjust the rest, removing them from the chain (but not hashtable)
    687      at the same time.  */
    688   for (a = &sinfo->htab->first, e = *a; e; e = e->next)
    689     if (e->alignment)
    690       a = &e->next;
    691     else
    692       {
    693 	*a = e->next;
    694 	if (e->len)
    695 	  {
    696 	    e->secinfo = e->u.suffix->secinfo;
    697 	    e->alignment = e->u.suffix->alignment;
    698 	    e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
    699 	  }
    700       }
    701 }
    702 
    703 /* This function is called once after all SEC_MERGE sections are registered
    704    with _bfd_merge_section.  */
    705 
    706 bfd_boolean
    707 _bfd_merge_sections (bfd *abfd,
    708 		     struct bfd_link_info *info ATTRIBUTE_UNUSED,
    709 		     void *xsinfo,
    710 		     void (*remove_hook) (bfd *, asection *))
    711 {
    712   struct sec_merge_info *sinfo;
    713 
    714   for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
    715     {
    716       struct sec_merge_sec_info * secinfo;
    717 
    718       if (! sinfo->chain)
    719 	continue;
    720 
    721       /* Move sinfo->chain to head of the chain, terminate it.  */
    722       secinfo = sinfo->chain;
    723       sinfo->chain = secinfo->next;
    724       secinfo->next = NULL;
    725 
    726       /* Record the sections into the hash table.  */
    727       for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
    728 	if (secinfo->sec->flags & SEC_EXCLUDE)
    729 	  {
    730 	    *secinfo->psecinfo = NULL;
    731 	    if (remove_hook)
    732 	      (*remove_hook) (abfd, secinfo->sec);
    733 	  }
    734 	else if (! record_section (sinfo, secinfo))
    735 	  break;
    736 
    737       if (secinfo)
    738 	continue;
    739 
    740       if (sinfo->htab->first == NULL)
    741 	continue;
    742 
    743       if (sinfo->htab->strings)
    744 	merge_strings (sinfo);
    745       else
    746 	{
    747 	  struct sec_merge_hash_entry *e;
    748 	  bfd_size_type size = 0;
    749 
    750 	  /* Things are much simpler for non-strings.
    751 	     Just assign them slots in the section.  */
    752 	  secinfo = NULL;
    753 	  for (e = sinfo->htab->first; e; e = e->next)
    754 	    {
    755 	      if (e->secinfo->first_str == NULL)
    756 		{
    757 		  if (secinfo)
    758 		    secinfo->sec->size = size;
    759 		  e->secinfo->first_str = e;
    760 		  size = 0;
    761 		}
    762 	      size = (size + e->alignment - 1)
    763 		     & ~((bfd_vma) e->alignment - 1);
    764 	      e->u.index = size;
    765 	      size += e->len;
    766 	      secinfo = e->secinfo;
    767 	    }
    768 	  secinfo->sec->size = size;
    769 	}
    770 
    771 	/* Finally remove all input sections which have not made it into
    772 	   the hash table at all.  */
    773 	for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
    774 	  if (secinfo->first_str == NULL)
    775 	    secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP;
    776     }
    777 
    778   return TRUE;
    779 }
    780 
    781 /* Write out the merged section.  */
    782 
    783 bfd_boolean
    784 _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
    785 {
    786   struct sec_merge_sec_info *secinfo;
    787   file_ptr pos;
    788 
    789   secinfo = (struct sec_merge_sec_info *) psecinfo;
    790 
    791   if (!secinfo)
    792     return FALSE;
    793 
    794   if (secinfo->first_str == NULL)
    795     return TRUE;
    796 
    797   /* FIXME: octets_per_byte.  */
    798   pos = sec->output_section->filepos + sec->output_offset;
    799   if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
    800     return FALSE;
    801 
    802   if (! sec_merge_emit (output_bfd, secinfo->first_str))
    803     return FALSE;
    804 
    805   return TRUE;
    806 }
    807 
    808 /* Adjust an address in the SEC_MERGE section.  Given OFFSET within
    809    *PSEC, this returns the new offset in the adjusted SEC_MERGE
    810    section and writes the new section back into *PSEC.  */
    811 
    812 bfd_vma
    813 _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
    814 			    void *psecinfo, bfd_vma offset)
    815 {
    816   struct sec_merge_sec_info *secinfo;
    817   struct sec_merge_hash_entry *entry;
    818   unsigned char *p;
    819   asection *sec = *psec;
    820 
    821   secinfo = (struct sec_merge_sec_info *) psecinfo;
    822 
    823   if (!secinfo)
    824     return offset;
    825 
    826   if (offset >= sec->rawsize)
    827     {
    828       if (offset > sec->rawsize)
    829 	{
    830 	  (*_bfd_error_handler)
    831 	    (_("%s: access beyond end of merged section (%ld)"),
    832 	     bfd_get_filename (sec->owner), (long) offset);
    833 	}
    834       return secinfo->first_str ? sec->size : 0;
    835     }
    836 
    837   if (secinfo->htab->strings)
    838     {
    839       if (sec->entsize == 1)
    840 	{
    841 	  p = secinfo->contents + offset - 1;
    842 	  while (p >= secinfo->contents && *p)
    843 	    --p;
    844 	  ++p;
    845 	}
    846       else
    847 	{
    848 	  p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
    849 	  p -= sec->entsize;
    850 	  while (p >= secinfo->contents)
    851 	    {
    852 	      unsigned int i;
    853 
    854 	      for (i = 0; i < sec->entsize; ++i)
    855 		if (p[i] != '\0')
    856 		  break;
    857 	      if (i == sec->entsize)
    858 		break;
    859 	      p -= sec->entsize;
    860 	    }
    861 	  p += sec->entsize;
    862 	}
    863     }
    864   else
    865     {
    866       p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
    867     }
    868   entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, 0, FALSE);
    869   if (!entry)
    870     {
    871       if (! secinfo->htab->strings)
    872 	abort ();
    873       /* This should only happen if somebody points into the padding
    874 	 after a NUL character but before next entity.  */
    875       if (*p)
    876 	abort ();
    877       if (! secinfo->htab->first)
    878 	abort ();
    879       entry = secinfo->htab->first;
    880       p = (secinfo->contents + (offset / sec->entsize + 1) * sec->entsize
    881 	   - entry->len);
    882     }
    883 
    884   *psec = entry->secinfo->sec;
    885   return entry->u.index + (secinfo->contents + offset - p);
    886 }
    887 
    888 /* Tidy up when done.  */
    889 
    890 void
    891 _bfd_merge_sections_free (void *xsinfo)
    892 {
    893   struct sec_merge_info *sinfo;
    894 
    895   for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
    896     {
    897       bfd_hash_table_free (&sinfo->htab->table);
    898       free (sinfo->htab);
    899     }
    900 }
    901