OSDN Git Service

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