bfd: use less memory in string merging
[binutils-gdb.git] / bfd / merge.c
1 /* SEC_MERGE support.
2 Copyright (C) 2001-2023 Free Software Foundation, Inc.
3 Written by Jakub Jelinek <jakub@redhat.com>.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22
23 /* This file contains support for merging duplicate entities within sections,
24 as used in ELF SHF_MERGE. */
25
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"
33
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).
43
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. */
49
50 /* An entry in the section merge hash table. */
51
52 struct sec_merge_hash_entry
53 {
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
60 {
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];
69 };
70
71 /* The section merge hash table. */
72
73 struct sec_merge_hash
74 {
75 struct bfd_hash_table table;
76 /* Next available index. */
77 bfd_size_type size;
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;
82 /* Entity size. */
83 unsigned int entsize;
84 /* Are entries fixed size or zero terminated strings? */
85 bool 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]). */
93 uint64_t *key_lens;
94 struct sec_merge_hash_entry **values;
95 };
96
97 /* True when given NEWCOUNT and NBUCKETS indicate that the hash table needs
98 resizing. */
99 #define NEEDS_RESIZE(newcount, nbuckets) ((newcount) > (nbuckets) / 3 * 2)
100
101 struct sec_merge_sec_info;
102
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
107 {
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;
116 };
117
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;
121
122 /* Given a sec_merge_sec_info S this gives the input offset of the IDX's
123 recorded entry. */
124 #define MAP_OFS(S,IDX) (S)->map_ofs[IDX]
125 /* And this gives the output offset (in the merged blob representing
126 this S. */
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
131 we use that. */
132 #define OFSDIV 32
133
134 /* Information per input merge section. */
135 struct sec_merge_sec_info
136 {
137 /* Chain of sec_merge_sec_infos. */
138 struct sec_merge_sec_info *next;
139 /* The corresponding section. */
140 asection *sec;
141 /* Pointer to merge_info pointing to us. */
142 void **psecinfo;
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. */
147 asection *reprsec;
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. */
153 union {
154 struct sec_merge_hash_entry *entry; /* Covering hash entry ... */
155 bfd_size_type idx; /* ... or destination offset. */
156 } *map;
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;
162 int fast_state;
163 };
164
165
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
168 resizing. */
169
170 static bool
171 sec_merge_maybe_resize (struct sec_merge_hash *table, unsigned added)
172 {
173 struct bfd_hash_table *bfdtab = &table->table;
174 if (NEEDS_RESIZE (bfdtab->count + added, table->nbuckets))
175 {
176 unsigned i;
177 unsigned long newnb = table->nbuckets * 2;
178 struct sec_merge_hash_entry **newv;
179 uint64_t *newl;
180 unsigned long alloc;
181
182 while (NEEDS_RESIZE (bfdtab->count + added, newnb))
183 {
184 newnb *= 2;
185 if (!newnb)
186 return false;
187 }
188
189 alloc = newnb * sizeof (newl[0]);
190 if (alloc / sizeof (newl[0]) != newnb)
191 return false;
192 newl = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
193 if (newl == NULL)
194 return false;
195 memset (newl, 0, alloc);
196 alloc = newnb * sizeof (newv[0]);
197 if (alloc / sizeof (newv[0]) != newnb)
198 return false;
199 newv = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
200 if (newv == NULL)
201 return false;
202 memset (newv, 0, alloc);
203
204 for (i = 0; i < table->nbuckets; i++)
205 {
206 struct sec_merge_hash_entry *v = table->values[i];
207 if (v)
208 {
209 uint32_t thishash = table->key_lens[i] >> 32;
210 unsigned idx = thishash & (newnb - 1);
211 while (newv[idx])
212 idx = (idx + 1) & (newnb - 1);
213 newl[idx] = table->key_lens[i];
214 newv[idx] = v;
215 }
216 }
217
218 table->key_lens = newl;
219 table->values = newv;
220 table->nbuckets = newnb;
221 }
222 return true;
223 }
224
225 /* Insert STRING (actually a byte blob of length LEN, with pre-computed
226 HASH and bucket _INDEX) into our hash TABLE. */
227
228 static struct sec_merge_hash_entry *
229 sec_merge_hash_insert (struct sec_merge_hash *table,
230 const char *string,
231 uint64_t hash, unsigned int len, unsigned int _index)
232 {
233 struct bfd_hash_table *bfdtab = &table->table;
234 struct sec_merge_hash_entry *hashp;
235
236 hashp = (struct sec_merge_hash_entry *)
237 bfd_hash_allocate (bfdtab, len + sizeof (struct sec_merge_hash_entry));
238 if (hashp == NULL)
239 return NULL;
240
241 memcpy (hashp->str, string, len);
242 hashp->len = len;
243 hashp->alignment = 0;
244 hashp->u.suffix = NULL;
245 hashp->next = NULL;
246 // We must not need resizing, otherwise the estimation was wrong
247 BFD_ASSERT (!NEEDS_RESIZE (bfdtab->count + 1, table->nbuckets));
248 bfdtab->count++;
249 table->key_lens[_index] = (hash << 32) | (uint32_t)len;
250 table->values[_index] = hashp;
251
252 return hashp;
253 }
254
255 /* Read four bytes from *STR, interpret it as 32bit unsigned little
256 endian value and return that. */
257
258 static inline uint32_t
259 hash_read32 (const char *str)
260 {
261 uint32_t i;
262 /* All reasonable compilers will inline this memcpy and generate optimal
263 code on architectures that support unaligned (4-byte) accesses. */
264 memcpy(&i, str, 4);
265 #ifdef WORDS_BIGENDIAN
266 i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
267 #endif
268 return i;
269 }
270
271 /* Calculate and return a hashvalue of the bytes at STR[0..LEN-1].
272 All non-zero lengths and all alignments are supported.
273
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. */
279
280 static uint32_t
281 hash_blob (const char *str, unsigned int len)
282 {
283 uint32_t ret = 0;
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);
286 mul += (1u << 31);
287 if (len >= 8)
288 {
289 uint32_t acc = len * 0x9e3779b1;
290 while (len >= 8)
291 {
292 uint32_t i1 = hash_read32 (str) ^ (0x396cfeb8 + 1*len);
293 uint32_t i2 = hash_read32 (str + 4) ^ (0xbe4ba423 + 1*len);
294 str += 8;
295 len -= 8;
296 uint64_t m = (uint64_t)i1 * i2;
297 acc += (uint32_t)m ^ (uint32_t)(m >> 32);
298 }
299 acc = acc ^ (acc >> 7);
300 uint64_t r = (uint64_t)mul * acc;
301 ret = (uint32_t)r ^ (uint32_t)(r >> 32);
302 if (len == 0)
303 goto end;
304 }
305 if (len >= 4)
306 {
307 uint32_t i1 = hash_read32 (str);
308 uint32_t i2 = hash_read32 (str + len - 4);
309 i1 = ((i1 + len) ^ (i1 >> 7));
310 i2 = i2 ^ (i2 >> 7);
311 uint64_t r = (uint64_t)mul * i1 + i2;
312 ret += r ^ (r >> 32);
313 }
314 else
315 {
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);
322 i1 = i1 ^ (i1 >> 7);
323 uint64_t r = (uint64_t)mul * i1;
324 ret += r ^ (r >> 32);
325 }
326 end:
327 return ret;
328 }
329
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. */
333
334 static uint32_t
335 hashit (struct sec_merge_hash *table, const char *string, unsigned int *plen)
336 {
337 const unsigned char *s;
338 uint32_t hash;
339 unsigned int len, i;
340
341 s = (const unsigned char *) string;
342 if (table->strings)
343 {
344 if (table->entsize == 1)
345 len = strlen (string) + 1;
346 else
347 {
348 len = 0;
349 for (;;)
350 {
351 for (i = 0; i < table->entsize; ++i)
352 if (s[i] != '\0')
353 break;
354 if (i == table->entsize)
355 break;
356 s += table->entsize;
357 ++len;
358 }
359 len *= table->entsize;
360 len += table->entsize;
361 }
362 }
363 else
364 len = table->entsize;
365 hash = hash_blob (string, len);
366 *plen = len;
367 return hash;
368 }
369
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. */
372
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)
377 {
378 struct sec_merge_hash_entry *hashp;
379 unsigned int _index;
380
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);
388 while (1)
389 {
390 uint64_t candlen = key_lens[_index];
391 if (candlen == hlen
392 && !memcmp (values[_index]->str, string, len))
393 {
394 hashp = values[_index];
395 if (hashp->alignment < alignment)
396 hashp->alignment = alignment;
397 return hashp;
398 }
399 if (!(candlen & (uint32_t)-1))
400 break;
401 _index = (_index + 1) & (nbuckets - 1);
402 }
403
404 hashp = sec_merge_hash_insert (table, string, hash, len, _index);
405 if (hashp == NULL)
406 return NULL;
407 hashp->alignment = alignment;
408
409 table->size++;
410 BFD_ASSERT (table->size == table->table.count);
411 if (table->first == NULL)
412 table->first = hashp;
413 else
414 table->last->next = hashp;
415 table->last = hashp;
416
417 return hashp;
418 }
419
420 /* Create a new hash table. */
421
422 static struct sec_merge_hash *
423 sec_merge_init (unsigned int entsize, bool strings)
424 {
425 struct sec_merge_hash *table;
426
427 table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash));
428 if (table == NULL)
429 return NULL;
430
431 if (! bfd_hash_table_init_n (&table->table, NULL,
432 sizeof (struct sec_merge_hash_entry), 0x2000))
433 {
434 free (table);
435 return NULL;
436 }
437
438 table->size = 0;
439 table->first = NULL;
440 table->last = NULL;
441 table->entsize = entsize;
442 table->strings = strings;
443
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]));
451
452 return table;
453 }
454
455 /* Append the tuple of input-offset O corresponding
456 to hash table ENTRY into SECINFO, such that we later may lookup the
457 entry just by O. */
458
459 static bool
460 append_offsetmap (struct sec_merge_sec_info *secinfo,
461 mapofs_type o,
462 struct sec_merge_hash_entry *entry)
463 {
464 if ((secinfo->noffsetmap & 2047) == 0)
465 {
466 bfd_size_type amt;
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)
471 return false;
472 secinfo->map = bfd_realloc (secinfo->map, amt * sizeof(secinfo->map[0]));
473 if (!secinfo->map)
474 return false;
475 }
476 unsigned int i = secinfo->noffsetmap++;
477 MAP_OFS(secinfo, i) = o;
478 secinfo->map[i].entry = entry;
479 return true;
480 }
481
482 /* Prepare the input-offset-to-entry tables after output offsets are
483 determined. */
484
485 static void
486 prepare_offsetmap (struct sec_merge_sec_info *secinfo)
487 {
488 unsigned int noffsetmap = secinfo->noffsetmap;
489 unsigned int i, lbi;
490 bfd_size_type l, sz, amt;
491
492 secinfo->fast_state = 1;
493
494 for (i = 0; i < noffsetmap; i++)
495 MAP_IDX(secinfo, i) = secinfo->map[i].entry->u.index;
496
497 sz = secinfo->sec->rawsize;
498 amt = (sz / OFSDIV + 1) * sizeof (secinfo->ofstolowbound[0]);
499 secinfo->ofstolowbound = bfd_zmalloc (amt);
500 if (!secinfo->ofstolowbound)
501 return;
502 for (l = lbi = 0; l < sz; l += OFSDIV)
503 {
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)
507 lbi++;
508 //BFD_ASSERT ((l / OFSDIV) <= (i / OFSDIV));
509 secinfo->ofstolowbound[l / OFSDIV] = lbi;
510 }
511 secinfo->fast_state = 2;
512 }
513
514 static bool
515 sec_merge_emit (bfd *abfd, struct sec_merge_sec_info *secinfo,
516 unsigned char *contents)
517 {
518 struct sec_merge_hash_entry *entry = secinfo->first_str;
519 asection *sec = secinfo->sec;
520 file_ptr offset = sec->output_offset;
521 char *pad = NULL;
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. */
526
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;
530
531 pad = (char *) bfd_zmalloc (pad_len);
532 if (pad == NULL)
533 return false;
534
535 for (; entry != NULL; entry = entry->next)
536 {
537 const char *str;
538 bfd_size_type len;
539
540 if (!entry->len)
541 continue;
542 BFD_ASSERT (entry->alignment);
543 len = -off & (entry->alignment - 1);
544 if (len != 0)
545 {
546 BFD_ASSERT (len <= pad_len);
547 if (contents)
548 {
549 memcpy (contents + offset, pad, len);
550 offset += len;
551 }
552 else if (bfd_write (pad, len, abfd) != len)
553 goto err;
554 off += len;
555 }
556
557 str = entry->str;
558 len = entry->len;
559
560 if (contents)
561 {
562 memcpy (contents + offset, str, len);
563 offset += len;
564 }
565 else if (bfd_write (str, len, abfd) != len)
566 goto err;
567
568 off += len;
569 }
570 BFD_ASSERT (!entry);
571
572 /* Trailing alignment needed? */
573 off = sec->size - off;
574 if (1 && off != 0)
575 {
576 BFD_ASSERT (off <= pad_len);
577 if (contents)
578 memcpy (contents + offset, pad, off);
579 else if (bfd_write (pad, off, abfd) != off)
580 goto err;
581 }
582
583 free (pad);
584 return true;
585
586 err:
587 free (pad);
588 return false;
589 }
590
591 /* Register a SEC_MERGE section as a candidate for merging.
592 This function is called for all non-dynamic SEC_MERGE input sections. */
593
594 bool
595 _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
596 void **psecinfo)
597 {
598 struct sec_merge_info *sinfo;
599 struct sec_merge_sec_info *secinfo;
600 asection *repr;
601 unsigned int alignment_power; /* Octets. */
602 unsigned int align; /* Octets. */
603 unsigned int opb = bfd_octets_per_byte (abfd, sec);
604
605 if ((abfd->flags & DYNAMIC) != 0
606 || (sec->flags & SEC_MERGE) == 0)
607 abort ();
608
609 if (sec->size == 0
610 || (sec->flags & SEC_EXCLUDE) != 0
611 || sec->entsize == 0)
612 return true;
613
614 if (sec->size % sec->entsize != 0)
615 return true;
616
617 if ((sec->flags & SEC_RELOC) != 0)
618 {
619 /* We aren't prepared to handle relocations in merged sections. */
620 return true;
621 }
622
623 if (sec->size > (mapofs_type)-1)
624 {
625 /* Input offsets must be representable by mapofs_type. */
626 return true;
627 }
628
629 #ifndef CHAR_BIT
630 #define CHAR_BIT 8
631 #endif
632 alignment_power = sec->alignment_power * opb;
633 if (alignment_power >= sizeof (align) * CHAR_BIT)
634 return true;
635
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))))
642 {
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. */
649 return true;
650 }
651
652 /* Initialize the descriptor for this input section. */
653
654 *psecinfo = secinfo = bfd_zalloc (abfd, sizeof (*secinfo));
655 if (*psecinfo == NULL)
656 goto error_return;
657
658 secinfo->sec = sec;
659 secinfo->psecinfo = psecinfo;
660
661 /* Search for a matching output merged section. */
662 for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
663 if (sinfo->chain
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)
669 break;
670
671 if (sinfo == NULL)
672 {
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));
676 if (sinfo == NULL)
677 goto error_return;
678 sinfo->next = (struct sec_merge_info *) *psinfo;
679 sinfo->chain = NULL;
680 sinfo->last = &sinfo->chain;
681 *psinfo = sinfo;
682 sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
683 if (sinfo->htab == NULL)
684 goto error_return;
685 }
686
687 *sinfo->last = secinfo;
688 sinfo->last = &secinfo->next;
689
690 secinfo->sinfo = sinfo;
691 secinfo->reprsec = sinfo->chain->sec;
692
693 return true;
694
695 error_return:
696 *psecinfo = NULL;
697 return false;
698 }
699
700 /* Record one whole input section (described by SECINFO) into the hash table
701 SINFO. */
702
703 static bool
704 record_section (struct sec_merge_info *sinfo,
705 struct sec_merge_sec_info *secinfo)
706 {
707 asection *sec = secinfo->sec;
708 struct sec_merge_hash_entry *entry;
709 unsigned char *p, *end;
710 bfd_vma mask, eltalign;
711 unsigned int align;
712 bfd_size_type amt;
713 bfd_byte *contents;
714 void *tmpptr;
715
716 amt = sec->size;
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. */
721 amt += sec->entsize;
722 contents = bfd_malloc (amt);
723 if (!contents)
724 goto error_return;
725
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))
731 goto error_return;
732
733 /* Now populate the hash table and offset mapping. */
734
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))
739 {
740 bfd_set_error (bfd_error_no_memory);
741 goto error_return;
742 }
743
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;)
751 {
752 unsigned len;
753 uint32_t hash = hashit (sinfo->htab, (char*) p, &len);
754 unsigned int ofs = p - contents;
755 eltalign = ofs;
756 eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
757 if (!eltalign || eltalign > mask)
758 eltalign = mask + 1;
759 entry = sec_merge_hash_lookup (sinfo->htab, (char *) p, len, hash,
760 (unsigned) eltalign);
761 if (! entry)
762 goto error_return;
763 if (! append_offsetmap (secinfo, ofs, entry))
764 goto error_return;
765 p += len;
766 }
767
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--;
772
773 free (contents);
774 contents = NULL;
775
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]));
782 if (tmpptr)
783 secinfo->map = tmpptr;
784 tmpptr = bfd_realloc (secinfo->map_ofs, amt * sizeof(secinfo->map_ofs[0]));
785 if (tmpptr)
786 secinfo->map_ofs = tmpptr;
787
788 /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
789 (unsigned)secinfo->noffsetmap);*/
790
791 return true;
792
793 error_return:
794 free (contents);
795 contents = NULL;
796 for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
797 *secinfo->psecinfo = NULL;
798 return false;
799 }
800
801 /* qsort comparison function. Won't ever return zero as all entries
802 differ, so there is no issue with qsort stability here. */
803
804 static int
805 strrevcmp (const void *a, const void *b)
806 {
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;
814
815 while (l)
816 {
817 if (*s != *t)
818 return (int) *s - (int) *t;
819 s--;
820 t--;
821 l--;
822 }
823 return lenA - lenB;
824 }
825
826 /* Like strrevcmp, but for the case where all strings have the same
827 alignment > entsize. */
828
829 static int
830 strrevcmp_align (const void *a, const void *b)
831 {
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));
840
841 if (tail_align != 0)
842 return tail_align;
843
844 while (l)
845 {
846 if (*s != *t)
847 return (int) *s - (int) *t;
848 s--;
849 t--;
850 l--;
851 }
852 return lenA - lenB;
853 }
854
855 static inline int
856 is_suffix (const struct sec_merge_hash_entry *A,
857 const struct sec_merge_hash_entry *B)
858 {
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. */
862 return 0;
863
864 return memcmp (A->str + (A->len - B->len),
865 B->str, B->len) == 0;
866 }
867
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)
872 {
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;
877
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);
881 if (array == NULL)
882 return NULL;
883
884 for (e = sinfo->htab->first, a = array; e; e = e->next)
885 if (e->alignment)
886 {
887 *a++ = e;
888 /* Adjust the length to not include the zero terminator. */
889 e->len -= sinfo->htab->entsize;
890 if (alignment != e->alignment)
891 {
892 if (alignment == 0)
893 alignment = e->alignment;
894 else
895 alignment = (unsigned) -1;
896 }
897 }
898
899 sinfo->htab->size = a - array;
900 if (sinfo->htab->size != 0)
901 {
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));
906
907 /* Loop over the sorted array and merge suffixes */
908 e = *--a;
909 e->len += sinfo->htab->entsize;
910 while (--a >= array)
911 {
912 struct sec_merge_hash_entry *cmp = *a;
913
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))
918 {
919 cmp->u.suffix = e;
920 cmp->alignment = 0;
921 }
922 else
923 e = cmp;
924 }
925 }
926
927 free (array);
928
929 /* Now assign positions to the strings we want to keep. */
930 size = 0;
931 secinfo = sinfo->chain;
932 for (e = sinfo->htab->first; e; e = e->next)
933 {
934 if (e->alignment)
935 {
936 size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
937 e->u.index = size;
938 size += e->len;
939 }
940 }
941 secinfo->sec->size = size;
942
943 /* And now adjust the rest, removing them from the chain (but not hashtable)
944 at the same time. */
945 for (a = &sinfo->htab->first, e = *a; e; e = e->next)
946 if (e->alignment)
947 a = &e->next;
948 else
949 {
950 *a = e->next;
951 if (e->len)
952 {
953 e->alignment = e->u.suffix->alignment;
954 e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
955 }
956 }
957
958 BFD_ASSERT (!secinfo->first_str);
959 secinfo->first_str = sinfo->htab->first;
960
961 return secinfo;
962 }
963
964 /* This function is called once after all SEC_MERGE sections are registered
965 with _bfd_merge_section. */
966
967 bool
968 _bfd_merge_sections (bfd *abfd,
969 struct bfd_link_info *info ATTRIBUTE_UNUSED,
970 void *xsinfo,
971 void (*remove_hook) (bfd *, asection *))
972 {
973 struct sec_merge_info *sinfo;
974
975 for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
976 {
977 struct sec_merge_sec_info *secinfo;
978 bfd_size_type align; /* Bytes. */
979
980 if (! sinfo->chain)
981 continue;
982
983 /* Record the sections into the hash table. */
984 align = 1;
985 for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
986 if (secinfo->sec->flags & SEC_EXCLUDE)
987 {
988 *secinfo->psecinfo = NULL;
989 if (remove_hook)
990 (*remove_hook) (abfd, secinfo->sec);
991 }
992 else
993 {
994 if (!record_section (sinfo, secinfo))
995 return false;
996 if (align)
997 {
998 unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
999
1000 align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
1001 if (((secinfo->sec->size / opb) & (align - 1)) != 0)
1002 align = 0;
1003 }
1004 }
1005
1006 if (sinfo->htab->first == NULL)
1007 continue;
1008
1009 if (sinfo->htab->strings)
1010 {
1011 secinfo = merge_strings (sinfo);
1012 if (!secinfo)
1013 return false;
1014 }
1015 else
1016 {
1017 struct sec_merge_hash_entry *e = sinfo->htab->first;
1018 bfd_size_type size = 0; /* Octets. */
1019
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)
1026 {
1027 if (e->alignment)
1028 {
1029 size = (size + e->alignment - 1)
1030 & ~((bfd_vma) e->alignment - 1);
1031 e->u.index = size;
1032 size += e->len;
1033 }
1034 }
1035 secinfo->sec->size = size;
1036 }
1037
1038 /* If the input sections were padded according to their alignments,
1039 then pad the output too. */
1040 if (align)
1041 secinfo->sec->size = (secinfo->sec->size + align - 1) & -align;
1042
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;
1048 }
1049
1050 return true;
1051 }
1052
1053 /* Write out the merged section. */
1054
1055 bool
1056 _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
1057 {
1058 struct sec_merge_sec_info *secinfo;
1059 file_ptr pos;
1060 unsigned char *contents;
1061 Elf_Internal_Shdr *hdr;
1062
1063 secinfo = (struct sec_merge_sec_info *) psecinfo;
1064
1065 if (!secinfo)
1066 return false;
1067
1068 if (secinfo->first_str == NULL)
1069 return true;
1070
1071 /* FIXME: octets_per_byte. */
1072 hdr = &elf_section_data (sec->output_section)->this_hdr;
1073 if (hdr->sh_offset == (file_ptr) -1)
1074 {
1075 /* We must compress this section. Write output to the
1076 buffer. */
1077 contents = hdr->contents;
1078 if (contents == NULL)
1079 abort ();
1080 }
1081 else
1082 {
1083 contents = NULL;
1084 pos = sec->output_section->filepos + sec->output_offset;
1085 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
1086 return false;
1087 }
1088
1089 BFD_ASSERT (sec == secinfo->sec);
1090 BFD_ASSERT (secinfo == secinfo->sinfo->chain);
1091 if (! sec_merge_emit (output_bfd, secinfo, contents))
1092 return false;
1093
1094 return true;
1095 }
1096
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. */
1100
1101 bfd_vma
1102 _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
1103 void *psecinfo, bfd_vma offset)
1104 {
1105 struct sec_merge_sec_info *secinfo;
1106 asection *sec = *psec;
1107
1108 secinfo = (struct sec_merge_sec_info *) psecinfo;
1109
1110 if (!secinfo)
1111 return offset;
1112
1113 if (offset >= sec->rawsize)
1114 {
1115 if (offset > sec->rawsize)
1116 _bfd_error_handler
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;
1121 }
1122
1123 if (secinfo->fast_state != 2)
1124 {
1125 if (!secinfo->fast_state)
1126 prepare_offsetmap (secinfo);
1127 if (secinfo->fast_state != 2)
1128 return offset;
1129 }
1130
1131 long lb = secinfo->ofstolowbound[offset / OFSDIV];
1132 *psec = secinfo->reprsec;
1133
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)
1137 lb++;
1138 lb--;
1139
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);
1144 }
1145
1146 /* Tidy up when done. */
1147
1148 void
1149 _bfd_merge_sections_free (void *xsinfo)
1150 {
1151 struct sec_merge_info *sinfo;
1152
1153 for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
1154 {
1155 struct sec_merge_sec_info *secinfo;
1156 for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
1157 {
1158 free (secinfo->ofstolowbound);
1159 free (secinfo->map);
1160 free (secinfo->map_ofs);
1161 }
1162 bfd_hash_table_free (&sinfo->htab->table);
1163 free (sinfo->htab);
1164 }
1165 }