Coverage Report

Created: 2023-08-28 06:25

/src/binutils-gdb/bfd/merge.c
Line
Count
Source (jump to first uncovered line)
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
0
#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
0
#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
0
#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
0
{
169
0
  struct bfd_hash_table *bfdtab = &table->table;
170
0
  if (bfdtab->count + added > table->nbuckets * 2 / 3)
171
0
    {
172
0
      unsigned i;
173
0
      unsigned long newnb = table->nbuckets * 2;
174
0
      struct sec_merge_hash_entry **newv;
175
0
      uint64_t *newl;
176
0
      unsigned long alloc;
177
178
0
      while (bfdtab->count + added > newnb * 2 / 3)
179
0
  {
180
0
    newnb *= 2;
181
0
    if (!newnb)
182
0
      return false;
183
0
  }
184
185
0
      alloc = newnb * sizeof (newl[0]);
186
0
      if (alloc / sizeof (newl[0]) != newnb)
187
0
  return false;
188
0
      newl = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
189
0
      if (newl == NULL)
190
0
  return false;
191
0
      memset (newl, 0, alloc);
192
0
      alloc = newnb * sizeof (newv[0]);
193
0
      if (alloc / sizeof (newv[0]) != newnb)
194
0
  return false;
195
0
      newv = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
196
0
      if (newv == NULL)
197
0
  return false;
198
0
      memset (newv, 0, alloc);
199
200
0
      for (i = 0; i < table->nbuckets; i++)
201
0
  {
202
0
    struct sec_merge_hash_entry *v = table->values[i];
203
0
    if (v)
204
0
      {
205
0
        uint32_t thishash = table->key_lens[i] >> 32;
206
0
        unsigned idx = thishash & (newnb - 1);
207
0
        while (newv[idx])
208
0
    idx = (idx + 1) & (newnb - 1);
209
0
        newl[idx] = table->key_lens[i];
210
0
        newv[idx] = v;
211
0
      }
212
0
  }
213
214
0
      table->key_lens = newl;
215
0
      table->values = newv;
216
0
      table->nbuckets = newnb;
217
0
    }
218
0
  return true;
219
0
}
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
0
{
229
0
  struct bfd_hash_table *bfdtab = &table->table;
230
0
  struct sec_merge_hash_entry *hashp;
231
232
0
  hashp = (struct sec_merge_hash_entry *)
233
0
      bfd_hash_allocate (bfdtab, len + sizeof (struct sec_merge_hash_entry));
234
0
  if (hashp == NULL)
235
0
    return NULL;
236
237
0
  memcpy (hashp->str, string, len);
238
0
  hashp->len = len;
239
0
  hashp->alignment = 0;
240
0
  hashp->u.suffix = NULL;
241
0
  hashp->next = NULL;
242
  // We must not need resizing, otherwise _index is wrong
243
0
  BFD_ASSERT (bfdtab->count + 1 <= table->nbuckets * 2 / 3);
244
0
  bfdtab->count++;
245
0
  table->key_lens[_index] = (hash << 32) | (uint32_t)len;
246
0
  table->values[_index] = hashp;
247
248
0
  return hashp;
249
0
}
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
0
{
257
0
  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
0
  memcpy(&i, str, 4);
261
#ifdef WORDS_BIGENDIAN
262
  i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
263
#endif
264
0
  return i;
265
0
}
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
0
{
279
0
  uint32_t ret = 0;
280
0
  uint32_t mul = (1 << 0) +  (1 << 2) + (1 << 3) + (1 << 5) + (1 << 7);
281
0
  mul += (1 << 11) + (1 << 13) + (1 << 17) + (0 << 19) + (1 << 23) + (1 << 29);
282
0
  mul += (1u << 31);
283
0
  if (len >= 8)
284
0
    {
285
0
      uint32_t acc = len * 0x9e3779b1;
286
0
      while (len >= 8)
287
0
  {
288
0
    uint32_t i1 = hash_read32  (str) ^ (0x396cfeb8 + 1*len);
289
0
    uint32_t i2 = hash_read32  (str + 4) ^ (0xbe4ba423 + 1*len);
290
0
    str += 8;
291
0
    len -= 8;
292
0
    uint64_t m = (uint64_t)i1 * i2;
293
0
    acc += (uint32_t)m ^ (uint32_t)(m >> 32);
294
0
  }
295
0
      acc = acc ^ (acc >> 7);
296
0
      uint64_t r = (uint64_t)mul * acc;
297
0
      ret = (uint32_t)r ^ (uint32_t)(r >> 32);
298
0
      if (len == 0)
299
0
  goto end;
300
0
    }
301
0
  if (len >= 4)
302
0
    {
303
0
      uint32_t i1 = hash_read32  (str);
304
0
      uint32_t i2 = hash_read32  (str + len - 4);
305
0
      i1 = ((i1 + len) ^ (i1 >> 7));
306
0
      i2 = i2 ^ (i2 >> 7);
307
0
      uint64_t r = (uint64_t)mul * i1 + i2;
308
0
      ret += r ^ (r >> 32);
309
0
    }
310
0
  else
311
0
    {
312
      /* Cleverly read in 1 to 3 bytes without further conditionals.  */
313
0
      unsigned char c1 = str[0];
314
0
      unsigned char c2 = str[len >> 1];
315
0
      unsigned char c3 = str[len - 1];
316
0
      uint32_t i1 = ((uint32_t)c1 << 16) | ((uint32_t)c2 << 24)
317
0
         | ((uint32_t) c3) | (len << 8);
318
0
      i1 = i1 ^ (i1 >> 7);
319
0
      uint64_t r = (uint64_t)mul * i1;
320
0
      ret += r ^ (r >> 32);
321
0
    }
322
0
end:
323
0
  return ret;
324
0
}
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
0
{
333
0
  const unsigned char *s;
334
0
  uint32_t hash;
335
0
  unsigned int len, i;
336
337
0
  s = (const unsigned char *) string;
338
0
  if (table->strings)
339
0
    {
340
0
      if (table->entsize == 1)
341
0
  len = strlen (string) + 1;
342
0
      else
343
0
  {
344
0
    len = 0;
345
0
    for (;;)
346
0
      {
347
0
        for (i = 0; i < table->entsize; ++i)
348
0
    if (s[i] != '\0')
349
0
      break;
350
0
        if (i == table->entsize)
351
0
    break;
352
0
        s += table->entsize;
353
0
        ++len;
354
0
      }
355
0
    len *= table->entsize;
356
0
    len += table->entsize;
357
0
  }
358
0
    }
359
0
  else
360
0
    len = table->entsize;
361
0
  hash = hash_blob (string, len);
362
0
  *plen = len;
363
0
  return hash;
364
0
}
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
0
{
374
0
  struct sec_merge_hash_entry *hashp;
375
0
  unsigned int _index;
376
377
  /*printf ("YYY insert 0x%x into %u buckets (%s)\n",
378
    (unsigned)hash, (unsigned)table->nbuckets, string);*/
379
0
  uint64_t *key_lens = table->key_lens;
380
0
  struct sec_merge_hash_entry **values = table->values;
381
0
  uint64_t hlen = (hash << 32) | (uint32_t)len;
382
0
  unsigned int nbuckets = table->nbuckets;
383
0
  _index = hash & (nbuckets - 1);
384
0
  while (1)
385
0
    {
386
0
      uint64_t candlen = key_lens[_index];
387
0
      if (candlen == hlen
388
0
    && !memcmp (values[_index]->str, string, len))
389
0
  {
390
0
    hashp = values[_index];
391
0
    if (hashp->alignment < alignment)
392
0
      hashp->alignment = alignment;
393
0
    return hashp;
394
0
  }
395
0
      if (!(candlen & (uint32_t)-1))
396
0
  break;
397
0
      _index = (_index + 1) & (nbuckets - 1);
398
0
    }
399
400
0
  hashp = sec_merge_hash_insert (table, string, hash, len, _index);
401
0
  if (hashp == NULL)
402
0
    return NULL;
403
0
  hashp->alignment = alignment;
404
405
0
  table->size++;
406
0
  BFD_ASSERT (table->size == table->table.count);
407
0
  if (table->first == NULL)
408
0
    table->first = hashp;
409
0
  else
410
0
    table->last->next = hashp;
411
0
  table->last = hashp;
412
413
0
  return hashp;
414
0
}
415
416
/* Create a new hash table.  */
417
418
static struct sec_merge_hash *
419
sec_merge_init (unsigned int entsize, bool strings)
420
0
{
421
0
  struct sec_merge_hash *table;
422
423
0
  table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash));
424
0
  if (table == NULL)
425
0
    return NULL;
426
427
0
  if (! bfd_hash_table_init_n (&table->table, NULL,
428
0
             sizeof (struct sec_merge_hash_entry), 0x2000))
429
0
    {
430
0
      free (table);
431
0
      return NULL;
432
0
    }
433
434
0
  table->size = 0;
435
0
  table->first = NULL;
436
0
  table->last = NULL;
437
0
  table->entsize = entsize;
438
0
  table->strings = strings;
439
440
0
  table->nbuckets = 0x2000;
441
0
  table->key_lens = objalloc_alloc ((struct objalloc *) table->table.memory,
442
0
        table->nbuckets * sizeof (table->key_lens[0]));
443
0
  memset (table->key_lens, 0, table->nbuckets * sizeof (table->key_lens[0]));
444
0
  table->values = objalloc_alloc ((struct objalloc *) table->table.memory,
445
0
        table->nbuckets * sizeof (table->values[0]));
446
0
  memset (table->values, 0, table->nbuckets * sizeof (table->values[0]));
447
448
0
  return table;
449
0
}
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
0
{
460
0
  if ((secinfo->noffsetmap & 2047) == 0)
461
0
    {
462
0
      bfd_size_type amt;
463
0
      amt = (secinfo->noffsetmap + 2048);
464
0
      secinfo->map_ofs = bfd_realloc (secinfo->map_ofs,
465
0
              amt * sizeof(secinfo->map_ofs[0]));
466
0
      if (!secinfo->map_ofs)
467
0
  return false;
468
0
      secinfo->map = bfd_realloc (secinfo->map, amt * sizeof(secinfo->map[0]));
469
0
      if (!secinfo->map)
470
0
  return false;
471
0
    }
472
0
  unsigned int i = secinfo->noffsetmap++;
473
0
  MAP_OFS(secinfo, i) = o;
474
0
  secinfo->map[i].entry = entry;
475
0
  return true;
476
0
}
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
0
{
484
0
  unsigned int noffsetmap = secinfo->noffsetmap;
485
0
  unsigned int i, lbi;
486
0
  bfd_size_type l, sz, amt;
487
488
0
  secinfo->fast_state = 1;
489
490
0
  for (i = 0; i < noffsetmap; i++)
491
0
    MAP_IDX(secinfo, i) = secinfo->map[i].entry->u.index;
492
493
0
  sz = secinfo->sec->rawsize;
494
0
  amt = (sz / OFSDIV + 1) * sizeof (secinfo->ofstolowbound[0]);
495
0
  secinfo->ofstolowbound = bfd_zmalloc (amt);
496
0
  if (!secinfo->ofstolowbound)
497
0
    return;
498
0
  for (l = lbi = 0; l < sz; l += OFSDIV)
499
0
    {
500
      /* No need for bounds checking on lbi, as we've added a sentinel that's
501
   larger than any offset.  */
502
0
      while (MAP_OFS(secinfo, lbi) <= l)
503
0
  lbi++;
504
      //BFD_ASSERT ((l / OFSDIV) <= (i / OFSDIV));
505
0
      secinfo->ofstolowbound[l / OFSDIV] = lbi;
506
0
    }
507
0
  secinfo->fast_state = 2;
508
0
}
509
510
static bool
511
sec_merge_emit (bfd *abfd, struct sec_merge_sec_info *secinfo,
512
    unsigned char *contents)
513
0
{
514
0
  struct sec_merge_hash_entry *entry = secinfo->first_str;
515
0
  asection *sec = secinfo->sec;
516
0
  file_ptr offset = sec->output_offset;
517
0
  char *pad = NULL;
518
0
  bfd_size_type off = 0;
519
0
  unsigned int opb = bfd_octets_per_byte (abfd, sec);
520
0
  int alignment_power = sec->output_section->alignment_power * opb;
521
0
  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
0
  pad_len = alignment_power ? ((bfd_size_type) 1 << alignment_power) : 16;
526
527
0
  pad = (char *) bfd_zmalloc (pad_len);
528
0
  if (pad == NULL)
529
0
    return false;
530
531
0
  for (; entry != NULL; entry = entry->next)
532
0
    {
533
0
      const char *str;
534
0
      bfd_size_type len;
535
536
0
      if (!entry->len)
537
0
  continue;
538
0
      BFD_ASSERT (entry->alignment);
539
0
      len = -off & (entry->alignment - 1);
540
0
      if (len != 0)
541
0
  {
542
0
    BFD_ASSERT (len <= pad_len);
543
0
    if (contents)
544
0
      {
545
0
        memcpy (contents + offset, pad, len);
546
0
        offset += len;
547
0
      }
548
0
    else if (bfd_write (pad, len, abfd) != len)
549
0
      goto err;
550
0
    off += len;
551
0
  }
552
553
0
      str = entry->str;
554
0
      len = entry->len;
555
556
0
      if (contents)
557
0
  {
558
0
    memcpy (contents + offset, str, len);
559
0
    offset += len;
560
0
  }
561
0
      else if (bfd_write (str, len, abfd) != len)
562
0
  goto err;
563
564
0
      off += len;
565
0
    }
566
0
  BFD_ASSERT (!entry);
567
568
  /* Trailing alignment needed?  */
569
0
  off = sec->size - off;
570
0
  if (1 && off != 0)
571
0
    {
572
0
      BFD_ASSERT (off <= pad_len);
573
0
      if (contents)
574
0
  memcpy (contents + offset, pad, off);
575
0
      else if (bfd_write (pad, off, abfd) != off)
576
0
  goto err;
577
0
    }
578
579
0
  free (pad);
580
0
  return true;
581
582
0
 err:
583
0
  free (pad);
584
0
  return false;
585
0
}
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
0
{
594
0
  struct sec_merge_info *sinfo;
595
0
  struct sec_merge_sec_info *secinfo;
596
0
  asection *repr;
597
0
  unsigned int alignment_power;  /* Octets.  */
598
0
  unsigned int align;            /* Octets.  */
599
0
  unsigned int opb = bfd_octets_per_byte (abfd, sec);
600
601
0
  if ((abfd->flags & DYNAMIC) != 0
602
0
      || (sec->flags & SEC_MERGE) == 0)
603
0
    abort ();
604
605
0
  if (sec->size == 0
606
0
      || (sec->flags & SEC_EXCLUDE) != 0
607
0
      || sec->entsize == 0)
608
0
    return true;
609
610
0
  if (sec->size % sec->entsize != 0)
611
0
    return true;
612
613
0
  if ((sec->flags & SEC_RELOC) != 0)
614
0
    {
615
      /* We aren't prepared to handle relocations in merged sections.  */
616
0
      return true;
617
0
    }
618
619
0
  if (sec->size > (mapofs_type)-1)
620
0
    {
621
      /* Input offsets must be representable by mapofs_type.  */
622
0
      return true;
623
0
    }
624
625
#ifndef CHAR_BIT
626
#define CHAR_BIT 8
627
#endif
628
0
  alignment_power = sec->alignment_power * opb;
629
0
  if (alignment_power >= sizeof (align) * CHAR_BIT)
630
0
    return true;
631
632
0
  align = 1u << alignment_power;
633
0
  if ((sec->entsize < align
634
0
       && ((sec->entsize & (sec->entsize - 1))
635
0
     || !(sec->flags & SEC_STRINGS)))
636
0
      || (sec->entsize > align
637
0
    && (sec->entsize & (align - 1))))
638
0
    {
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
0
      return true;
646
0
    }
647
648
  /* Initialize the descriptor for this input section.  */
649
650
0
  *psecinfo = secinfo = bfd_zalloc (abfd, sizeof (*secinfo));
651
0
  if (*psecinfo == NULL)
652
0
    goto error_return;
653
654
0
  secinfo->sec = sec;
655
0
  secinfo->psecinfo = psecinfo;
656
657
  /* Search for a matching output merged section.  */
658
0
  for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
659
0
    if (sinfo->chain
660
0
  && (repr = sinfo->chain->sec)
661
0
  && ! ((repr->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
662
0
  && repr->entsize == sec->entsize
663
0
  && repr->alignment_power == sec->alignment_power
664
0
  && repr->output_section == sec->output_section)
665
0
      break;
666
667
0
  if (sinfo == NULL)
668
0
    {
669
      /* Initialize the information we need to keep track of.  */
670
0
      sinfo = (struct sec_merge_info *)
671
0
    bfd_alloc (abfd, sizeof (struct sec_merge_info));
672
0
      if (sinfo == NULL)
673
0
  goto error_return;
674
0
      sinfo->next = (struct sec_merge_info *) *psinfo;
675
0
      sinfo->chain = NULL;
676
0
      sinfo->last = &sinfo->chain;
677
0
      *psinfo = sinfo;
678
0
      sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
679
0
      if (sinfo->htab == NULL)
680
0
  goto error_return;
681
0
    }
682
683
0
  *sinfo->last = secinfo;
684
0
  sinfo->last = &secinfo->next;
685
686
0
  secinfo->sinfo = sinfo;
687
0
  secinfo->reprsec = sinfo->chain->sec;
688
689
0
  return true;
690
691
0
 error_return:
692
0
  *psecinfo = NULL;
693
0
  return false;
694
0
}
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
0
{
703
0
  asection *sec = secinfo->sec;
704
0
  struct sec_merge_hash_entry *entry;
705
0
  unsigned char *p, *end;
706
0
  bfd_vma mask, eltalign;
707
0
  unsigned int align;
708
0
  bfd_size_type amt;
709
0
  bfd_byte *contents;
710
711
0
  amt = sec->size;
712
0
  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
0
    amt += sec->entsize;
717
0
  contents = bfd_malloc (amt);
718
0
  if (!contents)
719
0
    goto error_return;
720
721
  /* Slurp in all section contents (possibly decompressing it).  */
722
0
  sec->rawsize = sec->size;
723
0
  if (sec->flags & SEC_STRINGS)
724
0
    memset (contents + sec->size, 0, sec->entsize);
725
0
  if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
726
0
    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
0
  if (!sec_merge_maybe_resize (sinfo->htab, 1 + sec->size / 2))
734
0
    {
735
0
      bfd_set_error (bfd_error_no_memory);
736
0
      goto error_return;
737
0
    }
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
0
  align = sec->alignment_power;
743
0
  mask = ((bfd_vma) 1 << align) - 1;
744
0
  end = contents + sec->size;
745
0
  for (p = contents; p < end;)
746
0
    {
747
0
      unsigned len;
748
0
      uint32_t hash = hashit (sinfo->htab, (char*) p, &len);
749
0
      unsigned int ofs = p - contents;
750
0
      eltalign = ofs;
751
0
      eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
752
0
      if (!eltalign || eltalign > mask)
753
0
  eltalign = mask + 1;
754
0
      entry = sec_merge_hash_lookup (sinfo->htab, (char *) p, len, hash,
755
0
             (unsigned) eltalign);
756
0
      if (! entry)
757
0
  goto error_return;
758
0
      if (! append_offsetmap (secinfo, ofs, entry))
759
0
  goto error_return;
760
0
      p += len;
761
0
    }
762
763
  /* Add a sentinel element that's conceptually behind all others.  */
764
0
  append_offsetmap (secinfo, sec->size, NULL);
765
  /* But don't count it.  */
766
0
  secinfo->noffsetmap--;
767
768
0
  free (contents);
769
0
  contents = NULL;
770
  /*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
771
    (unsigned)secinfo->noffsetmap);*/
772
773
0
  return true;
774
775
0
 error_return:
776
0
  free (contents);
777
0
  contents = NULL;
778
0
  for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
779
0
    *secinfo->psecinfo = NULL;
780
0
  return false;
781
0
}
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
0
{
789
0
  struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
790
0
  struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
791
0
  unsigned int lenA = A->len;
792
0
  unsigned int lenB = B->len;
793
0
  const unsigned char *s = (const unsigned char *) A->str + lenA - 1;
794
0
  const unsigned char *t = (const unsigned char *) B->str + lenB - 1;
795
0
  int l = lenA < lenB ? lenA : lenB;
796
797
0
  while (l)
798
0
    {
799
0
      if (*s != *t)
800
0
  return (int) *s - (int) *t;
801
0
      s--;
802
0
      t--;
803
0
      l--;
804
0
    }
805
0
  return lenA - lenB;
806
0
}
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
0
{
814
0
  struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
815
0
  struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
816
0
  unsigned int lenA = A->len;
817
0
  unsigned int lenB = B->len;
818
0
  const unsigned char *s = (const unsigned char *) A->str + lenA - 1;
819
0
  const unsigned char *t = (const unsigned char *) B->str + lenB - 1;
820
0
  int l = lenA < lenB ? lenA : lenB;
821
0
  int tail_align = (lenA & (A->alignment - 1)) - (lenB & (A->alignment - 1));
822
823
0
  if (tail_align != 0)
824
0
    return tail_align;
825
826
0
  while (l)
827
0
    {
828
0
      if (*s != *t)
829
0
  return (int) *s - (int) *t;
830
0
      s--;
831
0
      t--;
832
0
      l--;
833
0
    }
834
0
  return lenA - lenB;
835
0
}
836
837
static inline int
838
is_suffix (const struct sec_merge_hash_entry *A,
839
     const struct sec_merge_hash_entry *B)
840
0
{
841
0
  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
0
    return 0;
845
846
0
  return memcmp (A->str + (A->len - B->len),
847
0
     B->str, B->len) == 0;
848
0
}
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
0
{
855
0
  struct sec_merge_hash_entry **array, **a, *e;
856
0
  struct sec_merge_sec_info *secinfo;
857
0
  bfd_size_type size, amt;
858
0
  unsigned int alignment = 0;
859
860
  /* Now sort the strings */
861
0
  amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
862
0
  array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
863
0
  if (array == NULL)
864
0
    return NULL;
865
866
0
  for (e = sinfo->htab->first, a = array; e; e = e->next)
867
0
    if (e->alignment)
868
0
      {
869
0
  *a++ = e;
870
  /* Adjust the length to not include the zero terminator.  */
871
0
  e->len -= sinfo->htab->entsize;
872
0
  if (alignment != e->alignment)
873
0
    {
874
0
      if (alignment == 0)
875
0
        alignment = e->alignment;
876
0
      else
877
0
        alignment = (unsigned) -1;
878
0
    }
879
0
      }
880
881
0
  sinfo->htab->size = a - array;
882
0
  if (sinfo->htab->size != 0)
883
0
    {
884
0
      qsort (array, (size_t) sinfo->htab->size,
885
0
       sizeof (struct sec_merge_hash_entry *),
886
0
       (alignment != (unsigned) -1 && alignment > sinfo->htab->entsize
887
0
        ? strrevcmp_align : strrevcmp));
888
889
      /* Loop over the sorted array and merge suffixes */
890
0
      e = *--a;
891
0
      e->len += sinfo->htab->entsize;
892
0
      while (--a >= array)
893
0
  {
894
0
    struct sec_merge_hash_entry *cmp = *a;
895
896
0
    cmp->len += sinfo->htab->entsize;
897
0
    if (e->alignment >= cmp->alignment
898
0
        && !((e->len - cmp->len) & (cmp->alignment - 1))
899
0
        && is_suffix (e, cmp))
900
0
      {
901
0
        cmp->u.suffix = e;
902
0
        cmp->alignment = 0;
903
0
      }
904
0
    else
905
0
      e = cmp;
906
0
  }
907
0
    }
908
909
0
  free (array);
910
911
  /* Now assign positions to the strings we want to keep.  */
912
0
  size = 0;
913
0
  secinfo = sinfo->chain;
914
0
  for (e = sinfo->htab->first; e; e = e->next)
915
0
    {
916
0
      if (e->alignment)
917
0
  {
918
0
    size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
919
0
    e->u.index = size;
920
0
    size += e->len;
921
0
  }
922
0
    }
923
0
  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
0
  for (a = &sinfo->htab->first, e = *a; e; e = e->next)
928
0
    if (e->alignment)
929
0
      a = &e->next;
930
0
    else
931
0
      {
932
0
  *a = e->next;
933
0
  if (e->len)
934
0
    {
935
0
      e->alignment = e->u.suffix->alignment;
936
0
      e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
937
0
    }
938
0
      }
939
940
0
  BFD_ASSERT (!secinfo->first_str);
941
0
  secinfo->first_str = sinfo->htab->first;
942
943
0
  return secinfo;
944
0
}
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
0
{
955
0
  struct sec_merge_info *sinfo;
956
957
0
  for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
958
0
    {
959
0
      struct sec_merge_sec_info *secinfo;
960
0
      bfd_size_type align;  /* Bytes.  */
961
962
0
      if (! sinfo->chain)
963
0
  continue;
964
965
      /* Record the sections into the hash table.  */
966
0
      align = 1;
967
0
      for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
968
0
  if (secinfo->sec->flags & SEC_EXCLUDE)
969
0
    {
970
0
      *secinfo->psecinfo = NULL;
971
0
      if (remove_hook)
972
0
        (*remove_hook) (abfd, secinfo->sec);
973
0
    }
974
0
  else
975
0
    {
976
0
      if (!record_section (sinfo, secinfo))
977
0
        return false;
978
0
      if (align)
979
0
        {
980
0
    unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
981
982
0
    align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
983
0
    if (((secinfo->sec->size / opb) & (align - 1)) != 0)
984
0
      align = 0;
985
0
        }
986
0
    }
987
988
0
      if (sinfo->htab->first == NULL)
989
0
  continue;
990
991
0
      if (sinfo->htab->strings)
992
0
  {
993
0
    secinfo = merge_strings (sinfo);
994
0
    if (!secinfo)
995
0
      return false;
996
0
  }
997
0
      else
998
0
  {
999
0
    struct sec_merge_hash_entry *e = sinfo->htab->first;
1000
0
    bfd_size_type size = 0;  /* Octets.  */
1001
1002
    /* Things are much simpler for non-strings.
1003
       Just assign them slots in the section.  */
1004
0
    secinfo = sinfo->chain;
1005
0
    BFD_ASSERT (!secinfo->first_str);
1006
0
    secinfo->first_str = e;
1007
0
    for (e = sinfo->htab->first; e; e = e->next)
1008
0
      {
1009
0
        if (e->alignment)
1010
0
    {
1011
0
      size = (size + e->alignment - 1)
1012
0
       & ~((bfd_vma) e->alignment - 1);
1013
0
      e->u.index = size;
1014
0
      size += e->len;
1015
0
    }
1016
0
      }
1017
0
    secinfo->sec->size = size;
1018
0
  }
1019
1020
      /* If the input sections were padded according to their alignments,
1021
   then pad the output too.  */
1022
0
      if (align)
1023
0
  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
0
      for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
1028
0
  if (secinfo->first_str == NULL)
1029
0
    secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP;
1030
0
    }
1031
1032
0
  return true;
1033
0
}
1034
1035
/* Write out the merged section.  */
1036
1037
bool
1038
_bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
1039
0
{
1040
0
  struct sec_merge_sec_info *secinfo;
1041
0
  file_ptr pos;
1042
0
  unsigned char *contents;
1043
0
  Elf_Internal_Shdr *hdr;
1044
1045
0
  secinfo = (struct sec_merge_sec_info *) psecinfo;
1046
1047
0
  if (!secinfo)
1048
0
    return false;
1049
1050
0
  if (secinfo->first_str == NULL)
1051
0
    return true;
1052
1053
  /* FIXME: octets_per_byte.  */
1054
0
  hdr = &elf_section_data (sec->output_section)->this_hdr;
1055
0
  if (hdr->sh_offset == (file_ptr) -1)
1056
0
    {
1057
      /* We must compress this section.  Write output to the
1058
   buffer.  */
1059
0
      contents = hdr->contents;
1060
0
      if (contents == NULL)
1061
0
  abort ();
1062
0
    }
1063
0
  else
1064
0
    {
1065
0
      contents = NULL;
1066
0
      pos = sec->output_section->filepos + sec->output_offset;
1067
0
      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
1068
0
  return false;
1069
0
    }
1070
1071
0
  BFD_ASSERT (sec == secinfo->sec);
1072
0
  BFD_ASSERT (secinfo == secinfo->sinfo->chain);
1073
0
  if (! sec_merge_emit (output_bfd, secinfo, contents))
1074
0
    return false;
1075
1076
0
  return true;
1077
0
}
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
0
{
1087
0
  struct sec_merge_sec_info *secinfo;
1088
0
  asection *sec = *psec;
1089
1090
0
  secinfo = (struct sec_merge_sec_info *) psecinfo;
1091
1092
0
  if (!secinfo)
1093
0
    return offset;
1094
1095
0
  if (offset >= sec->rawsize)
1096
0
    {
1097
0
      if (offset > sec->rawsize)
1098
0
  _bfd_error_handler
1099
    /* xgettext:c-format */
1100
0
    (_("%pB: access beyond end of merged section (%" PRId64 ")"),
1101
0
     sec->owner, (int64_t) offset);
1102
0
      return secinfo->first_str ? sec->size : 0;
1103
0
    }
1104
1105
0
  if (secinfo->fast_state != 2)
1106
0
    {
1107
0
      if (!secinfo->fast_state)
1108
0
  prepare_offsetmap (secinfo);
1109
0
      if (secinfo->fast_state != 2)
1110
0
  return offset;
1111
0
    }
1112
1113
0
  long lb = secinfo->ofstolowbound[offset / OFSDIV];
1114
0
  *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
0
  while (MAP_OFS(secinfo, lb) <= offset)
1119
0
    lb++;
1120
0
  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
0
  return MAP_IDX(secinfo, lb) + offset - MAP_OFS(secinfo, lb);
1126
0
}
1127
1128
/* Tidy up when done.  */
1129
1130
void
1131
_bfd_merge_sections_free (void *xsinfo)
1132
0
{
1133
0
  struct sec_merge_info *sinfo;
1134
1135
0
  for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
1136
0
    {
1137
0
      struct sec_merge_sec_info *secinfo;
1138
0
      for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
1139
0
  {
1140
0
    free (secinfo->ofstolowbound);
1141
0
    free (secinfo->map);
1142
0
    free (secinfo->map_ofs);
1143
0
  }
1144
0
      bfd_hash_table_free (&sinfo->htab->table);
1145
0
      free (sinfo->htab);
1146
0
    }
1147
0
}