* merge.c (_bfd_merged_section_offset): Avoid accessing byte before
[platform/upstream/binutils.git] / bfd / merge.c
1 /* SEC_MERGE support.
2    Copyright 2001, 2002 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 #include "libiberty.h"
29
30 struct sec_merge_sec_info;
31
32 /* An entry in the section merge hash table.  */
33
34 struct sec_merge_hash_entry
35 {
36   struct bfd_hash_entry root;
37   /* Length of this entry.  */
38   unsigned int len;
39   /* Start of this string needs to be aligned to
40      alignment octets (not 1 << align).  */
41   unsigned int alignment;
42   union
43   {
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   bfd_size_type amt = sizeof (struct sec_merge_hash);
266
267   table = (struct sec_merge_hash *) bfd_malloc (amt);
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 ((bfd_size_type) 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_bwrite ((PTR) pad, (bfd_size_type) len, abfd) != len)
340             break;
341           off += len;
342         }
343
344       str = entry->root.string;
345       len = entry->len;
346
347       if (bfd_bwrite ((PTR) str, (bfd_size_type) 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   bfd_size_type amt;
373
374   if (sec->_raw_size == 0
375       || (sec->flags & SEC_EXCLUDE)
376       || (sec->flags & SEC_MERGE) == 0
377       || sec->entsize == 0)
378     return true;
379
380   if ((sec->flags & SEC_RELOC) != 0)
381     {
382       /* We aren't prepared to handle relocations in merged sections.  */
383       return true;
384     }
385
386   if (sec->output_section != NULL
387       && bfd_is_abs_section (sec->output_section))
388     {
389       /* The section is being discarded from the link, so we should
390          just ignore it.  */
391       return true;
392     }
393
394   align = bfd_get_section_alignment (sec->owner, sec);
395   if ((sec->entsize < (unsigned int)(1 << align)
396        && ((sec->entsize & (sec->entsize - 1))
397            || !(sec->flags & SEC_STRINGS)))
398       || (sec->entsize > (unsigned int)(1 << align)
399           && (sec->entsize & ((1 << align) - 1))))
400     {
401       /* Sanity check.  If string character size is smaller than
402          alignment, then we require character size to be a power
403          of 2, otherwise character size must be integer multiple
404          of alignment.  For non-string constants, alignment must
405          be smaller than or equal to entity size and entity size
406          must be integer multiple of alignment.  */
407       return true;
408     }
409
410   for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
411     if ((secinfo = sinfo->chain)
412         && ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
413         && secinfo->sec->entsize == sec->entsize
414         && ! strcmp (secinfo->sec->name, sec->name))
415       break;
416
417   if (sinfo == NULL)
418     {
419       /* Initialize the information we need to keep track of.  */
420       sinfo = (struct sec_merge_info *)
421               bfd_alloc (abfd, (bfd_size_type) sizeof (struct sec_merge_info));
422       if (sinfo == NULL)
423         goto error_return;
424       sinfo->next = (struct sec_merge_info *) *psinfo;
425       sinfo->chain = NULL;
426       *psinfo = (PTR) sinfo;
427       sinfo->htab =
428         sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
429       if (sinfo->htab == NULL)
430         goto error_return;
431     }
432
433   /* Read the section from abfd.  */
434
435   amt = sizeof (struct sec_merge_sec_info) + sec->_raw_size - 1;
436   *psecinfo = bfd_alloc (abfd, amt);
437   if (*psecinfo == NULL)
438     goto error_return;
439
440   secinfo = (struct sec_merge_sec_info *)*psecinfo;
441   if (sinfo->chain)
442     {
443       secinfo->next = sinfo->chain->next;
444       sinfo->chain->next = secinfo;
445     }
446   else
447     secinfo->next = secinfo;
448   sinfo->chain = secinfo;
449   secinfo->sec = sec;
450   secinfo->psecinfo = psecinfo;
451   secinfo->htab = sinfo->htab;
452   secinfo->first = NULL;
453
454   if (! bfd_get_section_contents (sec->owner, sec, secinfo->contents,
455                                   (bfd_vma) 0, sec->_raw_size))
456     goto error_return;
457
458   return true;
459
460  error_return:
461   *psecinfo = NULL;
462   return false;
463 }
464
465 /* Compare two sec_merge_hash_entry structures.  This is called via qsort.  */
466
467 static int
468 cmplengthentry (a, b)
469      const PTR a;
470      const PTR b;
471 {
472   struct sec_merge_hash_entry * A = *(struct sec_merge_hash_entry **) a;
473   struct sec_merge_hash_entry * B = *(struct sec_merge_hash_entry **) b;
474
475   if (A->len < B->len)
476     return 1;
477   else if (A->len > B->len)
478     return -1;
479
480   return memcmp (A->root.string, B->root.string, A->len);
481 }
482
483 static int
484 last4_eq (a, b)
485      const PTR a;
486      const PTR b;
487 {
488   struct sec_merge_hash_entry * A = (struct sec_merge_hash_entry *) a;
489   struct sec_merge_hash_entry * B = (struct sec_merge_hash_entry *) b;
490
491   if (memcmp (A->root.string + A->len - 5 * A->u.entsize,
492               B->root.string + B->len - 5 * A->u.entsize,
493               4 * A->u.entsize) != 0)
494     /* This was a hashtable collision.  */
495     return 0;
496
497   if (A->len <= B->len)
498     /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
499        not to be equal by the hash table.  */
500     return 0;
501
502   if (A->alignment < B->alignment
503       || ((A->len - B->len) & (B->alignment - 1)))
504     /* The suffix is not sufficiently aligned.  */
505     return 0;
506
507   return memcmp (A->root.string + (A->len - B->len),
508                  B->root.string, B->len - 5 * A->u.entsize) == 0;
509 }
510
511 static int
512 last_eq (a, b)
513      const PTR a;
514      const PTR b;
515 {
516   struct sec_merge_hash_entry * A = (struct sec_merge_hash_entry *) a;
517   struct sec_merge_hash_entry * B = (struct sec_merge_hash_entry *) b;
518
519   if (B->len >= 5 * A->u.entsize)
520     /* Longer strings are just pushed into the hash table,
521        they'll be used when looking up for very short strings.  */
522     return 0;
523
524   if (memcmp (A->root.string + A->len - 2 * A->u.entsize,
525               B->root.string + B->len - 2 * A->u.entsize,
526               A->u.entsize) != 0)
527     /* This was a hashtable collision.  */
528     return 0;
529
530   if (A->len <= B->len)
531     /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
532        not to be equal by the hash table.  */
533     return 0;
534
535   if (A->alignment < B->alignment
536       || ((A->len - B->len) & (B->alignment - 1)))
537     /* The suffix is not sufficiently aligned.  */
538     return 0;
539
540   return memcmp (A->root.string + (A->len - B->len),
541                  B->root.string, B->len - 2 * A->u.entsize) == 0;
542 }
543
544 /* Record one section into the hash table.  */
545 static boolean
546 record_section (sinfo, secinfo)
547      struct sec_merge_info *sinfo;
548      struct sec_merge_sec_info *secinfo;
549 {
550   asection *sec = secinfo->sec;
551   struct sec_merge_hash_entry *entry;
552   boolean nul;
553   unsigned char *p, *end;
554   bfd_vma mask, eltalign;
555   unsigned int align, i;
556
557   align = bfd_get_section_alignment (sec->owner, sec);
558   end = secinfo->contents + sec->_raw_size;
559   nul = false;
560   mask = ((bfd_vma) 1 << align) - 1;
561   if (sec->flags & SEC_STRINGS)
562     {
563       for (p = secinfo->contents; p < end; )
564         {
565           eltalign = p - secinfo->contents;
566           eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
567           if (!eltalign || eltalign > mask)
568             eltalign = mask + 1;
569           entry = sec_merge_add (sinfo->htab, p, (unsigned) eltalign, secinfo);
570           if (! entry)
571             goto error_return;
572           p += entry->len;
573           if (sec->entsize == 1)
574             {
575               while (p < end && *p == 0)
576                 {
577                   if (!nul && !((p - secinfo->contents) & mask))
578                     {
579                       nul = true;
580                       entry = sec_merge_add (sinfo->htab, "",
581                                              (unsigned) mask + 1, secinfo);
582                       if (! entry)
583                         goto error_return;
584                     }
585                   p++;
586                 }
587             }
588           else
589             {
590               while (p < end)
591                 {
592                   for (i = 0; i < sec->entsize; i++)
593                     if (p[i] != '\0')
594                       break;
595                   if (i != sec->entsize)
596                     break;
597                   if (!nul && !((p - secinfo->contents) & mask))
598                     {
599                       nul = true;
600                       entry = sec_merge_add (sinfo->htab, p,
601                                              (unsigned) mask + 1, secinfo);
602                       if (! entry)
603                         goto error_return;
604                     }
605                   p += sec->entsize;
606                 }
607             }
608         }
609     }
610   else
611     {
612       for (p = secinfo->contents; p < end; p += sec->entsize)
613         {
614           entry = sec_merge_add (sinfo->htab, p, 1, secinfo);
615           if (! entry)
616             goto error_return;
617         }
618     }
619
620   return true;
621
622 error_return:
623   for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
624     *secinfo->psecinfo = NULL;
625   return false;
626 }
627
628 /* This is a helper function for _bfd_merge_sections.  It attempts to
629    merge strings matching suffixes of longer strings.  */
630 static void
631 merge_strings (sinfo)
632      struct sec_merge_info *sinfo;
633 {
634   struct sec_merge_hash_entry **array, **a, **end, *e;
635   struct sec_merge_sec_info *secinfo;
636   htab_t lasttab = NULL, last4tab = NULL;
637   bfd_size_type size, amt;
638
639   /* Now sort the strings by length, longest first.  */
640   array = NULL;
641   amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
642   array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
643   if (array == NULL)
644     goto alloc_failure;
645
646   for (e = sinfo->htab->first, a = array; e; e = e->next)
647     if (e->alignment)
648       *a++ = e;
649
650   sinfo->htab->size = a - array;
651
652   qsort (array, (size_t) sinfo->htab->size,
653          sizeof (struct sec_merge_hash_entry *), cmplengthentry);
654
655   last4tab = htab_create_alloc ((size_t) sinfo->htab->size * 4, 
656                                 NULL, last4_eq, NULL, calloc, free);
657   lasttab = htab_create_alloc ((size_t) sinfo->htab->size * 4, 
658                                NULL, last_eq, NULL, calloc, free);
659   if (lasttab == NULL || last4tab == NULL)
660     goto alloc_failure;
661
662   /* Now insert the strings into hash tables (strings with last 4 characters
663      and strings with last character equal), look for longer strings which
664      we're suffix of.  */
665   for (a = array, end = array + sinfo->htab->size; a < end; a++)
666     {
667       register hashval_t hash;
668       unsigned int c;
669       unsigned int i;
670       const unsigned char *s;
671       PTR *p;
672
673       e = *a;
674       e->u.entsize = sinfo->htab->entsize;
675       if (e->len <= e->u.entsize)
676         break;
677       if (e->len > 4 * e->u.entsize)
678         {
679           s = e->root.string + e->len - e->u.entsize;
680           hash = 0;
681           for (i = 0; i < 4 * e->u.entsize; i++)
682             {
683               c = *--s;
684               hash += c + (c << 17);
685               hash ^= hash >> 2;
686             }
687           p = htab_find_slot_with_hash (last4tab, e, hash, INSERT);
688           if (p == NULL)
689             goto alloc_failure;
690           if (*p)
691             {
692               struct sec_merge_hash_entry *ent;
693
694               ent = (struct sec_merge_hash_entry *) *p;
695               e->u.suffix = ent;
696               e->alignment = 0;
697               continue;
698             }
699           else
700             *p = (PTR) e;
701         }
702       s = e->root.string + e->len - e->u.entsize;
703       hash = 0;
704       for (i = 0; i < e->u.entsize; i++)
705         {
706           c = *--s;
707           hash += c + (c << 17);
708           hash ^= hash >> 2;
709         }
710       p = htab_find_slot_with_hash (lasttab, e, hash, INSERT);
711       if (p == NULL)
712         goto alloc_failure;
713       if (*p)
714         {
715           struct sec_merge_hash_entry *ent;
716
717           ent = (struct sec_merge_hash_entry *) *p;
718           e->u.suffix = ent;
719           e->alignment = 0;
720         }
721       else
722         *p = (PTR) e;
723     }
724
725 alloc_failure:
726   if (array)
727     free (array);
728   if (lasttab)
729     htab_delete (lasttab);
730   if (last4tab)
731     htab_delete (last4tab);
732
733   /* Now assign positions to the strings we want to keep.  */
734   size = 0;
735   secinfo = sinfo->htab->first->secinfo;
736   for (e = sinfo->htab->first; e; e = e->next)
737     {
738       if (e->secinfo != secinfo)
739         {
740           secinfo->sec->_cooked_size = size;
741           secinfo = e->secinfo;
742         }
743       if (e->alignment)
744         {
745           if (e->secinfo->first == NULL)
746             {
747               e->secinfo->first = e;
748               size = 0;
749             }
750           size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
751           e->u.index = size;
752           size += e->len;
753         }
754     }
755   secinfo->sec->_cooked_size = size;
756
757   /* And now adjust the rest, removing them from the chain (but not hashtable)
758      at the same time.  */
759   for (a = &sinfo->htab->first, e = *a; e; e = e->next)
760     if (e->alignment)
761       a = &e->next;
762     else
763       {
764         *a = e->next;
765         if (e->len)
766           {
767             e->secinfo = e->u.suffix->secinfo;
768             e->alignment = e->u.suffix->alignment;
769             e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
770           }
771       }
772 }
773
774 /* This function is called once after all SEC_MERGE sections are registered
775    with _bfd_merge_section.  */
776
777 boolean
778 _bfd_merge_sections (abfd, xsinfo, remove_hook)
779      bfd *abfd ATTRIBUTE_UNUSED;
780      PTR xsinfo;
781      void (*remove_hook) PARAMS((bfd *, asection *));
782 {
783   struct sec_merge_info *sinfo;
784
785   for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
786     {
787       struct sec_merge_sec_info * secinfo;
788
789       if (! sinfo->chain)
790         continue;
791
792       /* Move sinfo->chain to head of the chain, terminate it.  */
793       secinfo = sinfo->chain;
794       sinfo->chain = secinfo->next;
795       secinfo->next = NULL;
796
797       /* Record the sections into the hash table.  */
798       for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
799         if (secinfo->sec->flags & SEC_EXCLUDE)
800           {
801             *secinfo->psecinfo = NULL;
802             if (remove_hook)
803               (*remove_hook) (abfd, secinfo->sec);
804           }
805         else if (! record_section (sinfo, secinfo))
806           break;
807
808       if (secinfo)
809         continue;
810
811       if (sinfo->htab->first == NULL)
812         continue;
813
814       if (sinfo->htab->strings)
815         merge_strings (sinfo);
816       else
817         {
818           struct sec_merge_hash_entry *e;
819           bfd_size_type size = 0;
820
821           /* Things are much simpler for non-strings.
822              Just assign them slots in the section.  */
823           secinfo = NULL;
824           for (e = sinfo->htab->first; e; e = e->next)
825             {
826               if (e->secinfo->first == NULL)
827                 {
828                   if (secinfo)
829                     secinfo->sec->_cooked_size = size;
830                   e->secinfo->first = e;
831                   size = 0;
832                 }
833               size = (size + e->alignment - 1)
834                      & ~((bfd_vma) e->alignment - 1);
835               e->u.index = size;
836               size += e->len;
837               secinfo = e->secinfo;
838             }
839           secinfo->sec->_cooked_size = size;
840         }
841
842         /* Finally shrink all input sections which have not made it into
843            the hash table at all.  */
844         for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
845           if (secinfo->first == NULL)
846             {
847               secinfo->sec->_cooked_size = 0;
848               secinfo->sec->flags |= SEC_EXCLUDE;
849             }
850     }
851
852   return true;
853 }
854
855 /* Write out the merged section.  */
856
857 boolean
858 _bfd_write_merged_section (output_bfd, sec, psecinfo)
859      bfd *output_bfd;
860      asection *sec;
861      PTR psecinfo;
862 {
863   struct sec_merge_sec_info *secinfo;
864   file_ptr pos;
865
866   secinfo = (struct sec_merge_sec_info *) psecinfo;
867
868   if (!secinfo->first)
869     return true;
870
871   pos = sec->output_section->filepos + sec->output_offset;
872   if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
873     return false;
874
875   if (! sec_merge_emit (output_bfd, secinfo->first))
876     return false;
877
878   return true;
879 }
880
881 /* Adjust an address in the SEC_MERGE section.  Given OFFSET within
882    *PSEC, this returns the new offset in the adjusted SEC_MERGE
883    section and writes the new section back into *PSEC.  */
884
885 bfd_vma
886 _bfd_merged_section_offset (output_bfd, psec, psecinfo, offset, addend)
887      bfd *output_bfd ATTRIBUTE_UNUSED;
888      asection **psec;
889      PTR psecinfo;
890      bfd_vma offset, addend;
891 {
892   struct sec_merge_sec_info *secinfo;
893   struct sec_merge_hash_entry *entry;
894   unsigned char *p;
895   asection *sec = *psec;
896
897   secinfo = (struct sec_merge_sec_info *) psecinfo;
898
899   if (offset + addend >= sec->_raw_size)
900     {
901       if (offset + addend > sec->_raw_size)
902         {
903           (*_bfd_error_handler)
904             (_("%s: access beyond end of merged section (%ld + %ld)"),
905              bfd_get_filename (sec->owner), (long) offset, (long) addend);
906         }
907       return (secinfo->first ? sec->_cooked_size : 0);
908     }
909
910   if (secinfo->htab->strings)
911     {
912       if (sec->entsize == 1)
913         {
914           p = secinfo->contents + offset + addend - 1;
915           while (p >= secinfo->contents && *p)
916             --p;
917           ++p;
918         }
919       else
920         {
921           p = secinfo->contents
922               + ((offset + addend) / sec->entsize) * sec->entsize;
923           p -= sec->entsize;
924           while (p >= secinfo->contents)
925             {
926               unsigned int i;
927
928               for (i = 0; i < sec->entsize; ++i)
929                 if (p[i] != '\0')
930                   break;
931               if (i == sec->entsize)
932                 break;
933               p -= sec->entsize;
934             }
935           p += sec->entsize;
936         }
937     }
938   else
939     {
940       p = secinfo->contents
941           + ((offset + addend) / sec->entsize) * sec->entsize;
942     }
943   entry = sec_merge_hash_lookup (secinfo->htab, p, 0, false);
944   if (!entry)
945     {
946       if (! secinfo->htab->strings)
947         abort ();
948       /* This should only happen if somebody points into the padding
949          after a NUL character but before next entity.  */
950       if (*p)
951         abort ();
952       if (! secinfo->htab->first)
953         abort ();
954       entry = secinfo->htab->first;
955       p = secinfo->contents
956           + ((offset + addend) / sec->entsize + 1) * sec->entsize
957           - entry->len;
958     }
959
960   *psec = entry->secinfo->sec;
961   return entry->u.index + (secinfo->contents + offset - p);
962 }