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