2 Copyright (C) 2001-2024 Free Software Foundation, Inc.
3 Written by Jakub Jelinek <jakub@redhat.com>.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
23 /* This file contains support for merging duplicate entities within sections,
24 as used in ELF SHF_MERGE. */
32 #include "libiberty.h"
34 /* We partition all mergable input sections into sets of similar
35 characteristics. These sets are the unit of merging. All content
36 of the input sections is scanned and inserted into a hash table.
37 We also remember an input-offset to entry mapping per input section, but
38 the content itself is removed. After everything is read in we assign
39 output offsets to all hash entries, and when relocations are processed we
40 lookup the given input offset per input-section, get the matching entry
41 and its output offset (possibly adjusted for offset pointing into the
44 The input-offset-to-entry mapping (in map_ofs/map) is sorted, so in principle
45 we could binary search it, but that's not cache-friendly and it's faster
46 to add another lookup structure that gets us very near the correct
47 entry in just one step (that's what ofstolowbound is for) and do a linear
50 /* An entry in the section merge hash table. */
52 struct sec_merge_hash_entry
54 /* Length of this entry. This includes the zero terminator. */
56 /* Start of this string needs to be aligned to
57 alignment octets (not 1 << align). */
58 unsigned int alignment
;
61 /* Index within the merged section. */
63 /* Entry this is a suffix of (if alignment is 0). */
64 struct sec_merge_hash_entry
*suffix
;
66 /* Next entity in the hash table (in order of entering). */
67 struct sec_merge_hash_entry
*next
;
71 /* The section merge hash table. */
75 struct bfd_hash_table table
;
76 /* First entity in the SEC_MERGE sections of this type. */
77 struct sec_merge_hash_entry
*first
;
78 /* Last entity in the SEC_MERGE sections of this type. */
79 struct sec_merge_hash_entry
*last
;
82 /* Are entries fixed size or zero terminated strings? */
84 /* struct-of-array variant of all entries in the hash-table: */
85 unsigned int nbuckets
;
86 /* We keep hash-code and length of entry together in a separate
87 array in such a way that it can be checked with just a single memory
88 reference. In this way we don't need indirect access to the entries
89 in the normal case. keys_lens[i] is 'hashcode << 32) | len' for entry
90 i (which is pointed to be values[i]). */
92 struct sec_merge_hash_entry
**values
;
95 struct sec_merge_sec_info
;
97 /* Information per merged blob. This is the unit of merging and is
98 related to (multiple) input sections of similar characteristics
99 (alignment, entity size, strings or blobs). */
100 struct sec_merge_info
102 /* Chain of sec_merge_infos. */
103 struct sec_merge_info
*next
;
104 /* Chain of sec_merge_sec_infos. This first one will be the representative
105 section that conceptually collects all merged content. */
106 struct sec_merge_sec_info
*chain
;
107 struct sec_merge_sec_info
**last
;
108 /* A hash table used to hold section content. */
109 struct sec_merge_hash
*htab
;
112 /* Offset into input mergable sections are represented by this type.
113 Note how doesn't support crazy large mergable sections. */
114 typedef uint32_t mapofs_type
;
116 /* Given a sec_merge_sec_info S this gives the input offset of the IDX's
118 #define MAP_OFS(S,IDX) (S)->map_ofs[IDX]
119 /* And this gives the output offset (in the merged blob representing
121 #define MAP_IDX(S,IDX) (S)->map[IDX].idx
122 /* For quick lookup of output offset given an input offset we store
123 an array mapping intput-offset / OFSDIV to entry index.
124 16 is better than 8, 32 is roughly same as 16, but uses less memory, so
128 /* Information per input merge section. */
129 struct sec_merge_sec_info
131 /* Chain of sec_merge_sec_infos. */
132 struct sec_merge_sec_info
*next
;
133 /* The corresponding section. */
135 /* Pointer to merge_info pointing to us. */
137 /* The merge entity this is a part of. */
138 struct sec_merge_info
*sinfo
;
139 /* The section associated with sinfo (i.e. the representative section).
140 Same as sinfo->chain->sec, but faster to access in the hot function. */
142 /* First string in this section. */
143 struct sec_merge_hash_entry
*first_str
;
144 /* Sparse mapping from input offset to entry covering that offset: */
145 unsigned int noffsetmap
; /* Number of these mappings. */
146 mapofs_type
*map_ofs
; /* Input offset. */
148 struct sec_merge_hash_entry
*entry
; /* Covering hash entry ... */
149 bfd_size_type idx
; /* ... or destination offset. */
151 /* Quick access: index into map_ofs[]. ofstolowbound[o / OFSDIV]=I is
152 such that map_ofs[I] is the smallest offset higher that
153 rounddown(o, OFSDIV) (and hence I-1 is the largest entry whose offset is
154 smaller or equal to o/OFSDIV*OFSDIV). */
155 unsigned int *ofstolowbound
;
160 /* True when COUNT+ADDED and NBUCKETS indicate that the hash table
164 needs_resize (unsigned int count
, unsigned int added
, unsigned int nbuckets
)
166 /* This doesn't consider the possibility of "count" + "added"
167 overflowing, because that can't happen given current usage. If
168 code calling this function changes then that assumption may no
169 longer be correct. Currently "added" is always 1 and "nbuckets"
170 is limited to 0x80000000. We'll attempt and fail resizing at
171 "count" of 0x55555555. */
172 return count
+ added
> nbuckets
/ 3 * 2;
175 /* Given a merge hash table TABLE and a number of entries to be
176 ADDED, resize the table for this to fit.
177 Returns false if that can't be done for whatever reason. */
180 sec_merge_resize (struct sec_merge_hash
*table
, unsigned added
)
182 struct bfd_hash_table
*bfdtab
= &table
->table
;
184 unsigned long newnb
= table
->nbuckets
;
185 struct sec_merge_hash_entry
**newv
;
191 if (newnb
>> (8 * sizeof(mapofs_type
) - 1))
195 while (needs_resize (bfdtab
->count
, added
, newnb
));
197 alloc
= newnb
* sizeof (newl
[0]);
198 if (alloc
/ sizeof (newl
[0]) != newnb
)
200 newl
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
, alloc
);
203 memset (newl
, 0, alloc
);
204 alloc
= newnb
* sizeof (newv
[0]);
205 if (alloc
/ sizeof (newv
[0]) != newnb
)
207 newv
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
, alloc
);
210 memset (newv
, 0, alloc
);
212 for (i
= 0; i
< table
->nbuckets
; i
++)
214 struct sec_merge_hash_entry
*v
= table
->values
[i
];
217 uint32_t thishash
= table
->key_lens
[i
] >> 32;
218 unsigned idx
= thishash
& (newnb
- 1);
220 idx
= (idx
+ 1) & (newnb
- 1);
221 newl
[idx
] = table
->key_lens
[i
];
226 table
->key_lens
= newl
;
227 table
->values
= newv
;
228 table
->nbuckets
= newnb
;
232 /* Insert STRING (actually a byte blob of length LEN, with pre-computed
233 HASH and bucket _INDEX) into our hash TABLE. */
235 static struct sec_merge_hash_entry
*
236 sec_merge_hash_insert (struct sec_merge_hash
*table
,
238 uint64_t hash
, unsigned int len
, unsigned int _index
)
240 struct bfd_hash_table
*bfdtab
= &table
->table
;
241 struct sec_merge_hash_entry
*hashp
;
243 hashp
= (struct sec_merge_hash_entry
*)
244 bfd_hash_allocate (bfdtab
, len
+ sizeof (struct sec_merge_hash_entry
));
248 memcpy (hashp
->str
, string
, len
);
250 hashp
->alignment
= 0;
251 hashp
->u
.suffix
= NULL
;
254 if (needs_resize (bfdtab
->count
, 1, table
->nbuckets
))
256 if (!sec_merge_resize (table
, 1))
258 uint64_t *key_lens
= table
->key_lens
;
259 unsigned int nbuckets
= table
->nbuckets
;
260 _index
= hash
& (nbuckets
- 1);
263 uint64_t candlen
= key_lens
[_index
];
264 if (!(candlen
& (uint32_t)-1))
266 _index
= (_index
+ 1) & (nbuckets
- 1);
271 table
->key_lens
[_index
] = (hash
<< 32) | (uint32_t)len
;
272 table
->values
[_index
] = hashp
;
277 /* Read four bytes from *STR, interpret it as 32bit unsigned little
278 endian value and return that. */
280 static inline uint32_t
281 hash_read32 (const char *str
)
284 /* All reasonable compilers will inline this memcpy and generate optimal
285 code on architectures that support unaligned (4-byte) accesses. */
287 #ifdef WORDS_BIGENDIAN
288 i
= (i
<< 24) | ((i
& 0xff00) << 8) | ((i
>> 8) & 0xff00) | (i
>> 24);
293 /* Calculate and return a hashvalue of the bytes at STR[0..LEN-1].
294 All non-zero lengths and all alignments are supported.
296 This is somewhat similar to xxh3 (of xxhash), but restricted to 32bit.
297 On cc1 strings this has quite similar statistic properties, and we
298 don't need to jump through hoops to get fast 64x64->128 mults,
299 or 64bit arith on 32 bit hosts. We also don't care for seeds
300 or secrets. They improve mixing very little. */
303 hash_blob (const char *str
, unsigned int len
)
306 uint32_t mul
= (1 << 0) + (1 << 2) + (1 << 3) + (1 << 5) + (1 << 7);
307 mul
+= (1 << 11) + (1 << 13) + (1 << 17) + (0 << 19) + (1 << 23) + (1 << 29);
311 uint32_t acc
= len
* 0x9e3779b1;
314 uint32_t i1
= hash_read32 (str
) ^ (0x396cfeb8 + 1*len
);
315 uint32_t i2
= hash_read32 (str
+ 4) ^ (0xbe4ba423 + 1*len
);
318 uint64_t m
= (uint64_t)i1
* i2
;
319 acc
+= (uint32_t)m
^ (uint32_t)(m
>> 32);
321 acc
= acc
^ (acc
>> 7);
322 uint64_t r
= (uint64_t)mul
* acc
;
323 ret
= (uint32_t)r
^ (uint32_t)(r
>> 32);
329 uint32_t i1
= hash_read32 (str
);
330 uint32_t i2
= hash_read32 (str
+ len
- 4);
331 i1
= ((i1
+ len
) ^ (i1
>> 7));
333 uint64_t r
= (uint64_t)mul
* i1
+ i2
;
334 ret
+= r
^ (r
>> 32);
338 /* Cleverly read in 1 to 3 bytes without further conditionals. */
339 unsigned char c1
= str
[0];
340 unsigned char c2
= str
[len
>> 1];
341 unsigned char c3
= str
[len
- 1];
342 uint32_t i1
= ((uint32_t)c1
<< 16) | ((uint32_t)c2
<< 24)
343 | ((uint32_t) c3
) | (len
<< 8);
345 uint64_t r
= (uint64_t)mul
* i1
;
346 ret
+= r
^ (r
>> 32);
352 /* Given a hash TABLE, return the hash of STRING (a blob described
353 according to info in TABLE, either a character string, or some fixed
354 size entity) and set *PLEN to the length of this blob. */
357 hashit (struct sec_merge_hash
*table
, const char *string
, unsigned int *plen
)
359 const unsigned char *s
;
363 s
= (const unsigned char *) string
;
366 if (table
->entsize
== 1)
367 len
= strlen (string
) + 1;
373 for (i
= 0; i
< table
->entsize
; ++i
)
376 if (i
== table
->entsize
)
381 len
*= table
->entsize
;
382 len
+= table
->entsize
;
386 len
= table
->entsize
;
387 hash
= hash_blob (string
, len
);
392 /* Lookup or insert a blob STRING (of length LEN, precomputed HASH and
393 input ALIGNMENT) into TABLE. Return the found or new hash table entry. */
395 static struct sec_merge_hash_entry
*
396 sec_merge_hash_lookup (struct sec_merge_hash
*table
, const char *string
,
397 unsigned int len
, uint64_t hash
,
398 unsigned int alignment
)
400 struct sec_merge_hash_entry
*hashp
;
403 /*printf ("YYY insert 0x%x into %u buckets (%s)\n",
404 (unsigned)hash, (unsigned)table->nbuckets, string);*/
405 uint64_t *key_lens
= table
->key_lens
;
406 struct sec_merge_hash_entry
**values
= table
->values
;
407 uint64_t hlen
= (hash
<< 32) | (uint32_t)len
;
408 unsigned int nbuckets
= table
->nbuckets
;
409 _index
= hash
& (nbuckets
- 1);
412 uint64_t candlen
= key_lens
[_index
];
414 && !memcmp (values
[_index
]->str
, string
, len
))
416 hashp
= values
[_index
];
417 if (hashp
->alignment
< alignment
)
418 hashp
->alignment
= alignment
;
421 if (!(candlen
& (uint32_t)-1))
423 _index
= (_index
+ 1) & (nbuckets
- 1);
426 hashp
= sec_merge_hash_insert (table
, string
, hash
, len
, _index
);
429 hashp
->alignment
= alignment
;
431 if (table
->first
== NULL
)
432 table
->first
= hashp
;
434 table
->last
->next
= hashp
;
440 /* Create a new hash table. */
442 static struct sec_merge_hash
*
443 sec_merge_init (unsigned int entsize
, bool strings
)
445 struct sec_merge_hash
*table
;
447 table
= (struct sec_merge_hash
*) bfd_malloc (sizeof (struct sec_merge_hash
));
451 if (! bfd_hash_table_init_n (&table
->table
, NULL
,
452 sizeof (struct sec_merge_hash_entry
), 0x2000))
460 table
->entsize
= entsize
;
461 table
->strings
= strings
;
463 table
->nbuckets
= 0x2000;
464 table
->key_lens
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
,
465 table
->nbuckets
* sizeof (table
->key_lens
[0]));
466 memset (table
->key_lens
, 0, table
->nbuckets
* sizeof (table
->key_lens
[0]));
467 table
->values
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
,
468 table
->nbuckets
* sizeof (table
->values
[0]));
469 memset (table
->values
, 0, table
->nbuckets
* sizeof (table
->values
[0]));
474 /* Append the tuple of input-offset O corresponding
475 to hash table ENTRY into SECINFO, such that we later may lookup the
479 append_offsetmap (struct sec_merge_sec_info
*secinfo
,
481 struct sec_merge_hash_entry
*entry
)
483 if ((secinfo
->noffsetmap
& 2047) == 0)
486 amt
= (secinfo
->noffsetmap
+ 2048);
487 secinfo
->map_ofs
= bfd_realloc (secinfo
->map_ofs
,
488 amt
* sizeof(secinfo
->map_ofs
[0]));
489 if (!secinfo
->map_ofs
)
491 secinfo
->map
= bfd_realloc (secinfo
->map
, amt
* sizeof(secinfo
->map
[0]));
495 unsigned int i
= secinfo
->noffsetmap
++;
496 MAP_OFS(secinfo
, i
) = o
;
497 secinfo
->map
[i
].entry
= entry
;
501 /* Prepare the input-offset-to-entry tables after output offsets are
505 prepare_offsetmap (struct sec_merge_sec_info
*secinfo
)
507 unsigned int noffsetmap
= secinfo
->noffsetmap
;
509 bfd_size_type l
, sz
, amt
;
511 secinfo
->fast_state
= 1;
513 for (i
= 0; i
< noffsetmap
; i
++)
514 MAP_IDX(secinfo
, i
) = secinfo
->map
[i
].entry
->u
.index
;
516 sz
= secinfo
->sec
->rawsize
;
517 amt
= (sz
/ OFSDIV
+ 1) * sizeof (secinfo
->ofstolowbound
[0]);
518 secinfo
->ofstolowbound
= bfd_zmalloc (amt
);
519 if (!secinfo
->ofstolowbound
)
521 for (l
= lbi
= 0; l
< sz
; l
+= OFSDIV
)
523 /* No need for bounds checking on lbi, as we've added a sentinel that's
524 larger than any offset. */
525 while (MAP_OFS(secinfo
, lbi
) <= l
)
527 //BFD_ASSERT ((l / OFSDIV) <= (i / OFSDIV));
528 secinfo
->ofstolowbound
[l
/ OFSDIV
] = lbi
;
530 secinfo
->fast_state
= 2;
534 sec_merge_emit (bfd
*abfd
, struct sec_merge_sec_info
*secinfo
,
535 unsigned char *contents
)
537 struct sec_merge_hash_entry
*entry
= secinfo
->first_str
;
538 asection
*sec
= secinfo
->sec
;
539 file_ptr offset
= sec
->output_offset
;
541 bfd_size_type off
= 0;
542 unsigned int opb
= bfd_octets_per_byte (abfd
, sec
);
543 int alignment_power
= sec
->output_section
->alignment_power
* opb
;
544 bfd_size_type pad_len
; /* Octets. */
546 /* FIXME: If alignment_power is 0 then really we should scan the
547 entry list for the largest required alignment and use that. */
548 pad_len
= alignment_power
? ((bfd_size_type
) 1 << alignment_power
) : 16;
550 pad
= (char *) bfd_zmalloc (pad_len
);
554 for (; entry
!= NULL
; entry
= entry
->next
)
561 BFD_ASSERT (entry
->alignment
);
562 len
= -off
& (entry
->alignment
- 1);
565 BFD_ASSERT (len
<= pad_len
);
568 memcpy (contents
+ offset
, pad
, len
);
571 else if (bfd_write (pad
, len
, abfd
) != len
)
581 memcpy (contents
+ offset
, str
, len
);
584 else if (bfd_write (str
, len
, abfd
) != len
)
591 /* Trailing alignment needed? */
592 off
= sec
->size
- off
;
595 BFD_ASSERT (off
<= pad_len
);
597 memcpy (contents
+ offset
, pad
, off
);
598 else if (bfd_write (pad
, off
, abfd
) != off
)
610 /* Register a SEC_MERGE section as a candidate for merging.
611 This function is called for all non-dynamic SEC_MERGE input sections. */
614 _bfd_add_merge_section (bfd
*abfd
, void **psinfo
, asection
*sec
,
617 struct sec_merge_info
*sinfo
;
618 struct sec_merge_sec_info
*secinfo
;
620 unsigned int alignment_power
; /* Octets. */
621 unsigned int align
; /* Octets. */
622 unsigned int opb
= bfd_octets_per_byte (abfd
, sec
);
624 if ((abfd
->flags
& DYNAMIC
) != 0
625 || (sec
->flags
& SEC_MERGE
) == 0)
629 || (sec
->flags
& SEC_EXCLUDE
) != 0
630 || (sec
->flags
& SEC_HAS_CONTENTS
) == 0
631 || sec
->entsize
== 0)
634 if (sec
->size
% sec
->entsize
!= 0)
637 if ((sec
->flags
& SEC_RELOC
) != 0)
639 /* We aren't prepared to handle relocations in merged sections. */
643 if (sec
->size
> (mapofs_type
)-1)
645 /* Input offsets must be representable by mapofs_type. */
652 alignment_power
= sec
->alignment_power
* opb
;
653 if (alignment_power
>= sizeof (align
) * CHAR_BIT
)
656 align
= 1u << alignment_power
;
657 if ((sec
->entsize
< align
658 && ((sec
->entsize
& (sec
->entsize
- 1))
659 || !(sec
->flags
& SEC_STRINGS
)))
660 || (sec
->entsize
> align
661 && (sec
->entsize
& (align
- 1))))
663 /* Sanity check. If string character size is smaller than
664 alignment, then we require character size to be a power
665 of 2, otherwise character size must be integer multiple
666 of alignment. For non-string constants, alignment must
667 be smaller than or equal to entity size and entity size
668 must be integer multiple of alignment. */
672 /* Initialize the descriptor for this input section. */
674 *psecinfo
= secinfo
= bfd_zalloc (abfd
, sizeof (*secinfo
));
675 if (*psecinfo
== NULL
)
679 secinfo
->psecinfo
= psecinfo
;
681 /* Search for a matching output merged section. */
682 for (sinfo
= (struct sec_merge_info
*) *psinfo
; sinfo
; sinfo
= sinfo
->next
)
684 && (repr
= sinfo
->chain
->sec
)
685 && ! ((repr
->flags
^ sec
->flags
) & (SEC_MERGE
| SEC_STRINGS
))
686 && repr
->entsize
== sec
->entsize
687 && repr
->alignment_power
== sec
->alignment_power
688 && repr
->output_section
== sec
->output_section
)
693 /* Initialize the information we need to keep track of. */
694 sinfo
= (struct sec_merge_info
*)
695 bfd_alloc (abfd
, sizeof (struct sec_merge_info
));
698 sinfo
->next
= (struct sec_merge_info
*) *psinfo
;
700 sinfo
->last
= &sinfo
->chain
;
702 sinfo
->htab
= sec_merge_init (sec
->entsize
, (sec
->flags
& SEC_STRINGS
));
703 if (sinfo
->htab
== NULL
)
707 *sinfo
->last
= secinfo
;
708 sinfo
->last
= &secinfo
->next
;
710 secinfo
->sinfo
= sinfo
;
711 secinfo
->reprsec
= sinfo
->chain
->sec
;
720 /* Record one whole input section (described by SECINFO) into the hash table
721 SINFO. Returns true when section is completely recorded, and false when
722 it wasn't recorded but we can continue (e.g. by simply not deduplicating
726 record_section (struct sec_merge_info
*sinfo
,
727 struct sec_merge_sec_info
*secinfo
)
729 asection
*sec
= secinfo
->sec
;
730 struct sec_merge_hash_entry
*entry
;
731 unsigned char *p
, *end
;
732 bfd_vma mask
, eltalign
;
739 if (sec
->flags
& SEC_STRINGS
)
740 /* Some versions of gcc may emit a string without a zero terminator.
741 See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html
742 Allocate space for an extra zero. */
744 contents
= bfd_malloc (amt
);
748 /* Slurp in all section contents (possibly decompressing it). */
749 sec
->rawsize
= sec
->size
;
750 if (sec
->flags
& SEC_STRINGS
)
751 memset (contents
+ sec
->size
, 0, sec
->entsize
);
752 if (! bfd_get_full_section_contents (sec
->owner
, sec
, &contents
))
755 /* Now populate the hash table and offset mapping. */
757 /* Walk through the contents, calculate hashes and length of all
758 blobs (strings or fixed-size entries) we find and fill the
759 hash and offset tables. */
760 align
= sec
->alignment_power
;
761 mask
= ((bfd_vma
) 1 << align
) - 1;
762 end
= contents
+ sec
->size
;
763 for (p
= contents
; p
< end
;)
766 uint32_t hash
= hashit (sinfo
->htab
, (char*) p
, &len
);
767 unsigned int ofs
= p
- contents
;
769 eltalign
= ((eltalign
^ (eltalign
- 1)) + 1) >> 1;
770 if (!eltalign
|| eltalign
> mask
)
772 entry
= sec_merge_hash_lookup (sinfo
->htab
, (char *) p
, len
, hash
,
773 (unsigned) eltalign
);
776 if (! append_offsetmap (secinfo
, ofs
, entry
))
781 /* Add a sentinel element that's conceptually behind all others. */
782 append_offsetmap (secinfo
, sec
->size
, NULL
);
783 /* But don't count it. */
784 secinfo
->noffsetmap
--;
789 /* We allocate the ofsmap arrays in blocks of 2048 elements.
790 In case we have very many small input files/sections,
791 this might waste large amounts of memory, so reallocate these
792 arrays here to their true size. */
793 amt
= secinfo
->noffsetmap
+ 1;
794 tmpptr
= bfd_realloc (secinfo
->map
, amt
* sizeof(secinfo
->map
[0]));
796 secinfo
->map
= tmpptr
;
797 tmpptr
= bfd_realloc (secinfo
->map_ofs
, amt
* sizeof(secinfo
->map_ofs
[0]));
799 secinfo
->map_ofs
= tmpptr
;
801 /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
802 (unsigned)secinfo->noffsetmap);*/
812 /* qsort comparison function. Won't ever return zero as all entries
813 differ, so there is no issue with qsort stability here. */
816 strrevcmp (const void *a
, const void *b
)
818 struct sec_merge_hash_entry
*A
= *(struct sec_merge_hash_entry
**) a
;
819 struct sec_merge_hash_entry
*B
= *(struct sec_merge_hash_entry
**) b
;
820 unsigned int lenA
= A
->len
;
821 unsigned int lenB
= B
->len
;
822 const unsigned char *s
= (const unsigned char *) A
->str
+ lenA
- 1;
823 const unsigned char *t
= (const unsigned char *) B
->str
+ lenB
- 1;
824 int l
= lenA
< lenB
? lenA
: lenB
;
829 return (int) *s
- (int) *t
;
837 /* Like strrevcmp, but for the case where all strings have the same
838 alignment > entsize. */
841 strrevcmp_align (const void *a
, const void *b
)
843 struct sec_merge_hash_entry
*A
= *(struct sec_merge_hash_entry
**) a
;
844 struct sec_merge_hash_entry
*B
= *(struct sec_merge_hash_entry
**) b
;
845 unsigned int lenA
= A
->len
;
846 unsigned int lenB
= B
->len
;
847 const unsigned char *s
= (const unsigned char *) A
->str
+ lenA
- 1;
848 const unsigned char *t
= (const unsigned char *) B
->str
+ lenB
- 1;
849 int l
= lenA
< lenB
? lenA
: lenB
;
850 int tail_align
= (lenA
& (A
->alignment
- 1)) - (lenB
& (A
->alignment
- 1));
858 return (int) *s
- (int) *t
;
867 is_suffix (const struct sec_merge_hash_entry
*A
,
868 const struct sec_merge_hash_entry
*B
)
870 if (A
->len
<= B
->len
)
871 /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
872 not to be equal by the hash table. */
875 return memcmp (A
->str
+ (A
->len
- B
->len
),
876 B
->str
, B
->len
) == 0;
879 /* This is a helper function for _bfd_merge_sections. It attempts to
880 merge strings matching suffixes of longer strings. */
881 static struct sec_merge_sec_info
*
882 merge_strings (struct sec_merge_info
*sinfo
)
884 struct sec_merge_hash_entry
**array
, **a
, *e
;
885 struct sec_merge_sec_info
*secinfo
;
886 bfd_size_type size
, amt
;
887 unsigned int alignment
= 0;
889 /* Now sort the strings */
890 amt
= sinfo
->htab
->table
.count
* sizeof (struct sec_merge_hash_entry
*);
891 array
= (struct sec_merge_hash_entry
**) bfd_malloc (amt
);
895 for (e
= sinfo
->htab
->first
, a
= array
; e
; e
= e
->next
)
899 /* Adjust the length to not include the zero terminator. */
900 e
->len
-= sinfo
->htab
->entsize
;
901 if (alignment
!= e
->alignment
)
904 alignment
= e
->alignment
;
906 alignment
= (unsigned) -1;
910 size_t asize
= a
- array
;
914 sizeof (struct sec_merge_hash_entry
*),
915 (alignment
!= (unsigned) -1 && alignment
> sinfo
->htab
->entsize
916 ? strrevcmp_align
: strrevcmp
));
918 /* Loop over the sorted array and merge suffixes */
920 e
->len
+= sinfo
->htab
->entsize
;
923 struct sec_merge_hash_entry
*cmp
= *a
;
925 cmp
->len
+= sinfo
->htab
->entsize
;
926 if (e
->alignment
>= cmp
->alignment
927 && !((e
->len
- cmp
->len
) & (cmp
->alignment
- 1))
928 && is_suffix (e
, cmp
))
940 /* Now assign positions to the strings we want to keep. */
942 secinfo
= sinfo
->chain
;
943 for (e
= sinfo
->htab
->first
; e
; e
= e
->next
)
947 size
= (size
+ e
->alignment
- 1) & ~((bfd_vma
) e
->alignment
- 1);
952 secinfo
->sec
->size
= size
;
954 /* And now adjust the rest, removing them from the chain (but not hashtable)
956 for (a
= &sinfo
->htab
->first
, e
= *a
; e
; e
= e
->next
)
964 e
->alignment
= e
->u
.suffix
->alignment
;
965 e
->u
.index
= e
->u
.suffix
->u
.index
+ (e
->u
.suffix
->len
- e
->len
);
969 BFD_ASSERT (!secinfo
->first_str
);
970 secinfo
->first_str
= sinfo
->htab
->first
;
975 /* This function is called once after all SEC_MERGE sections are registered
976 with _bfd_merge_section. */
979 _bfd_merge_sections (bfd
*abfd
,
980 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
982 void (*remove_hook
) (bfd
*, asection
*))
984 struct sec_merge_info
*sinfo
;
986 for (sinfo
= (struct sec_merge_info
*) xsinfo
; sinfo
; sinfo
= sinfo
->next
)
988 struct sec_merge_sec_info
*secinfo
;
989 bfd_size_type align
; /* Bytes. */
994 /* Record the sections into the hash table. */
996 for (secinfo
= sinfo
->chain
; secinfo
; secinfo
= secinfo
->next
)
997 if (secinfo
->sec
->flags
& SEC_EXCLUDE
998 || !record_section (sinfo
, secinfo
))
1000 *secinfo
->psecinfo
= NULL
;
1002 (*remove_hook
) (abfd
, secinfo
->sec
);
1006 unsigned int opb
= bfd_octets_per_byte (abfd
, secinfo
->sec
);
1008 align
= (bfd_size_type
) 1 << secinfo
->sec
->alignment_power
;
1009 if (((secinfo
->sec
->size
/ opb
) & (align
- 1)) != 0)
1013 if (sinfo
->htab
->first
== NULL
)
1016 if (sinfo
->htab
->strings
)
1018 secinfo
= merge_strings (sinfo
);
1024 struct sec_merge_hash_entry
*e
= sinfo
->htab
->first
;
1025 bfd_size_type size
= 0; /* Octets. */
1027 /* Things are much simpler for non-strings.
1028 Just assign them slots in the section. */
1029 secinfo
= sinfo
->chain
;
1030 BFD_ASSERT (!secinfo
->first_str
);
1031 secinfo
->first_str
= e
;
1032 for (e
= sinfo
->htab
->first
; e
; e
= e
->next
)
1036 size
= (size
+ e
->alignment
- 1)
1037 & ~((bfd_vma
) e
->alignment
- 1);
1042 secinfo
->sec
->size
= size
;
1045 /* If the input sections were padded according to their alignments,
1046 then pad the output too. */
1048 secinfo
->sec
->size
= (secinfo
->sec
->size
+ align
- 1) & -align
;
1050 /* Finally remove all input sections which have not made it into
1051 the hash table at all. */
1052 for (secinfo
= sinfo
->chain
; secinfo
; secinfo
= secinfo
->next
)
1053 if (secinfo
->first_str
== NULL
1054 && secinfo
->sec
->sec_info_type
== SEC_INFO_TYPE_MERGE
)
1055 secinfo
->sec
->flags
|= SEC_EXCLUDE
| SEC_KEEP
;
1061 /* Write out the merged section. */
1064 _bfd_write_merged_section (bfd
*output_bfd
, asection
*sec
, void *psecinfo
)
1066 struct sec_merge_sec_info
*secinfo
;
1068 unsigned char *contents
;
1069 Elf_Internal_Shdr
*hdr
;
1071 secinfo
= (struct sec_merge_sec_info
*) psecinfo
;
1076 if (secinfo
->first_str
== NULL
)
1079 /* FIXME: octets_per_byte. */
1080 hdr
= &elf_section_data (sec
->output_section
)->this_hdr
;
1081 if (hdr
->sh_offset
== (file_ptr
) -1)
1083 /* We must compress this section. Write output to the
1085 contents
= hdr
->contents
;
1086 if (contents
== NULL
)
1092 pos
= sec
->output_section
->filepos
+ sec
->output_offset
;
1093 if (bfd_seek (output_bfd
, pos
, SEEK_SET
) != 0)
1097 BFD_ASSERT (sec
== secinfo
->sec
);
1098 BFD_ASSERT (secinfo
== secinfo
->sinfo
->chain
);
1099 if (! sec_merge_emit (output_bfd
, secinfo
, contents
))
1105 /* Adjust an address in the SEC_MERGE section. Given OFFSET within
1106 *PSEC, this returns the new offset in the adjusted SEC_MERGE
1107 section and writes the new section back into *PSEC. */
1110 _bfd_merged_section_offset (bfd
*output_bfd ATTRIBUTE_UNUSED
, asection
**psec
,
1111 void *psecinfo
, bfd_vma offset
)
1113 struct sec_merge_sec_info
*secinfo
;
1114 asection
*sec
= *psec
;
1116 secinfo
= (struct sec_merge_sec_info
*) psecinfo
;
1121 if (offset
>= sec
->rawsize
)
1123 if (offset
> sec
->rawsize
)
1125 /* xgettext:c-format */
1126 (_("%pB: access beyond end of merged section (%" PRId64
")"),
1127 sec
->owner
, (int64_t) offset
);
1128 return secinfo
->first_str
? sec
->size
: 0;
1131 if (secinfo
->fast_state
!= 2)
1133 if (!secinfo
->fast_state
)
1134 prepare_offsetmap (secinfo
);
1135 if (secinfo
->fast_state
!= 2)
1139 long lb
= secinfo
->ofstolowbound
[offset
/ OFSDIV
];
1140 *psec
= secinfo
->reprsec
;
1142 /* No need for bounds checking on lb, as we've added a sentinel that's
1143 larger than any offset. */
1144 while (MAP_OFS(secinfo
, lb
) <= offset
)
1148 /*printf ("YYY (%s:%s):%u -> (%s):%u\n",
1149 sec->owner->filename, sec->name, (unsigned)offset,
1150 (*psec)->name, (unsigned)lb);*/
1151 return MAP_IDX(secinfo
, lb
) + offset
- MAP_OFS(secinfo
, lb
);
1154 /* Tidy up when done. */
1157 _bfd_merge_sections_free (void *xsinfo
)
1159 struct sec_merge_info
*sinfo
;
1161 for (sinfo
= (struct sec_merge_info
*) xsinfo
; sinfo
; sinfo
= sinfo
->next
)
1163 struct sec_merge_sec_info
*secinfo
;
1164 for (secinfo
= sinfo
->chain
; secinfo
; secinfo
= secinfo
->next
)
1166 free (secinfo
->ofstolowbound
);
1167 free (secinfo
->map
);
1168 free (secinfo
->map_ofs
);
1170 bfd_hash_table_free (&sinfo
->htab
->table
);