RISC-V: Don't report warnings when linking different privileged spec objects.
[binutils-gdb.git] / bfd / merge.c
blob947f2ce78f24d9fe6338cd73716f9968e0b218e5
1 /* SEC_MERGE support.
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. */
26 #include "sysdep.h"
27 #include <limits.h>
28 #include "bfd.h"
29 #include "elf-bfd.h"
30 #include "libbfd.h"
31 #include "objalloc.h"
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
42 middle of an entry).
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
48 search from there. */
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. */
55 unsigned int len;
56 /* Start of this string needs to be aligned to
57 alignment octets (not 1 << align). */
58 unsigned int alignment;
59 union
61 /* Index within the merged section. */
62 bfd_size_type index;
63 /* Entry this is a suffix of (if alignment is 0). */
64 struct sec_merge_hash_entry *suffix;
65 } u;
66 /* Next entity in the hash table (in order of entering). */
67 struct sec_merge_hash_entry *next;
68 char str[1];
71 /* The section merge hash table. */
73 struct sec_merge_hash
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;
80 /* Entity size. */
81 unsigned int entsize;
82 /* Are entries fixed size or zero terminated strings? */
83 bool 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]). */
91 uint64_t *key_lens;
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
117 recorded entry. */
118 #define MAP_OFS(S,IDX) (S)->map_ofs[IDX]
119 /* And this gives the output offset (in the merged blob representing
120 this S. */
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
125 we use that. */
126 #define OFSDIV 32
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. */
134 asection *sec;
135 /* Pointer to merge_info pointing to us. */
136 void **psecinfo;
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. */
141 asection *reprsec;
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. */
147 union {
148 struct sec_merge_hash_entry *entry; /* Covering hash entry ... */
149 bfd_size_type idx; /* ... or destination offset. */
150 } *map;
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;
156 int fast_state;
160 /* True when COUNT+ADDED and NBUCKETS indicate that the hash table
161 needs resizing. */
163 static inline bool
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. */
179 static bool
180 sec_merge_resize (struct sec_merge_hash *table, unsigned added)
182 struct bfd_hash_table *bfdtab = &table->table;
183 unsigned i;
184 unsigned long newnb = table->nbuckets;
185 struct sec_merge_hash_entry **newv;
186 uint64_t *newl;
187 unsigned long alloc;
191 if (newnb >> (8 * sizeof(mapofs_type) - 1))
192 return false;
193 newnb *= 2;
195 while (needs_resize (bfdtab->count, added, newnb));
197 alloc = newnb * sizeof (newl[0]);
198 if (alloc / sizeof (newl[0]) != newnb)
199 return false;
200 newl = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
201 if (newl == NULL)
202 return false;
203 memset (newl, 0, alloc);
204 alloc = newnb * sizeof (newv[0]);
205 if (alloc / sizeof (newv[0]) != newnb)
206 return false;
207 newv = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
208 if (newv == NULL)
209 return false;
210 memset (newv, 0, alloc);
212 for (i = 0; i < table->nbuckets; i++)
214 struct sec_merge_hash_entry *v = table->values[i];
215 if (v)
217 uint32_t thishash = table->key_lens[i] >> 32;
218 unsigned idx = thishash & (newnb - 1);
219 while (newv[idx])
220 idx = (idx + 1) & (newnb - 1);
221 newl[idx] = table->key_lens[i];
222 newv[idx] = v;
226 table->key_lens = newl;
227 table->values = newv;
228 table->nbuckets = newnb;
229 return true;
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,
237 const char *string,
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));
245 if (hashp == NULL)
246 return NULL;
248 memcpy (hashp->str, string, len);
249 hashp->len = len;
250 hashp->alignment = 0;
251 hashp->u.suffix = NULL;
252 hashp->next = NULL;
254 if (needs_resize (bfdtab->count, 1, table->nbuckets))
256 if (!sec_merge_resize (table, 1))
257 return NULL;
258 uint64_t *key_lens = table->key_lens;
259 unsigned int nbuckets = table->nbuckets;
260 _index = hash & (nbuckets - 1);
261 while (1)
263 uint64_t candlen = key_lens[_index];
264 if (!(candlen & (uint32_t)-1))
265 break;
266 _index = (_index + 1) & (nbuckets - 1);
270 bfdtab->count++;
271 table->key_lens[_index] = (hash << 32) | (uint32_t)len;
272 table->values[_index] = hashp;
274 return 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)
283 uint32_t i;
284 /* All reasonable compilers will inline this memcpy and generate optimal
285 code on architectures that support unaligned (4-byte) accesses. */
286 memcpy(&i, str, 4);
287 #ifdef WORDS_BIGENDIAN
288 i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
289 #endif
290 return i;
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. */
302 static uint32_t
303 hash_blob (const char *str, unsigned int len)
305 uint32_t ret = 0;
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);
308 mul += (1u << 31);
309 if (len >= 8)
311 uint32_t acc = len * 0x9e3779b1;
312 while (len >= 8)
314 uint32_t i1 = hash_read32 (str) ^ (0x396cfeb8 + 1*len);
315 uint32_t i2 = hash_read32 (str + 4) ^ (0xbe4ba423 + 1*len);
316 str += 8;
317 len -= 8;
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);
324 if (len == 0)
325 goto end;
327 if (len >= 4)
329 uint32_t i1 = hash_read32 (str);
330 uint32_t i2 = hash_read32 (str + len - 4);
331 i1 = ((i1 + len) ^ (i1 >> 7));
332 i2 = i2 ^ (i2 >> 7);
333 uint64_t r = (uint64_t)mul * i1 + i2;
334 ret += r ^ (r >> 32);
336 else
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);
344 i1 = i1 ^ (i1 >> 7);
345 uint64_t r = (uint64_t)mul * i1;
346 ret += r ^ (r >> 32);
348 end:
349 return ret;
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. */
356 static uint32_t
357 hashit (struct sec_merge_hash *table, const char *string, unsigned int *plen)
359 const unsigned char *s;
360 uint32_t hash;
361 unsigned int len, i;
363 s = (const unsigned char *) string;
364 if (table->strings)
366 if (table->entsize == 1)
367 len = strlen (string) + 1;
368 else
370 len = 0;
371 for (;;)
373 for (i = 0; i < table->entsize; ++i)
374 if (s[i] != '\0')
375 break;
376 if (i == table->entsize)
377 break;
378 s += table->entsize;
379 ++len;
381 len *= table->entsize;
382 len += table->entsize;
385 else
386 len = table->entsize;
387 hash = hash_blob (string, len);
388 *plen = len;
389 return hash;
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;
401 unsigned int _index;
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);
410 while (1)
412 uint64_t candlen = key_lens[_index];
413 if (candlen == hlen
414 && !memcmp (values[_index]->str, string, len))
416 hashp = values[_index];
417 if (hashp->alignment < alignment)
418 hashp->alignment = alignment;
419 return hashp;
421 if (!(candlen & (uint32_t)-1))
422 break;
423 _index = (_index + 1) & (nbuckets - 1);
426 hashp = sec_merge_hash_insert (table, string, hash, len, _index);
427 if (hashp == NULL)
428 return NULL;
429 hashp->alignment = alignment;
431 if (table->first == NULL)
432 table->first = hashp;
433 else
434 table->last->next = hashp;
435 table->last = hashp;
437 return 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));
448 if (table == NULL)
449 return NULL;
451 if (! bfd_hash_table_init_n (&table->table, NULL,
452 sizeof (struct sec_merge_hash_entry), 0x2000))
454 free (table);
455 return NULL;
458 table->first = NULL;
459 table->last = NULL;
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]));
471 return table;
474 /* Append the tuple of input-offset O corresponding
475 to hash table ENTRY into SECINFO, such that we later may lookup the
476 entry just by O. */
478 static bool
479 append_offsetmap (struct sec_merge_sec_info *secinfo,
480 mapofs_type o,
481 struct sec_merge_hash_entry *entry)
483 if ((secinfo->noffsetmap & 2047) == 0)
485 bfd_size_type amt;
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)
490 return false;
491 secinfo->map = bfd_realloc (secinfo->map, amt * sizeof(secinfo->map[0]));
492 if (!secinfo->map)
493 return false;
495 unsigned int i = secinfo->noffsetmap++;
496 MAP_OFS(secinfo, i) = o;
497 secinfo->map[i].entry = entry;
498 return true;
501 /* Prepare the input-offset-to-entry tables after output offsets are
502 determined. */
504 static void
505 prepare_offsetmap (struct sec_merge_sec_info *secinfo)
507 unsigned int noffsetmap = secinfo->noffsetmap;
508 unsigned int i, lbi;
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)
520 return;
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)
526 lbi++;
527 //BFD_ASSERT ((l / OFSDIV) <= (i / OFSDIV));
528 secinfo->ofstolowbound[l / OFSDIV] = lbi;
530 secinfo->fast_state = 2;
533 static bool
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;
540 char *pad = NULL;
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);
551 if (pad == NULL)
552 return false;
554 for (; entry != NULL; entry = entry->next)
556 const char *str;
557 bfd_size_type len;
559 if (!entry->len)
560 continue;
561 BFD_ASSERT (entry->alignment);
562 len = -off & (entry->alignment - 1);
563 if (len != 0)
565 BFD_ASSERT (len <= pad_len);
566 if (contents)
568 memcpy (contents + offset, pad, len);
569 offset += len;
571 else if (bfd_write (pad, len, abfd) != len)
572 goto err;
573 off += len;
576 str = entry->str;
577 len = entry->len;
579 if (contents)
581 memcpy (contents + offset, str, len);
582 offset += len;
584 else if (bfd_write (str, len, abfd) != len)
585 goto err;
587 off += len;
589 BFD_ASSERT (!entry);
591 /* Trailing alignment needed? */
592 off = sec->size - off;
593 if (1 && off != 0)
595 BFD_ASSERT (off <= pad_len);
596 if (contents)
597 memcpy (contents + offset, pad, off);
598 else if (bfd_write (pad, off, abfd) != off)
599 goto err;
602 free (pad);
603 return true;
605 err:
606 free (pad);
607 return false;
610 /* Register a SEC_MERGE section as a candidate for merging.
611 This function is called for all non-dynamic SEC_MERGE input sections. */
613 bool
614 _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
615 void **psecinfo)
617 struct sec_merge_info *sinfo;
618 struct sec_merge_sec_info *secinfo;
619 asection *repr;
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)
626 abort ();
628 if (sec->size == 0
629 || (sec->flags & SEC_EXCLUDE) != 0
630 || (sec->flags & SEC_HAS_CONTENTS) == 0
631 || sec->entsize == 0)
632 return true;
634 if (sec->size % sec->entsize != 0)
635 return true;
637 if ((sec->flags & SEC_RELOC) != 0)
639 /* We aren't prepared to handle relocations in merged sections. */
640 return true;
643 if (sec->size > (mapofs_type)-1)
645 /* Input offsets must be representable by mapofs_type. */
646 return true;
649 #ifndef CHAR_BIT
650 #define CHAR_BIT 8
651 #endif
652 alignment_power = sec->alignment_power * opb;
653 if (alignment_power >= sizeof (align) * CHAR_BIT)
654 return true;
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. */
669 return true;
672 /* Initialize the descriptor for this input section. */
674 *psecinfo = secinfo = bfd_zalloc (abfd, sizeof (*secinfo));
675 if (*psecinfo == NULL)
676 goto error_return;
678 secinfo->sec = sec;
679 secinfo->psecinfo = psecinfo;
681 /* Search for a matching output merged section. */
682 for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
683 if (sinfo->chain
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)
689 break;
691 if (sinfo == NULL)
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));
696 if (sinfo == NULL)
697 goto error_return;
698 sinfo->next = (struct sec_merge_info *) *psinfo;
699 sinfo->chain = NULL;
700 sinfo->last = &sinfo->chain;
701 *psinfo = sinfo;
702 sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
703 if (sinfo->htab == NULL)
704 goto error_return;
707 *sinfo->last = secinfo;
708 sinfo->last = &secinfo->next;
710 secinfo->sinfo = sinfo;
711 secinfo->reprsec = sinfo->chain->sec;
713 return true;
715 error_return:
716 *psecinfo = NULL;
717 return false;
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
723 this section). */
725 static bool
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;
733 unsigned int align;
734 bfd_size_type amt;
735 bfd_byte *contents;
736 void *tmpptr;
738 amt = sec->size;
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. */
743 amt += sec->entsize;
744 contents = bfd_malloc (amt);
745 if (!contents)
746 goto error_return;
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))
753 goto error_return;
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;)
765 unsigned len;
766 uint32_t hash = hashit (sinfo->htab, (char*) p, &len);
767 unsigned int ofs = p - contents;
768 eltalign = ofs;
769 eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
770 if (!eltalign || eltalign > mask)
771 eltalign = mask + 1;
772 entry = sec_merge_hash_lookup (sinfo->htab, (char *) p, len, hash,
773 (unsigned) eltalign);
774 if (! entry)
775 goto error_return;
776 if (! append_offsetmap (secinfo, ofs, entry))
777 goto error_return;
778 p += len;
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--;
786 free (contents);
787 contents = NULL;
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]));
795 if (tmpptr)
796 secinfo->map = tmpptr;
797 tmpptr = bfd_realloc (secinfo->map_ofs, amt * sizeof(secinfo->map_ofs[0]));
798 if (tmpptr)
799 secinfo->map_ofs = tmpptr;
801 /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
802 (unsigned)secinfo->noffsetmap);*/
804 return true;
806 error_return:
807 free (contents);
808 contents = NULL;
809 return false;
812 /* qsort comparison function. Won't ever return zero as all entries
813 differ, so there is no issue with qsort stability here. */
815 static int
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;
826 while (l)
828 if (*s != *t)
829 return (int) *s - (int) *t;
830 s--;
831 t--;
832 l--;
834 return lenA - lenB;
837 /* Like strrevcmp, but for the case where all strings have the same
838 alignment > entsize. */
840 static int
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));
852 if (tail_align != 0)
853 return tail_align;
855 while (l)
857 if (*s != *t)
858 return (int) *s - (int) *t;
859 s--;
860 t--;
861 l--;
863 return lenA - lenB;
866 static inline int
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. */
873 return 0;
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);
892 if (array == NULL)
893 return NULL;
895 for (e = sinfo->htab->first, a = array; e; e = e->next)
896 if (e->alignment)
898 *a++ = e;
899 /* Adjust the length to not include the zero terminator. */
900 e->len -= sinfo->htab->entsize;
901 if (alignment != e->alignment)
903 if (alignment == 0)
904 alignment = e->alignment;
905 else
906 alignment = (unsigned) -1;
910 size_t asize = a - array;
911 if (asize != 0)
913 qsort (array, asize,
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 */
919 e = *--a;
920 e->len += sinfo->htab->entsize;
921 while (--a >= array)
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))
930 cmp->u.suffix = e;
931 cmp->alignment = 0;
933 else
934 e = cmp;
938 free (array);
940 /* Now assign positions to the strings we want to keep. */
941 size = 0;
942 secinfo = sinfo->chain;
943 for (e = sinfo->htab->first; e; e = e->next)
945 if (e->alignment)
947 size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
948 e->u.index = size;
949 size += e->len;
952 secinfo->sec->size = size;
954 /* And now adjust the rest, removing them from the chain (but not hashtable)
955 at the same time. */
956 for (a = &sinfo->htab->first, e = *a; e; e = e->next)
957 if (e->alignment)
958 a = &e->next;
959 else
961 *a = e->next;
962 if (e->len)
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;
972 return secinfo;
975 /* This function is called once after all SEC_MERGE sections are registered
976 with _bfd_merge_section. */
978 bool
979 _bfd_merge_sections (bfd *abfd,
980 struct bfd_link_info *info ATTRIBUTE_UNUSED,
981 void *xsinfo,
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. */
991 if (! sinfo->chain)
992 continue;
994 /* Record the sections into the hash table. */
995 align = 1;
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;
1001 if (remove_hook)
1002 (*remove_hook) (abfd, secinfo->sec);
1004 else if (align)
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)
1010 align = 0;
1013 if (sinfo->htab->first == NULL)
1014 continue;
1016 if (sinfo->htab->strings)
1018 secinfo = merge_strings (sinfo);
1019 if (!secinfo)
1020 return false;
1022 else
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)
1034 if (e->alignment)
1036 size = (size + e->alignment - 1)
1037 & ~((bfd_vma) e->alignment - 1);
1038 e->u.index = size;
1039 size += e->len;
1042 secinfo->sec->size = size;
1045 /* If the input sections were padded according to their alignments,
1046 then pad the output too. */
1047 if (align)
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;
1058 return true;
1061 /* Write out the merged section. */
1063 bool
1064 _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
1066 struct sec_merge_sec_info *secinfo;
1067 file_ptr pos;
1068 unsigned char *contents;
1069 Elf_Internal_Shdr *hdr;
1071 secinfo = (struct sec_merge_sec_info *) psecinfo;
1073 if (!secinfo)
1074 return false;
1076 if (secinfo->first_str == NULL)
1077 return true;
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
1084 buffer. */
1085 contents = hdr->contents;
1086 if (contents == NULL)
1087 abort ();
1089 else
1091 contents = NULL;
1092 pos = sec->output_section->filepos + sec->output_offset;
1093 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
1094 return false;
1097 BFD_ASSERT (sec == secinfo->sec);
1098 BFD_ASSERT (secinfo == secinfo->sinfo->chain);
1099 if (! sec_merge_emit (output_bfd, secinfo, contents))
1100 return false;
1102 return true;
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. */
1109 bfd_vma
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;
1118 if (!secinfo)
1119 return offset;
1121 if (offset >= sec->rawsize)
1123 if (offset > sec->rawsize)
1124 _bfd_error_handler
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)
1136 return offset;
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)
1145 lb++;
1146 lb--;
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. */
1156 void
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);
1171 free (sinfo->htab);