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 /* Next available index. */
78 /* First entity in the SEC_MERGE sections of this type. */
79 struct sec_merge_hash_entry
*first
;
80 /* Last entity in the SEC_MERGE sections of this type. */
81 struct sec_merge_hash_entry
*last
;
84 /* Are entries fixed size or zero terminated strings? */
86 /* struct-of-array variant of all entries in the hash-table: */
87 unsigned int nbuckets
;
88 /* We keep hash-code and length of entry together in a separate
89 array in such a way that it can be checked with just a single memory
90 reference. In this way we don't need indirect access to the entries
91 in the normal case. keys_lens[i] is 'hashcode << 32) | len' for entry
92 i (which is pointed to be values[i]). */
94 struct sec_merge_hash_entry
**values
;
97 /* True when given NEWCOUNT and NBUCKETS indicate that the hash table needs
99 #define NEEDS_RESIZE(newcount, nbuckets) ((newcount) > (nbuckets) / 3 * 2)
101 struct sec_merge_sec_info
;
103 /* Information per merged blob. This is the unit of merging and is
104 related to (multiple) input sections of similar characteristics
105 (alignment, entity size, strings or blobs). */
106 struct sec_merge_info
108 /* Chain of sec_merge_infos. */
109 struct sec_merge_info
*next
;
110 /* Chain of sec_merge_sec_infos. This first one will be the representative
111 section that conceptually collects all merged content. */
112 struct sec_merge_sec_info
*chain
;
113 struct sec_merge_sec_info
**last
;
114 /* A hash table used to hold section content. */
115 struct sec_merge_hash
*htab
;
118 /* Offset into input mergable sections are represented by this type.
119 Note how doesn't support crazy large mergable sections. */
120 typedef uint32_t mapofs_type
;
122 /* Given a sec_merge_sec_info S this gives the input offset of the IDX's
124 #define MAP_OFS(S,IDX) (S)->map_ofs[IDX]
125 /* And this gives the output offset (in the merged blob representing
127 #define MAP_IDX(S,IDX) (S)->map[IDX].idx
128 /* For quick lookup of output offset given an input offset we store
129 an array mapping intput-offset / OFSDIV to entry index.
130 16 is better than 8, 32 is roughly same as 16, but uses less memory, so
134 /* Information per input merge section. */
135 struct sec_merge_sec_info
137 /* Chain of sec_merge_sec_infos. */
138 struct sec_merge_sec_info
*next
;
139 /* The corresponding section. */
141 /* Pointer to merge_info pointing to us. */
143 /* The merge entity this is a part of. */
144 struct sec_merge_info
*sinfo
;
145 /* The section associated with sinfo (i.e. the representative section).
146 Same as sinfo->chain->sec, but faster to access in the hot function. */
148 /* First string in this section. */
149 struct sec_merge_hash_entry
*first_str
;
150 /* Sparse mapping from input offset to entry covering that offset: */
151 unsigned int noffsetmap
; /* Number of these mappings. */
152 mapofs_type
*map_ofs
; /* Input offset. */
154 struct sec_merge_hash_entry
*entry
; /* Covering hash entry ... */
155 bfd_size_type idx
; /* ... or destination offset. */
157 /* Quick access: index into map_ofs[]. ofstolowbound[o / OFSDIV]=I is
158 such that map_ofs[I] is the smallest offset higher that
159 rounddown(o, OFSDIV) (and hence I-1 is the largest entry whose offset is
160 smaller or equal to o/OFSDIV*OFSDIV). */
161 unsigned int *ofstolowbound
;
166 /* Given a merge hash table TABLE and a number of entries to be
167 ADDED, possibly resize the table for this to fit without further
171 sec_merge_maybe_resize (struct sec_merge_hash
*table
, unsigned added
)
173 struct bfd_hash_table
*bfdtab
= &table
->table
;
174 if (NEEDS_RESIZE (bfdtab
->count
+ added
, table
->nbuckets
))
177 unsigned long newnb
= table
->nbuckets
* 2;
178 struct sec_merge_hash_entry
**newv
;
182 while (NEEDS_RESIZE (bfdtab
->count
+ added
, newnb
))
189 alloc
= newnb
* sizeof (newl
[0]);
190 if (alloc
/ sizeof (newl
[0]) != newnb
)
192 newl
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
, alloc
);
195 memset (newl
, 0, alloc
);
196 alloc
= newnb
* sizeof (newv
[0]);
197 if (alloc
/ sizeof (newv
[0]) != newnb
)
199 newv
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
, alloc
);
202 memset (newv
, 0, alloc
);
204 for (i
= 0; i
< table
->nbuckets
; i
++)
206 struct sec_merge_hash_entry
*v
= table
->values
[i
];
209 uint32_t thishash
= table
->key_lens
[i
] >> 32;
210 unsigned idx
= thishash
& (newnb
- 1);
212 idx
= (idx
+ 1) & (newnb
- 1);
213 newl
[idx
] = table
->key_lens
[i
];
218 table
->key_lens
= newl
;
219 table
->values
= newv
;
220 table
->nbuckets
= newnb
;
225 /* Insert STRING (actually a byte blob of length LEN, with pre-computed
226 HASH and bucket _INDEX) into our hash TABLE. */
228 static struct sec_merge_hash_entry
*
229 sec_merge_hash_insert (struct sec_merge_hash
*table
,
231 uint64_t hash
, unsigned int len
, unsigned int _index
)
233 struct bfd_hash_table
*bfdtab
= &table
->table
;
234 struct sec_merge_hash_entry
*hashp
;
236 hashp
= (struct sec_merge_hash_entry
*)
237 bfd_hash_allocate (bfdtab
, len
+ sizeof (struct sec_merge_hash_entry
));
241 memcpy (hashp
->str
, string
, len
);
243 hashp
->alignment
= 0;
244 hashp
->u
.suffix
= NULL
;
246 // We must not need resizing, otherwise the estimation was wrong
247 BFD_ASSERT (!NEEDS_RESIZE (bfdtab
->count
+ 1, table
->nbuckets
));
249 table
->key_lens
[_index
] = (hash
<< 32) | (uint32_t)len
;
250 table
->values
[_index
] = hashp
;
255 /* Read four bytes from *STR, interpret it as 32bit unsigned little
256 endian value and return that. */
258 static inline uint32_t
259 hash_read32 (const char *str
)
262 /* All reasonable compilers will inline this memcpy and generate optimal
263 code on architectures that support unaligned (4-byte) accesses. */
265 #ifdef WORDS_BIGENDIAN
266 i
= (i
<< 24) | ((i
& 0xff00) << 8) | ((i
>> 8) & 0xff00) | (i
>> 24);
271 /* Calculate and return a hashvalue of the bytes at STR[0..LEN-1].
272 All non-zero lengths and all alignments are supported.
274 This is somewhat similar to xxh3 (of xxhash), but restricted to 32bit.
275 On cc1 strings this has quite similar statistic properties, and we
276 don't need to jump through hoops to get fast 64x64->128 mults,
277 or 64bit arith on 32 bit hosts. We also don't care for seeds
278 or secrets. They improve mixing very little. */
281 hash_blob (const char *str
, unsigned int len
)
284 uint32_t mul
= (1 << 0) + (1 << 2) + (1 << 3) + (1 << 5) + (1 << 7);
285 mul
+= (1 << 11) + (1 << 13) + (1 << 17) + (0 << 19) + (1 << 23) + (1 << 29);
289 uint32_t acc
= len
* 0x9e3779b1;
292 uint32_t i1
= hash_read32 (str
) ^ (0x396cfeb8 + 1*len
);
293 uint32_t i2
= hash_read32 (str
+ 4) ^ (0xbe4ba423 + 1*len
);
296 uint64_t m
= (uint64_t)i1
* i2
;
297 acc
+= (uint32_t)m
^ (uint32_t)(m
>> 32);
299 acc
= acc
^ (acc
>> 7);
300 uint64_t r
= (uint64_t)mul
* acc
;
301 ret
= (uint32_t)r
^ (uint32_t)(r
>> 32);
307 uint32_t i1
= hash_read32 (str
);
308 uint32_t i2
= hash_read32 (str
+ len
- 4);
309 i1
= ((i1
+ len
) ^ (i1
>> 7));
311 uint64_t r
= (uint64_t)mul
* i1
+ i2
;
312 ret
+= r
^ (r
>> 32);
316 /* Cleverly read in 1 to 3 bytes without further conditionals. */
317 unsigned char c1
= str
[0];
318 unsigned char c2
= str
[len
>> 1];
319 unsigned char c3
= str
[len
- 1];
320 uint32_t i1
= ((uint32_t)c1
<< 16) | ((uint32_t)c2
<< 24)
321 | ((uint32_t) c3
) | (len
<< 8);
323 uint64_t r
= (uint64_t)mul
* i1
;
324 ret
+= r
^ (r
>> 32);
330 /* Given a hash TABLE, return the hash of STRING (a blob described
331 according to info in TABLE, either a character string, or some fixed
332 size entity) and set *PLEN to the length of this blob. */
335 hashit (struct sec_merge_hash
*table
, const char *string
, unsigned int *plen
)
337 const unsigned char *s
;
341 s
= (const unsigned char *) string
;
344 if (table
->entsize
== 1)
345 len
= strlen (string
) + 1;
351 for (i
= 0; i
< table
->entsize
; ++i
)
354 if (i
== table
->entsize
)
359 len
*= table
->entsize
;
360 len
+= table
->entsize
;
364 len
= table
->entsize
;
365 hash
= hash_blob (string
, len
);
370 /* Lookup or insert a blob STRING (of length LEN, precomputed HASH and
371 input ALIGNMENT) into TABLE. Return the found or new hash table entry. */
373 static struct sec_merge_hash_entry
*
374 sec_merge_hash_lookup (struct sec_merge_hash
*table
, const char *string
,
375 unsigned int len
, uint64_t hash
,
376 unsigned int alignment
)
378 struct sec_merge_hash_entry
*hashp
;
381 /*printf ("YYY insert 0x%x into %u buckets (%s)\n",
382 (unsigned)hash, (unsigned)table->nbuckets, string);*/
383 uint64_t *key_lens
= table
->key_lens
;
384 struct sec_merge_hash_entry
**values
= table
->values
;
385 uint64_t hlen
= (hash
<< 32) | (uint32_t)len
;
386 unsigned int nbuckets
= table
->nbuckets
;
387 _index
= hash
& (nbuckets
- 1);
390 uint64_t candlen
= key_lens
[_index
];
392 && !memcmp (values
[_index
]->str
, string
, len
))
394 hashp
= values
[_index
];
395 if (hashp
->alignment
< alignment
)
396 hashp
->alignment
= alignment
;
399 if (!(candlen
& (uint32_t)-1))
401 _index
= (_index
+ 1) & (nbuckets
- 1);
404 hashp
= sec_merge_hash_insert (table
, string
, hash
, len
, _index
);
407 hashp
->alignment
= alignment
;
410 BFD_ASSERT (table
->size
== table
->table
.count
);
411 if (table
->first
== NULL
)
412 table
->first
= hashp
;
414 table
->last
->next
= hashp
;
420 /* Create a new hash table. */
422 static struct sec_merge_hash
*
423 sec_merge_init (unsigned int entsize
, bool strings
)
425 struct sec_merge_hash
*table
;
427 table
= (struct sec_merge_hash
*) bfd_malloc (sizeof (struct sec_merge_hash
));
431 if (! bfd_hash_table_init_n (&table
->table
, NULL
,
432 sizeof (struct sec_merge_hash_entry
), 0x2000))
441 table
->entsize
= entsize
;
442 table
->strings
= strings
;
444 table
->nbuckets
= 0x2000;
445 table
->key_lens
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
,
446 table
->nbuckets
* sizeof (table
->key_lens
[0]));
447 memset (table
->key_lens
, 0, table
->nbuckets
* sizeof (table
->key_lens
[0]));
448 table
->values
= objalloc_alloc ((struct objalloc
*) table
->table
.memory
,
449 table
->nbuckets
* sizeof (table
->values
[0]));
450 memset (table
->values
, 0, table
->nbuckets
* sizeof (table
->values
[0]));
455 /* Append the tuple of input-offset O corresponding
456 to hash table ENTRY into SECINFO, such that we later may lookup the
460 append_offsetmap (struct sec_merge_sec_info
*secinfo
,
462 struct sec_merge_hash_entry
*entry
)
464 if ((secinfo
->noffsetmap
& 2047) == 0)
467 amt
= (secinfo
->noffsetmap
+ 2048);
468 secinfo
->map_ofs
= bfd_realloc (secinfo
->map_ofs
,
469 amt
* sizeof(secinfo
->map_ofs
[0]));
470 if (!secinfo
->map_ofs
)
472 secinfo
->map
= bfd_realloc (secinfo
->map
, amt
* sizeof(secinfo
->map
[0]));
476 unsigned int i
= secinfo
->noffsetmap
++;
477 MAP_OFS(secinfo
, i
) = o
;
478 secinfo
->map
[i
].entry
= entry
;
482 /* Prepare the input-offset-to-entry tables after output offsets are
486 prepare_offsetmap (struct sec_merge_sec_info
*secinfo
)
488 unsigned int noffsetmap
= secinfo
->noffsetmap
;
490 bfd_size_type l
, sz
, amt
;
492 secinfo
->fast_state
= 1;
494 for (i
= 0; i
< noffsetmap
; i
++)
495 MAP_IDX(secinfo
, i
) = secinfo
->map
[i
].entry
->u
.index
;
497 sz
= secinfo
->sec
->rawsize
;
498 amt
= (sz
/ OFSDIV
+ 1) * sizeof (secinfo
->ofstolowbound
[0]);
499 secinfo
->ofstolowbound
= bfd_zmalloc (amt
);
500 if (!secinfo
->ofstolowbound
)
502 for (l
= lbi
= 0; l
< sz
; l
+= OFSDIV
)
504 /* No need for bounds checking on lbi, as we've added a sentinel that's
505 larger than any offset. */
506 while (MAP_OFS(secinfo
, lbi
) <= l
)
508 //BFD_ASSERT ((l / OFSDIV) <= (i / OFSDIV));
509 secinfo
->ofstolowbound
[l
/ OFSDIV
] = lbi
;
511 secinfo
->fast_state
= 2;
515 sec_merge_emit (bfd
*abfd
, struct sec_merge_sec_info
*secinfo
,
516 unsigned char *contents
)
518 struct sec_merge_hash_entry
*entry
= secinfo
->first_str
;
519 asection
*sec
= secinfo
->sec
;
520 file_ptr offset
= sec
->output_offset
;
522 bfd_size_type off
= 0;
523 unsigned int opb
= bfd_octets_per_byte (abfd
, sec
);
524 int alignment_power
= sec
->output_section
->alignment_power
* opb
;
525 bfd_size_type pad_len
; /* Octets. */
527 /* FIXME: If alignment_power is 0 then really we should scan the
528 entry list for the largest required alignment and use that. */
529 pad_len
= alignment_power
? ((bfd_size_type
) 1 << alignment_power
) : 16;
531 pad
= (char *) bfd_zmalloc (pad_len
);
535 for (; entry
!= NULL
; entry
= entry
->next
)
542 BFD_ASSERT (entry
->alignment
);
543 len
= -off
& (entry
->alignment
- 1);
546 BFD_ASSERT (len
<= pad_len
);
549 memcpy (contents
+ offset
, pad
, len
);
552 else if (bfd_write (pad
, len
, abfd
) != len
)
562 memcpy (contents
+ offset
, str
, len
);
565 else if (bfd_write (str
, len
, abfd
) != len
)
572 /* Trailing alignment needed? */
573 off
= sec
->size
- off
;
576 BFD_ASSERT (off
<= pad_len
);
578 memcpy (contents
+ offset
, pad
, off
);
579 else if (bfd_write (pad
, off
, abfd
) != off
)
591 /* Register a SEC_MERGE section as a candidate for merging.
592 This function is called for all non-dynamic SEC_MERGE input sections. */
595 _bfd_add_merge_section (bfd
*abfd
, void **psinfo
, asection
*sec
,
598 struct sec_merge_info
*sinfo
;
599 struct sec_merge_sec_info
*secinfo
;
601 unsigned int alignment_power
; /* Octets. */
602 unsigned int align
; /* Octets. */
603 unsigned int opb
= bfd_octets_per_byte (abfd
, sec
);
605 if ((abfd
->flags
& DYNAMIC
) != 0
606 || (sec
->flags
& SEC_MERGE
) == 0)
610 || (sec
->flags
& SEC_EXCLUDE
) != 0
611 || sec
->entsize
== 0)
614 if (sec
->size
% sec
->entsize
!= 0)
617 if ((sec
->flags
& SEC_RELOC
) != 0)
619 /* We aren't prepared to handle relocations in merged sections. */
623 if (sec
->size
> (mapofs_type
)-1)
625 /* Input offsets must be representable by mapofs_type. */
632 alignment_power
= sec
->alignment_power
* opb
;
633 if (alignment_power
>= sizeof (align
) * CHAR_BIT
)
636 align
= 1u << alignment_power
;
637 if ((sec
->entsize
< align
638 && ((sec
->entsize
& (sec
->entsize
- 1))
639 || !(sec
->flags
& SEC_STRINGS
)))
640 || (sec
->entsize
> align
641 && (sec
->entsize
& (align
- 1))))
643 /* Sanity check. If string character size is smaller than
644 alignment, then we require character size to be a power
645 of 2, otherwise character size must be integer multiple
646 of alignment. For non-string constants, alignment must
647 be smaller than or equal to entity size and entity size
648 must be integer multiple of alignment. */
652 /* Initialize the descriptor for this input section. */
654 *psecinfo
= secinfo
= bfd_zalloc (abfd
, sizeof (*secinfo
));
655 if (*psecinfo
== NULL
)
659 secinfo
->psecinfo
= psecinfo
;
661 /* Search for a matching output merged section. */
662 for (sinfo
= (struct sec_merge_info
*) *psinfo
; sinfo
; sinfo
= sinfo
->next
)
664 && (repr
= sinfo
->chain
->sec
)
665 && ! ((repr
->flags
^ sec
->flags
) & (SEC_MERGE
| SEC_STRINGS
))
666 && repr
->entsize
== sec
->entsize
667 && repr
->alignment_power
== sec
->alignment_power
668 && repr
->output_section
== sec
->output_section
)
673 /* Initialize the information we need to keep track of. */
674 sinfo
= (struct sec_merge_info
*)
675 bfd_alloc (abfd
, sizeof (struct sec_merge_info
));
678 sinfo
->next
= (struct sec_merge_info
*) *psinfo
;
680 sinfo
->last
= &sinfo
->chain
;
682 sinfo
->htab
= sec_merge_init (sec
->entsize
, (sec
->flags
& SEC_STRINGS
));
683 if (sinfo
->htab
== NULL
)
687 *sinfo
->last
= secinfo
;
688 sinfo
->last
= &secinfo
->next
;
690 secinfo
->sinfo
= sinfo
;
691 secinfo
->reprsec
= sinfo
->chain
->sec
;
700 /* Record one whole input section (described by SECINFO) into the hash table
704 record_section (struct sec_merge_info
*sinfo
,
705 struct sec_merge_sec_info
*secinfo
)
707 asection
*sec
= secinfo
->sec
;
708 struct sec_merge_hash_entry
*entry
;
709 unsigned char *p
, *end
;
710 bfd_vma mask
, eltalign
;
717 if (sec
->flags
& SEC_STRINGS
)
718 /* Some versions of gcc may emit a string without a zero terminator.
719 See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html
720 Allocate space for an extra zero. */
722 contents
= bfd_malloc (amt
);
726 /* Slurp in all section contents (possibly decompressing it). */
727 sec
->rawsize
= sec
->size
;
728 if (sec
->flags
& SEC_STRINGS
)
729 memset (contents
+ sec
->size
, 0, sec
->entsize
);
730 if (! bfd_get_full_section_contents (sec
->owner
, sec
, &contents
))
733 /* Now populate the hash table and offset mapping. */
735 /* Presize the hash table for what we're going to add. We overestimate
736 quite a bit, but if it turns out to be too much then other sections
737 merged into this area will make use of that as well. */
738 if (!sec_merge_maybe_resize (sinfo
->htab
, 1 + sec
->size
/ 2))
740 bfd_set_error (bfd_error_no_memory
);
744 /* Walk through the contents, calculate hashes and length of all
745 blobs (strings or fixed-size entries) we find and fill the
746 hash and offset tables. */
747 align
= sec
->alignment_power
;
748 mask
= ((bfd_vma
) 1 << align
) - 1;
749 end
= contents
+ sec
->size
;
750 for (p
= contents
; p
< end
;)
753 uint32_t hash
= hashit (sinfo
->htab
, (char*) p
, &len
);
754 unsigned int ofs
= p
- contents
;
756 eltalign
= ((eltalign
^ (eltalign
- 1)) + 1) >> 1;
757 if (!eltalign
|| eltalign
> mask
)
759 entry
= sec_merge_hash_lookup (sinfo
->htab
, (char *) p
, len
, hash
,
760 (unsigned) eltalign
);
763 if (! append_offsetmap (secinfo
, ofs
, entry
))
768 /* Add a sentinel element that's conceptually behind all others. */
769 append_offsetmap (secinfo
, sec
->size
, NULL
);
770 /* But don't count it. */
771 secinfo
->noffsetmap
--;
776 /* We allocate the ofsmap arrays in blocks of 2048 elements.
777 In case we have very many small input files/sections,
778 this might waste large amounts of memory, so reallocate these
779 arrays here to their true size. */
780 amt
= secinfo
->noffsetmap
+ 1;
781 tmpptr
= bfd_realloc (secinfo
->map
, amt
* sizeof(secinfo
->map
[0]));
783 secinfo
->map
= tmpptr
;
784 tmpptr
= bfd_realloc (secinfo
->map_ofs
, amt
* sizeof(secinfo
->map_ofs
[0]));
786 secinfo
->map_ofs
= tmpptr
;
788 /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
789 (unsigned)secinfo->noffsetmap);*/
796 for (secinfo
= sinfo
->chain
; secinfo
; secinfo
= secinfo
->next
)
797 *secinfo
->psecinfo
= NULL
;
801 /* qsort comparison function. Won't ever return zero as all entries
802 differ, so there is no issue with qsort stability here. */
805 strrevcmp (const void *a
, const void *b
)
807 struct sec_merge_hash_entry
*A
= *(struct sec_merge_hash_entry
**) a
;
808 struct sec_merge_hash_entry
*B
= *(struct sec_merge_hash_entry
**) b
;
809 unsigned int lenA
= A
->len
;
810 unsigned int lenB
= B
->len
;
811 const unsigned char *s
= (const unsigned char *) A
->str
+ lenA
- 1;
812 const unsigned char *t
= (const unsigned char *) B
->str
+ lenB
- 1;
813 int l
= lenA
< lenB
? lenA
: lenB
;
818 return (int) *s
- (int) *t
;
826 /* Like strrevcmp, but for the case where all strings have the same
827 alignment > entsize. */
830 strrevcmp_align (const void *a
, const void *b
)
832 struct sec_merge_hash_entry
*A
= *(struct sec_merge_hash_entry
**) a
;
833 struct sec_merge_hash_entry
*B
= *(struct sec_merge_hash_entry
**) b
;
834 unsigned int lenA
= A
->len
;
835 unsigned int lenB
= B
->len
;
836 const unsigned char *s
= (const unsigned char *) A
->str
+ lenA
- 1;
837 const unsigned char *t
= (const unsigned char *) B
->str
+ lenB
- 1;
838 int l
= lenA
< lenB
? lenA
: lenB
;
839 int tail_align
= (lenA
& (A
->alignment
- 1)) - (lenB
& (A
->alignment
- 1));
847 return (int) *s
- (int) *t
;
856 is_suffix (const struct sec_merge_hash_entry
*A
,
857 const struct sec_merge_hash_entry
*B
)
859 if (A
->len
<= B
->len
)
860 /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
861 not to be equal by the hash table. */
864 return memcmp (A
->str
+ (A
->len
- B
->len
),
865 B
->str
, B
->len
) == 0;
868 /* This is a helper function for _bfd_merge_sections. It attempts to
869 merge strings matching suffixes of longer strings. */
870 static struct sec_merge_sec_info
*
871 merge_strings (struct sec_merge_info
*sinfo
)
873 struct sec_merge_hash_entry
**array
, **a
, *e
;
874 struct sec_merge_sec_info
*secinfo
;
875 bfd_size_type size
, amt
;
876 unsigned int alignment
= 0;
878 /* Now sort the strings */
879 amt
= sinfo
->htab
->size
* sizeof (struct sec_merge_hash_entry
*);
880 array
= (struct sec_merge_hash_entry
**) bfd_malloc (amt
);
884 for (e
= sinfo
->htab
->first
, a
= array
; e
; e
= e
->next
)
888 /* Adjust the length to not include the zero terminator. */
889 e
->len
-= sinfo
->htab
->entsize
;
890 if (alignment
!= e
->alignment
)
893 alignment
= e
->alignment
;
895 alignment
= (unsigned) -1;
899 sinfo
->htab
->size
= a
- array
;
900 if (sinfo
->htab
->size
!= 0)
902 qsort (array
, (size_t) sinfo
->htab
->size
,
903 sizeof (struct sec_merge_hash_entry
*),
904 (alignment
!= (unsigned) -1 && alignment
> sinfo
->htab
->entsize
905 ? strrevcmp_align
: strrevcmp
));
907 /* Loop over the sorted array and merge suffixes */
909 e
->len
+= sinfo
->htab
->entsize
;
912 struct sec_merge_hash_entry
*cmp
= *a
;
914 cmp
->len
+= sinfo
->htab
->entsize
;
915 if (e
->alignment
>= cmp
->alignment
916 && !((e
->len
- cmp
->len
) & (cmp
->alignment
- 1))
917 && is_suffix (e
, cmp
))
929 /* Now assign positions to the strings we want to keep. */
931 secinfo
= sinfo
->chain
;
932 for (e
= sinfo
->htab
->first
; e
; e
= e
->next
)
936 size
= (size
+ e
->alignment
- 1) & ~((bfd_vma
) e
->alignment
- 1);
941 secinfo
->sec
->size
= size
;
943 /* And now adjust the rest, removing them from the chain (but not hashtable)
945 for (a
= &sinfo
->htab
->first
, e
= *a
; e
; e
= e
->next
)
953 e
->alignment
= e
->u
.suffix
->alignment
;
954 e
->u
.index
= e
->u
.suffix
->u
.index
+ (e
->u
.suffix
->len
- e
->len
);
958 BFD_ASSERT (!secinfo
->first_str
);
959 secinfo
->first_str
= sinfo
->htab
->first
;
964 /* This function is called once after all SEC_MERGE sections are registered
965 with _bfd_merge_section. */
968 _bfd_merge_sections (bfd
*abfd
,
969 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
971 void (*remove_hook
) (bfd
*, asection
*))
973 struct sec_merge_info
*sinfo
;
975 for (sinfo
= (struct sec_merge_info
*) xsinfo
; sinfo
; sinfo
= sinfo
->next
)
977 struct sec_merge_sec_info
*secinfo
;
978 bfd_size_type align
; /* Bytes. */
983 /* Record the sections into the hash table. */
985 for (secinfo
= sinfo
->chain
; secinfo
; secinfo
= secinfo
->next
)
986 if (secinfo
->sec
->flags
& SEC_EXCLUDE
)
988 *secinfo
->psecinfo
= NULL
;
990 (*remove_hook
) (abfd
, secinfo
->sec
);
994 if (!record_section (sinfo
, secinfo
))
998 unsigned int opb
= bfd_octets_per_byte (abfd
, secinfo
->sec
);
1000 align
= (bfd_size_type
) 1 << secinfo
->sec
->alignment_power
;
1001 if (((secinfo
->sec
->size
/ opb
) & (align
- 1)) != 0)
1006 if (sinfo
->htab
->first
== NULL
)
1009 if (sinfo
->htab
->strings
)
1011 secinfo
= merge_strings (sinfo
);
1017 struct sec_merge_hash_entry
*e
= sinfo
->htab
->first
;
1018 bfd_size_type size
= 0; /* Octets. */
1020 /* Things are much simpler for non-strings.
1021 Just assign them slots in the section. */
1022 secinfo
= sinfo
->chain
;
1023 BFD_ASSERT (!secinfo
->first_str
);
1024 secinfo
->first_str
= e
;
1025 for (e
= sinfo
->htab
->first
; e
; e
= e
->next
)
1029 size
= (size
+ e
->alignment
- 1)
1030 & ~((bfd_vma
) e
->alignment
- 1);
1035 secinfo
->sec
->size
= size
;
1038 /* If the input sections were padded according to their alignments,
1039 then pad the output too. */
1041 secinfo
->sec
->size
= (secinfo
->sec
->size
+ align
- 1) & -align
;
1043 /* Finally remove all input sections which have not made it into
1044 the hash table at all. */
1045 for (secinfo
= sinfo
->chain
; secinfo
; secinfo
= secinfo
->next
)
1046 if (secinfo
->first_str
== NULL
)
1047 secinfo
->sec
->flags
|= SEC_EXCLUDE
| SEC_KEEP
;
1053 /* Write out the merged section. */
1056 _bfd_write_merged_section (bfd
*output_bfd
, asection
*sec
, void *psecinfo
)
1058 struct sec_merge_sec_info
*secinfo
;
1060 unsigned char *contents
;
1061 Elf_Internal_Shdr
*hdr
;
1063 secinfo
= (struct sec_merge_sec_info
*) psecinfo
;
1068 if (secinfo
->first_str
== NULL
)
1071 /* FIXME: octets_per_byte. */
1072 hdr
= &elf_section_data (sec
->output_section
)->this_hdr
;
1073 if (hdr
->sh_offset
== (file_ptr
) -1)
1075 /* We must compress this section. Write output to the
1077 contents
= hdr
->contents
;
1078 if (contents
== NULL
)
1084 pos
= sec
->output_section
->filepos
+ sec
->output_offset
;
1085 if (bfd_seek (output_bfd
, pos
, SEEK_SET
) != 0)
1089 BFD_ASSERT (sec
== secinfo
->sec
);
1090 BFD_ASSERT (secinfo
== secinfo
->sinfo
->chain
);
1091 if (! sec_merge_emit (output_bfd
, secinfo
, contents
))
1097 /* Adjust an address in the SEC_MERGE section. Given OFFSET within
1098 *PSEC, this returns the new offset in the adjusted SEC_MERGE
1099 section and writes the new section back into *PSEC. */
1102 _bfd_merged_section_offset (bfd
*output_bfd ATTRIBUTE_UNUSED
, asection
**psec
,
1103 void *psecinfo
, bfd_vma offset
)
1105 struct sec_merge_sec_info
*secinfo
;
1106 asection
*sec
= *psec
;
1108 secinfo
= (struct sec_merge_sec_info
*) psecinfo
;
1113 if (offset
>= sec
->rawsize
)
1115 if (offset
> sec
->rawsize
)
1117 /* xgettext:c-format */
1118 (_("%pB: access beyond end of merged section (%" PRId64
")"),
1119 sec
->owner
, (int64_t) offset
);
1120 return secinfo
->first_str
? sec
->size
: 0;
1123 if (secinfo
->fast_state
!= 2)
1125 if (!secinfo
->fast_state
)
1126 prepare_offsetmap (secinfo
);
1127 if (secinfo
->fast_state
!= 2)
1131 long lb
= secinfo
->ofstolowbound
[offset
/ OFSDIV
];
1132 *psec
= secinfo
->reprsec
;
1134 /* No need for bounds checking on lb, as we've added a sentinel that's
1135 larger than any offset. */
1136 while (MAP_OFS(secinfo
, lb
) <= offset
)
1140 /*printf ("YYY (%s:%s):%u -> (%s):%u\n",
1141 sec->owner->filename, sec->name, (unsigned)offset,
1142 (*psec)->name, (unsigned)lb);*/
1143 return MAP_IDX(secinfo
, lb
) + offset
- MAP_OFS(secinfo
, lb
);
1146 /* Tidy up when done. */
1149 _bfd_merge_sections_free (void *xsinfo
)
1151 struct sec_merge_info
*sinfo
;
1153 for (sinfo
= (struct sec_merge_info
*) xsinfo
; sinfo
; sinfo
= sinfo
->next
)
1155 struct sec_merge_sec_info
*secinfo
;
1156 for (secinfo
= sinfo
->chain
; secinfo
; secinfo
= secinfo
->next
)
1158 free (secinfo
->ofstolowbound
);
1159 free (secinfo
->map
);
1160 free (secinfo
->map_ofs
);
1162 bfd_hash_table_free (&sinfo
->htab
->table
);