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