722e665948627cbee4b5215d9011137713604f00
[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 struct sec_merge_sec_info;
98
99 /* Information per merged blob. This is the unit of merging and is
100 related to (multiple) input sections of similar characteristics
101 (alignment, entity size, strings or blobs). */
102 struct sec_merge_info
103 {
104 /* Chain of sec_merge_infos. */
105 struct sec_merge_info *next;
106 /* Chain of sec_merge_sec_infos. This first one will be the representative
107 section that conceptually collects all merged content. */
108 struct sec_merge_sec_info *chain;
109 struct sec_merge_sec_info **last;
110 /* A hash table used to hold section content. */
111 struct sec_merge_hash *htab;
112 };
113
114 /* Offset into input mergable sections are represented by this type.
115 Note how doesn't support crazy large mergable sections. */
116 typedef uint32_t mapofs_type;
117
118 /* Given a sec_merge_sec_info S this gives the input offset of the IDX's
119 recorded entry. */
120 #define MAP_OFS(S,IDX) (S)->map_ofs[IDX]
121 /* And this gives the output offset (in the merged blob representing
122 this S. */
123 #define MAP_IDX(S,IDX) (S)->map[IDX].idx
124 /* For quick lookup of output offset given an input offset we store
125 an array mapping intput-offset / OFSDIV to entry index.
126 16 is better than 8, 32 is roughly same as 16, but uses less memory, so
127 we use that. */
128 #define OFSDIV 32
129
130 /* Information per input merge section. */
131 struct sec_merge_sec_info
132 {
133 /* Chain of sec_merge_sec_infos. */
134 struct sec_merge_sec_info *next;
135 /* The corresponding section. */
136 asection *sec;
137 /* Pointer to merge_info pointing to us. */
138 void **psecinfo;
139 /* The merge entity this is a part of. */
140 struct sec_merge_info *sinfo;
141 /* The section associated with sinfo (i.e. the representative section).
142 Same as sinfo->chain->sec, but faster to access in the hot function. */
143 asection *reprsec;
144 /* First string in this section. */
145 struct sec_merge_hash_entry *first_str;
146 /* Sparse mapping from input offset to entry covering that offset: */
147 unsigned int noffsetmap; /* Number of these mappings. */
148 mapofs_type *map_ofs; /* Input offset. */
149 union {
150 struct sec_merge_hash_entry *entry; /* Covering hash entry ... */
151 bfd_size_type idx; /* ... or destination offset. */
152 } *map;
153 /* Quick access: index into map_ofs[]. ofstolowbound[o / OFSDIV]=I is
154 such that map_ofs[I] is the smallest offset higher that
155 rounddown(o, OFSDIV) (and hence I-1 is the largest entry whose offset is
156 smaller or equal to o/OFSDIV*OFSDIV). */
157 unsigned int *ofstolowbound;
158 int fast_state;
159 };
160
161
162 /* Given a merge hash table TABLE and a number of entries to be
163 ADDED, possibly resize the table for this to fit without further
164 resizing. */
165
166 static bool
167 sec_merge_maybe_resize (struct sec_merge_hash *table, unsigned added)
168 {
169 struct bfd_hash_table *bfdtab = &table->table;
170 if (bfdtab->count + added > table->nbuckets * 2 / 3)
171 {
172 unsigned i;
173 unsigned long newnb = table->nbuckets * 2;
174 struct sec_merge_hash_entry **newv;
175 uint64_t *newl;
176 unsigned long alloc;
177
178 while (bfdtab->count + added > newnb * 2 / 3)
179 {
180 newnb *= 2;
181 if (!newnb)
182 return false;
183 }
184
185 alloc = newnb * sizeof (newl[0]);
186 if (alloc / sizeof (newl[0]) != newnb)
187 return false;
188 newl = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
189 if (newl == NULL)
190 return false;
191 memset (newl, 0, alloc);
192 alloc = newnb * sizeof (newv[0]);
193 if (alloc / sizeof (newv[0]) != newnb)
194 return false;
195 newv = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
196 if (newv == NULL)
197 return false;
198 memset (newv, 0, alloc);
199
200 for (i = 0; i < table->nbuckets; i++)
201 {
202 struct sec_merge_hash_entry *v = table->values[i];
203 if (v)
204 {
205 uint32_t thishash = table->key_lens[i] >> 32;
206 unsigned idx = thishash & (newnb - 1);
207 while (newv[idx])
208 idx = (idx + 1) & (newnb - 1);
209 newl[idx] = table->key_lens[i];
210 newv[idx] = v;
211 }
212 }
213
214 table->key_lens = newl;
215 table->values = newv;
216 table->nbuckets = newnb;
217 }
218 return true;
219 }
220
221 /* Insert STRING (actually a byte blob of length LEN, with pre-computed
222 HASH and bucket _INDEX) into our hash TABLE. */
223
224 static struct sec_merge_hash_entry *
225 sec_merge_hash_insert (struct sec_merge_hash *table,
226 const char *string,
227 uint64_t hash, unsigned int len, unsigned int _index)
228 {
229 struct bfd_hash_table *bfdtab = &table->table;
230 struct sec_merge_hash_entry *hashp;
231
232 hashp = (struct sec_merge_hash_entry *)
233 bfd_hash_allocate (bfdtab, len + sizeof (struct sec_merge_hash_entry));
234 if (hashp == NULL)
235 return NULL;
236
237 memcpy (hashp->str, string, len);
238 hashp->len = len;
239 hashp->alignment = 0;
240 hashp->u.suffix = NULL;
241 hashp->next = NULL;
242 // We must not need resizing, otherwise _index is wrong
243 BFD_ASSERT (bfdtab->count + 1 <= table->nbuckets * 2 / 3);
244 bfdtab->count++;
245 table->key_lens[_index] = (hash << 32) | (uint32_t)len;
246 table->values[_index] = hashp;
247
248 return hashp;
249 }
250
251 /* Read four bytes from *STR, interpret it as 32bit unsigned little
252 endian value and return that. */
253
254 static inline uint32_t
255 hash_read32 (const char *str)
256 {
257 uint32_t i;
258 /* All reasonable compilers will inline this memcpy and generate optimal
259 code on architectures that support unaligned (4-byte) accesses. */
260 memcpy(&i, str, 4);
261 #ifdef WORDS_BIGENDIAN
262 i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
263 #endif
264 return i;
265 }
266
267 /* Calculate and return a hashvalue of the bytes at STR[0..LEN-1].
268 All non-zero lengths and all alignments are supported.
269
270 This is somewhat similar to xxh3 (of xxhash), but restricted to 32bit.
271 On cc1 strings this has quite similar statistic properties, and we
272 don't need to jump through hoops to get fast 64x64->128 mults,
273 or 64bit arith on 32 bit hosts. We also don't care for seeds
274 or secrets. They improve mixing very little. */
275
276 static uint32_t
277 hash_blob (const char *str, unsigned int len)
278 {
279 uint32_t ret = 0;
280 uint32_t mul = (1 << 0) + (1 << 2) + (1 << 3) + (1 << 5) + (1 << 7);
281 mul += (1 << 11) + (1 << 13) + (1 << 17) + (0 << 19) + (1 << 23) + (1 << 29);
282 mul += (1u << 31);
283 if (len >= 8)
284 {
285 uint32_t acc = len * 0x9e3779b1;
286 while (len >= 8)
287 {
288 uint32_t i1 = hash_read32 (str) ^ (0x396cfeb8 + 1*len);
289 uint32_t i2 = hash_read32 (str + 4) ^ (0xbe4ba423 + 1*len);
290 str += 8;
291 len -= 8;
292 uint64_t m = (uint64_t)i1 * i2;
293 acc += (uint32_t)m ^ (uint32_t)(m >> 32);
294 }
295 acc = acc ^ (acc >> 7);
296 uint64_t r = (uint64_t)mul * acc;
297 ret = (uint32_t)r ^ (uint32_t)(r >> 32);
298 if (len == 0)
299 goto end;
300 }
301 if (len >= 4)
302 {
303 uint32_t i1 = hash_read32 (str);
304 uint32_t i2 = hash_read32 (str + len - 4);
305 i1 = ((i1 + len) ^ (i1 >> 7));
306 i2 = i2 ^ (i2 >> 7);
307 uint64_t r = (uint64_t)mul * i1 + i2;
308 ret += r ^ (r >> 32);
309 }
310 else
311 {
312 /* Cleverly read in 1 to 3 bytes without further conditionals. */
313 unsigned char c1 = str[0];
314 unsigned char c2 = str[len >> 1];
315 unsigned char c3 = str[len - 1];
316 uint32_t i1 = ((uint32_t)c1 << 16) | ((uint32_t)c2 << 24)
317 | ((uint32_t) c3) | (len << 8);
318 i1 = i1 ^ (i1 >> 7);
319 uint64_t r = (uint64_t)mul * i1;
320 ret += r ^ (r >> 32);
321 }
322 end:
323 return ret;
324 }
325
326 /* Given a hash TABLE, return the hash of STRING (a blob described
327 according to info in TABLE, either a character string, or some fixed
328 size entity) and set *PLEN to the length of this blob. */
329
330 static uint32_t
331 hashit (struct sec_merge_hash *table, const char *string, unsigned int *plen)
332 {
333 const unsigned char *s;
334 uint32_t hash;
335 unsigned int len, i;
336
337 s = (const unsigned char *) string;
338 if (table->strings)
339 {
340 if (table->entsize == 1)
341 len = strlen (string) + 1;
342 else
343 {
344 len = 0;
345 for (;;)
346 {
347 for (i = 0; i < table->entsize; ++i)
348 if (s[i] != '\0')
349 break;
350 if (i == table->entsize)
351 break;
352 s += table->entsize;
353 ++len;
354 }
355 len *= table->entsize;
356 len += table->entsize;
357 }
358 }
359 else
360 len = table->entsize;
361 hash = hash_blob (string, len);
362 *plen = len;
363 return hash;
364 }
365
366 /* Lookup or insert a blob STRING (of length LEN, precomputed HASH and
367 input ALIGNMENT) into TABLE. Return the found or new hash table entry. */
368
369 static struct sec_merge_hash_entry *
370 sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
371 unsigned int len, uint64_t hash,
372 unsigned int alignment)
373 {
374 struct sec_merge_hash_entry *hashp;
375 unsigned int _index;
376
377 /*printf ("YYY insert 0x%x into %u buckets (%s)\n",
378 (unsigned)hash, (unsigned)table->nbuckets, string);*/
379 uint64_t *key_lens = table->key_lens;
380 struct sec_merge_hash_entry **values = table->values;
381 uint64_t hlen = (hash << 32) | (uint32_t)len;
382 unsigned int nbuckets = table->nbuckets;
383 _index = hash & (nbuckets - 1);
384 while (1)
385 {
386 uint64_t candlen = key_lens[_index];
387 if (candlen == hlen
388 && !memcmp (values[_index]->str, string, len))
389 {
390 hashp = values[_index];
391 if (hashp->alignment < alignment)
392 hashp->alignment = alignment;
393 return hashp;
394 }
395 if (!(candlen & (uint32_t)-1))
396 break;
397 _index = (_index + 1) & (nbuckets - 1);
398 }
399
400 hashp = sec_merge_hash_insert (table, string, hash, len, _index);
401 if (hashp == NULL)
402 return NULL;
403 hashp->alignment = alignment;
404
405 table->size++;
406 BFD_ASSERT (table->size == table->table.count);
407 if (table->first == NULL)
408 table->first = hashp;
409 else
410 table->last->next = hashp;
411 table->last = hashp;
412
413 return hashp;
414 }
415
416 /* Create a new hash table. */
417
418 static struct sec_merge_hash *
419 sec_merge_init (unsigned int entsize, bool strings)
420 {
421 struct sec_merge_hash *table;
422
423 table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash));
424 if (table == NULL)
425 return NULL;
426
427 if (! bfd_hash_table_init_n (&table->table, NULL,
428 sizeof (struct sec_merge_hash_entry), 0x2000))
429 {
430 free (table);
431 return NULL;
432 }
433
434 table->size = 0;
435 table->first = NULL;
436 table->last = NULL;
437 table->entsize = entsize;
438 table->strings = strings;
439
440 table->nbuckets = 0x2000;
441 table->key_lens = objalloc_alloc ((struct objalloc *) table->table.memory,
442 table->nbuckets * sizeof (table->key_lens[0]));
443 memset (table->key_lens, 0, table->nbuckets * sizeof (table->key_lens[0]));
444 table->values = objalloc_alloc ((struct objalloc *) table->table.memory,
445 table->nbuckets * sizeof (table->values[0]));
446 memset (table->values, 0, table->nbuckets * sizeof (table->values[0]));
447
448 return table;
449 }
450
451 /* Append the tuple of input-offset O corresponding
452 to hash table ENTRY into SECINFO, such that we later may lookup the
453 entry just by O. */
454
455 static bool
456 append_offsetmap (struct sec_merge_sec_info *secinfo,
457 mapofs_type o,
458 struct sec_merge_hash_entry *entry)
459 {
460 if ((secinfo->noffsetmap & 2047) == 0)
461 {
462 bfd_size_type amt;
463 amt = (secinfo->noffsetmap + 2048);
464 secinfo->map_ofs = bfd_realloc (secinfo->map_ofs,
465 amt * sizeof(secinfo->map_ofs[0]));
466 if (!secinfo->map_ofs)
467 return false;
468 secinfo->map = bfd_realloc (secinfo->map, amt * sizeof(secinfo->map[0]));
469 if (!secinfo->map)
470 return false;
471 }
472 unsigned int i = secinfo->noffsetmap++;
473 MAP_OFS(secinfo, i) = o;
474 secinfo->map[i].entry = entry;
475 return true;
476 }
477
478 /* Prepare the input-offset-to-entry tables after output offsets are
479 determined. */
480
481 static void
482 prepare_offsetmap (struct sec_merge_sec_info *secinfo)
483 {
484 unsigned int noffsetmap = secinfo->noffsetmap;
485 unsigned int i, lbi;
486 bfd_size_type l, sz, amt;
487
488 secinfo->fast_state = 1;
489
490 for (i = 0; i < noffsetmap; i++)
491 MAP_IDX(secinfo, i) = secinfo->map[i].entry->u.index;
492
493 sz = secinfo->sec->rawsize;
494 amt = (sz / OFSDIV + 1) * sizeof (secinfo->ofstolowbound[0]);
495 secinfo->ofstolowbound = bfd_zmalloc (amt);
496 if (!secinfo->ofstolowbound)
497 return;
498 for (l = lbi = 0; l < sz; l += OFSDIV)
499 {
500 /* No need for bounds checking on lbi, as we've added a sentinel that's
501 larger than any offset. */
502 while (MAP_OFS(secinfo, lbi) <= l)
503 lbi++;
504 //BFD_ASSERT ((l / OFSDIV) <= (i / OFSDIV));
505 secinfo->ofstolowbound[l / OFSDIV] = lbi;
506 }
507 secinfo->fast_state = 2;
508 }
509
510 static bool
511 sec_merge_emit (bfd *abfd, struct sec_merge_sec_info *secinfo,
512 unsigned char *contents)
513 {
514 struct sec_merge_hash_entry *entry = secinfo->first_str;
515 asection *sec = secinfo->sec;
516 file_ptr offset = sec->output_offset;
517 char *pad = NULL;
518 bfd_size_type off = 0;
519 unsigned int opb = bfd_octets_per_byte (abfd, sec);
520 int alignment_power = sec->output_section->alignment_power * opb;
521 bfd_size_type pad_len; /* Octets. */
522
523 /* FIXME: If alignment_power is 0 then really we should scan the
524 entry list for the largest required alignment and use that. */
525 pad_len = alignment_power ? ((bfd_size_type) 1 << alignment_power) : 16;
526
527 pad = (char *) bfd_zmalloc (pad_len);
528 if (pad == NULL)
529 return false;
530
531 for (; entry != NULL; entry = entry->next)
532 {
533 const char *str;
534 bfd_size_type len;
535
536 if (!entry->len)
537 continue;
538 BFD_ASSERT (entry->alignment);
539 len = -off & (entry->alignment - 1);
540 if (len != 0)
541 {
542 BFD_ASSERT (len <= pad_len);
543 if (contents)
544 {
545 memcpy (contents + offset, pad, len);
546 offset += len;
547 }
548 else if (bfd_write (pad, len, abfd) != len)
549 goto err;
550 off += len;
551 }
552
553 str = entry->str;
554 len = entry->len;
555
556 if (contents)
557 {
558 memcpy (contents + offset, str, len);
559 offset += len;
560 }
561 else if (bfd_write (str, len, abfd) != len)
562 goto err;
563
564 off += len;
565 }
566 BFD_ASSERT (!entry);
567
568 /* Trailing alignment needed? */
569 off = sec->size - off;
570 if (1 && off != 0)
571 {
572 BFD_ASSERT (off <= pad_len);
573 if (contents)
574 memcpy (contents + offset, pad, off);
575 else if (bfd_write (pad, off, abfd) != off)
576 goto err;
577 }
578
579 free (pad);
580 return true;
581
582 err:
583 free (pad);
584 return false;
585 }
586
587 /* Register a SEC_MERGE section as a candidate for merging.
588 This function is called for all non-dynamic SEC_MERGE input sections. */
589
590 bool
591 _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
592 void **psecinfo)
593 {
594 struct sec_merge_info *sinfo;
595 struct sec_merge_sec_info *secinfo;
596 asection *repr;
597 unsigned int alignment_power; /* Octets. */
598 unsigned int align; /* Octets. */
599 unsigned int opb = bfd_octets_per_byte (abfd, sec);
600
601 if ((abfd->flags & DYNAMIC) != 0
602 || (sec->flags & SEC_MERGE) == 0)
603 abort ();
604
605 if (sec->size == 0
606 || (sec->flags & SEC_EXCLUDE) != 0
607 || sec->entsize == 0)
608 return true;
609
610 if (sec->size % sec->entsize != 0)
611 return true;
612
613 if ((sec->flags & SEC_RELOC) != 0)
614 {
615 /* We aren't prepared to handle relocations in merged sections. */
616 return true;
617 }
618
619 if (sec->size > (mapofs_type)-1)
620 {
621 /* Input offsets must be representable by mapofs_type. */
622 return true;
623 }
624
625 #ifndef CHAR_BIT
626 #define CHAR_BIT 8
627 #endif
628 alignment_power = sec->alignment_power * opb;
629 if (alignment_power >= sizeof (align) * CHAR_BIT)
630 return true;
631
632 align = 1u << alignment_power;
633 if ((sec->entsize < align
634 && ((sec->entsize & (sec->entsize - 1))
635 || !(sec->flags & SEC_STRINGS)))
636 || (sec->entsize > align
637 && (sec->entsize & (align - 1))))
638 {
639 /* Sanity check. If string character size is smaller than
640 alignment, then we require character size to be a power
641 of 2, otherwise character size must be integer multiple
642 of alignment. For non-string constants, alignment must
643 be smaller than or equal to entity size and entity size
644 must be integer multiple of alignment. */
645 return true;
646 }
647
648 /* Initialize the descriptor for this input section. */
649
650 *psecinfo = secinfo = bfd_zalloc (abfd, sizeof (*secinfo));
651 if (*psecinfo == NULL)
652 goto error_return;
653
654 secinfo->sec = sec;
655 secinfo->psecinfo = psecinfo;
656
657 /* Search for a matching output merged section. */
658 for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
659 if (sinfo->chain
660 && (repr = sinfo->chain->sec)
661 && ! ((repr->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
662 && repr->entsize == sec->entsize
663 && repr->alignment_power == sec->alignment_power
664 && repr->output_section == sec->output_section)
665 break;
666
667 if (sinfo == NULL)
668 {
669 /* Initialize the information we need to keep track of. */
670 sinfo = (struct sec_merge_info *)
671 bfd_alloc (abfd, sizeof (struct sec_merge_info));
672 if (sinfo == NULL)
673 goto error_return;
674 sinfo->next = (struct sec_merge_info *) *psinfo;
675 sinfo->chain = NULL;
676 sinfo->last = &sinfo->chain;
677 *psinfo = sinfo;
678 sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
679 if (sinfo->htab == NULL)
680 goto error_return;
681 }
682
683 *sinfo->last = secinfo;
684 sinfo->last = &secinfo->next;
685
686 secinfo->sinfo = sinfo;
687 secinfo->reprsec = sinfo->chain->sec;
688
689 return true;
690
691 error_return:
692 *psecinfo = NULL;
693 return false;
694 }
695
696 /* Record one whole input section (described by SECINFO) into the hash table
697 SINFO. */
698
699 static bool
700 record_section (struct sec_merge_info *sinfo,
701 struct sec_merge_sec_info *secinfo)
702 {
703 asection *sec = secinfo->sec;
704 struct sec_merge_hash_entry *entry;
705 unsigned char *p, *end;
706 bfd_vma mask, eltalign;
707 unsigned int align;
708 bfd_size_type amt;
709 bfd_byte *contents;
710
711 amt = sec->size;
712 if (sec->flags & SEC_STRINGS)
713 /* Some versions of gcc may emit a string without a zero terminator.
714 See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html
715 Allocate space for an extra zero. */
716 amt += sec->entsize;
717 contents = bfd_malloc (amt);
718 if (!contents)
719 goto error_return;
720
721 /* Slurp in all section contents (possibly decompressing it). */
722 sec->rawsize = sec->size;
723 if (sec->flags & SEC_STRINGS)
724 memset (contents + sec->size, 0, sec->entsize);
725 if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
726 goto error_return;
727
728 /* Now populate the hash table and offset mapping. */
729
730 /* Presize the hash table for what we're going to add. We overestimate
731 quite a bit, but if it turns out to be too much then other sections
732 merged into this area will make use of that as well. */
733 if (!sec_merge_maybe_resize (sinfo->htab, 1 + sec->size / 2))
734 {
735 bfd_set_error (bfd_error_no_memory);
736 goto error_return;
737 }
738
739 /* Walk through the contents, calculate hashes and length of all
740 blobs (strings or fixed-size entries) we find and fill the
741 hash and offset tables. */
742 align = sec->alignment_power;
743 mask = ((bfd_vma) 1 << align) - 1;
744 end = contents + sec->size;
745 for (p = contents; p < end;)
746 {
747 unsigned len;
748 uint32_t hash = hashit (sinfo->htab, (char*) p, &len);
749 unsigned int ofs = p - contents;
750 eltalign = ofs;
751 eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
752 if (!eltalign || eltalign > mask)
753 eltalign = mask + 1;
754 entry = sec_merge_hash_lookup (sinfo->htab, (char *) p, len, hash,
755 (unsigned) eltalign);
756 if (! entry)
757 goto error_return;
758 if (! append_offsetmap (secinfo, ofs, entry))
759 goto error_return;
760 p += len;
761 }
762
763 /* Add a sentinel element that's conceptually behind all others. */
764 append_offsetmap (secinfo, sec->size, NULL);
765 /* But don't count it. */
766 secinfo->noffsetmap--;
767
768 free (contents);
769 contents = NULL;
770 /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
771 (unsigned)secinfo->noffsetmap);*/
772
773 return true;
774
775 error_return:
776 free (contents);
777 contents = NULL;
778 for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
779 *secinfo->psecinfo = NULL;
780 return false;
781 }
782
783 /* qsort comparison function. Won't ever return zero as all entries
784 differ, so there is no issue with qsort stability here. */
785
786 static int
787 strrevcmp (const void *a, const void *b)
788 {
789 struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
790 struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
791 unsigned int lenA = A->len;
792 unsigned int lenB = B->len;
793 const unsigned char *s = (const unsigned char *) A->str + lenA - 1;
794 const unsigned char *t = (const unsigned char *) B->str + lenB - 1;
795 int l = lenA < lenB ? lenA : lenB;
796
797 while (l)
798 {
799 if (*s != *t)
800 return (int) *s - (int) *t;
801 s--;
802 t--;
803 l--;
804 }
805 return lenA - lenB;
806 }
807
808 /* Like strrevcmp, but for the case where all strings have the same
809 alignment > entsize. */
810
811 static int
812 strrevcmp_align (const void *a, const void *b)
813 {
814 struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
815 struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
816 unsigned int lenA = A->len;
817 unsigned int lenB = B->len;
818 const unsigned char *s = (const unsigned char *) A->str + lenA - 1;
819 const unsigned char *t = (const unsigned char *) B->str + lenB - 1;
820 int l = lenA < lenB ? lenA : lenB;
821 int tail_align = (lenA & (A->alignment - 1)) - (lenB & (A->alignment - 1));
822
823 if (tail_align != 0)
824 return tail_align;
825
826 while (l)
827 {
828 if (*s != *t)
829 return (int) *s - (int) *t;
830 s--;
831 t--;
832 l--;
833 }
834 return lenA - lenB;
835 }
836
837 static inline int
838 is_suffix (const struct sec_merge_hash_entry *A,
839 const struct sec_merge_hash_entry *B)
840 {
841 if (A->len <= B->len)
842 /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
843 not to be equal by the hash table. */
844 return 0;
845
846 return memcmp (A->str + (A->len - B->len),
847 B->str, B->len) == 0;
848 }
849
850 /* This is a helper function for _bfd_merge_sections. It attempts to
851 merge strings matching suffixes of longer strings. */
852 static struct sec_merge_sec_info *
853 merge_strings (struct sec_merge_info *sinfo)
854 {
855 struct sec_merge_hash_entry **array, **a, *e;
856 struct sec_merge_sec_info *secinfo;
857 bfd_size_type size, amt;
858 unsigned int alignment = 0;
859
860 /* Now sort the strings */
861 amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
862 array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
863 if (array == NULL)
864 return NULL;
865
866 for (e = sinfo->htab->first, a = array; e; e = e->next)
867 if (e->alignment)
868 {
869 *a++ = e;
870 /* Adjust the length to not include the zero terminator. */
871 e->len -= sinfo->htab->entsize;
872 if (alignment != e->alignment)
873 {
874 if (alignment == 0)
875 alignment = e->alignment;
876 else
877 alignment = (unsigned) -1;
878 }
879 }
880
881 sinfo->htab->size = a - array;
882 if (sinfo->htab->size != 0)
883 {
884 qsort (array, (size_t) sinfo->htab->size,
885 sizeof (struct sec_merge_hash_entry *),
886 (alignment != (unsigned) -1 && alignment > sinfo->htab->entsize
887 ? strrevcmp_align : strrevcmp));
888
889 /* Loop over the sorted array and merge suffixes */
890 e = *--a;
891 e->len += sinfo->htab->entsize;
892 while (--a >= array)
893 {
894 struct sec_merge_hash_entry *cmp = *a;
895
896 cmp->len += sinfo->htab->entsize;
897 if (e->alignment >= cmp->alignment
898 && !((e->len - cmp->len) & (cmp->alignment - 1))
899 && is_suffix (e, cmp))
900 {
901 cmp->u.suffix = e;
902 cmp->alignment = 0;
903 }
904 else
905 e = cmp;
906 }
907 }
908
909 free (array);
910
911 /* Now assign positions to the strings we want to keep. */
912 size = 0;
913 secinfo = sinfo->chain;
914 for (e = sinfo->htab->first; e; e = e->next)
915 {
916 if (e->alignment)
917 {
918 size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
919 e->u.index = size;
920 size += e->len;
921 }
922 }
923 secinfo->sec->size = size;
924
925 /* And now adjust the rest, removing them from the chain (but not hashtable)
926 at the same time. */
927 for (a = &sinfo->htab->first, e = *a; e; e = e->next)
928 if (e->alignment)
929 a = &e->next;
930 else
931 {
932 *a = e->next;
933 if (e->len)
934 {
935 e->alignment = e->u.suffix->alignment;
936 e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
937 }
938 }
939
940 BFD_ASSERT (!secinfo->first_str);
941 secinfo->first_str = sinfo->htab->first;
942
943 return secinfo;
944 }
945
946 /* This function is called once after all SEC_MERGE sections are registered
947 with _bfd_merge_section. */
948
949 bool
950 _bfd_merge_sections (bfd *abfd,
951 struct bfd_link_info *info ATTRIBUTE_UNUSED,
952 void *xsinfo,
953 void (*remove_hook) (bfd *, asection *))
954 {
955 struct sec_merge_info *sinfo;
956
957 for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
958 {
959 struct sec_merge_sec_info *secinfo;
960 bfd_size_type align; /* Bytes. */
961
962 if (! sinfo->chain)
963 continue;
964
965 /* Record the sections into the hash table. */
966 align = 1;
967 for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
968 if (secinfo->sec->flags & SEC_EXCLUDE)
969 {
970 *secinfo->psecinfo = NULL;
971 if (remove_hook)
972 (*remove_hook) (abfd, secinfo->sec);
973 }
974 else
975 {
976 if (!record_section (sinfo, secinfo))
977 return false;
978 if (align)
979 {
980 unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
981
982 align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
983 if (((secinfo->sec->size / opb) & (align - 1)) != 0)
984 align = 0;
985 }
986 }
987
988 if (sinfo->htab->first == NULL)
989 continue;
990
991 if (sinfo->htab->strings)
992 {
993 secinfo = merge_strings (sinfo);
994 if (!secinfo)
995 return false;
996 }
997 else
998 {
999 struct sec_merge_hash_entry *e = sinfo->htab->first;
1000 bfd_size_type size = 0; /* Octets. */
1001
1002 /* Things are much simpler for non-strings.
1003 Just assign them slots in the section. */
1004 secinfo = sinfo->chain;
1005 BFD_ASSERT (!secinfo->first_str);
1006 secinfo->first_str = e;
1007 for (e = sinfo->htab->first; e; e = e->next)
1008 {
1009 if (e->alignment)
1010 {
1011 size = (size + e->alignment - 1)
1012 & ~((bfd_vma) e->alignment - 1);
1013 e->u.index = size;
1014 size += e->len;
1015 }
1016 }
1017 secinfo->sec->size = size;
1018 }
1019
1020 /* If the input sections were padded according to their alignments,
1021 then pad the output too. */
1022 if (align)
1023 secinfo->sec->size = (secinfo->sec->size + align - 1) & -align;
1024
1025 /* Finally remove all input sections which have not made it into
1026 the hash table at all. */
1027 for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
1028 if (secinfo->first_str == NULL)
1029 secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP;
1030 }
1031
1032 return true;
1033 }
1034
1035 /* Write out the merged section. */
1036
1037 bool
1038 _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
1039 {
1040 struct sec_merge_sec_info *secinfo;
1041 file_ptr pos;
1042 unsigned char *contents;
1043 Elf_Internal_Shdr *hdr;
1044
1045 secinfo = (struct sec_merge_sec_info *) psecinfo;
1046
1047 if (!secinfo)
1048 return false;
1049
1050 if (secinfo->first_str == NULL)
1051 return true;
1052
1053 /* FIXME: octets_per_byte. */
1054 hdr = &elf_section_data (sec->output_section)->this_hdr;
1055 if (hdr->sh_offset == (file_ptr) -1)
1056 {
1057 /* We must compress this section. Write output to the
1058 buffer. */
1059 contents = hdr->contents;
1060 if (contents == NULL)
1061 abort ();
1062 }
1063 else
1064 {
1065 contents = NULL;
1066 pos = sec->output_section->filepos + sec->output_offset;
1067 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
1068 return false;
1069 }
1070
1071 BFD_ASSERT (sec == secinfo->sec);
1072 BFD_ASSERT (secinfo == secinfo->sinfo->chain);
1073 if (! sec_merge_emit (output_bfd, secinfo, contents))
1074 return false;
1075
1076 return true;
1077 }
1078
1079 /* Adjust an address in the SEC_MERGE section. Given OFFSET within
1080 *PSEC, this returns the new offset in the adjusted SEC_MERGE
1081 section and writes the new section back into *PSEC. */
1082
1083 bfd_vma
1084 _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
1085 void *psecinfo, bfd_vma offset)
1086 {
1087 struct sec_merge_sec_info *secinfo;
1088 asection *sec = *psec;
1089
1090 secinfo = (struct sec_merge_sec_info *) psecinfo;
1091
1092 if (!secinfo)
1093 return offset;
1094
1095 if (offset >= sec->rawsize)
1096 {
1097 if (offset > sec->rawsize)
1098 _bfd_error_handler
1099 /* xgettext:c-format */
1100 (_("%pB: access beyond end of merged section (%" PRId64 ")"),
1101 sec->owner, (int64_t) offset);
1102 return secinfo->first_str ? sec->size : 0;
1103 }
1104
1105 if (secinfo->fast_state != 2)
1106 {
1107 if (!secinfo->fast_state)
1108 prepare_offsetmap (secinfo);
1109 if (secinfo->fast_state != 2)
1110 return offset;
1111 }
1112
1113 long lb = secinfo->ofstolowbound[offset / OFSDIV];
1114 *psec = secinfo->reprsec;
1115
1116 /* No need for bounds checking on lb, as we've added a sentinel that's
1117 larger than any offset. */
1118 while (MAP_OFS(secinfo, lb) <= offset)
1119 lb++;
1120 lb--;
1121
1122 /*printf ("YYY (%s:%s):%u -> (%s):%u\n",
1123 sec->owner->filename, sec->name, (unsigned)offset,
1124 (*psec)->name, (unsigned)lb);*/
1125 return MAP_IDX(secinfo, lb) + offset - MAP_OFS(secinfo, lb);
1126 }
1127
1128 /* Tidy up when done. */
1129
1130 void
1131 _bfd_merge_sections_free (void *xsinfo)
1132 {
1133 struct sec_merge_info *sinfo;
1134
1135 for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
1136 {
1137 struct sec_merge_sec_info *secinfo;
1138 for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
1139 {
1140 free (secinfo->ofstolowbound);
1141 free (secinfo->map);
1142 free (secinfo->map_ofs);
1143 }
1144 bfd_hash_table_free (&sinfo->htab->table);
1145 free (sinfo->htab);
1146 }
1147 }