Coverage Report

Created: 2024-05-21 06:29

/src/binutils-gdb/bfd/elf-attrs.c
Line
Count
Source (jump to first uncovered line)
1
/* ELF attributes support (based on ARM EABI attributes).
2
   Copyright (C) 2005-2024 Free Software Foundation, Inc.
3
4
   This file is part of BFD, the Binary File Descriptor library.
5
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "libiberty.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
27
/* Return the number of bytes needed by I in uleb128 format.  */
28
static int
29
uleb128_size (unsigned int i)
30
0
{
31
0
  int size;
32
0
  size = 1;
33
0
  while (i >= 0x80)
34
0
    {
35
0
      i >>= 7;
36
0
      size++;
37
0
    }
38
0
  return size;
39
0
}
40
41
/* Return TRUE if the attribute has the default value (0/"").  */
42
static bool
43
is_default_attr (obj_attribute *attr)
44
0
{
45
0
  if (ATTR_TYPE_HAS_ERROR (attr->type))
46
0
    return true;
47
0
  if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0)
48
0
    return false;
49
0
  if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s)
50
0
    return false;
51
0
  if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type))
52
0
    return false;
53
54
0
  return true;
55
0
}
56
57
/* Return the size of a single attribute.  */
58
static bfd_vma
59
obj_attr_size (unsigned int tag, obj_attribute *attr)
60
0
{
61
0
  bfd_vma size;
62
63
0
  if (is_default_attr (attr))
64
0
    return 0;
65
66
0
  size = uleb128_size (tag);
67
0
  if (ATTR_TYPE_HAS_INT_VAL (attr->type))
68
0
    size += uleb128_size (attr->i);
69
0
  if (ATTR_TYPE_HAS_STR_VAL (attr->type))
70
0
    size += strlen ((char *)attr->s) + 1;
71
0
  return size;
72
0
}
73
74
/* Return the vendor name for a given object attributes section.  */
75
static const char *
76
vendor_obj_attr_name (bfd *abfd, int vendor)
77
0
{
78
0
  return (vendor == OBJ_ATTR_PROC
79
0
    ? get_elf_backend_data (abfd)->obj_attrs_vendor
80
0
    : "gnu");
81
0
}
82
83
/* Return the size of the object attributes section for VENDOR
84
   (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
85
   for that vendor to record and the vendor is OBJ_ATTR_GNU.  */
86
static bfd_vma
87
vendor_obj_attr_size (bfd *abfd, int vendor)
88
0
{
89
0
  bfd_vma size;
90
0
  obj_attribute *attr;
91
0
  obj_attribute_list *list;
92
0
  int i;
93
0
  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
94
95
0
  if (!vendor_name)
96
0
    return 0;
97
98
0
  attr = elf_known_obj_attributes (abfd)[vendor];
99
0
  size = 0;
100
0
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
101
0
    size += obj_attr_size (i, &attr[i]);
102
103
0
  for (list = elf_other_obj_attributes (abfd)[vendor];
104
0
       list;
105
0
       list = list->next)
106
0
    size += obj_attr_size (list->tag, &list->attr);
107
108
  /* <size> <vendor_name> NUL 0x1 <size> */
109
0
  return (size
110
0
    ? size + 10 + strlen (vendor_name)
111
0
    : 0);
112
0
}
113
114
/* Return the size of the object attributes section.  */
115
bfd_vma
116
bfd_elf_obj_attr_size (bfd *abfd)
117
0
{
118
0
  bfd_vma size;
119
120
0
  size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC);
121
0
  size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU);
122
123
  /* 'A' <sections for each vendor> */
124
0
  return (size ? size + 1 : 0);
125
0
}
126
127
/* Write VAL in uleb128 format to P, returning a pointer to the
128
   following byte.  */
129
static bfd_byte *
130
write_uleb128 (bfd_byte *p, unsigned int val)
131
0
{
132
0
  bfd_byte c;
133
0
  do
134
0
    {
135
0
      c = val & 0x7f;
136
0
      val >>= 7;
137
0
      if (val)
138
0
  c |= 0x80;
139
0
      *(p++) = c;
140
0
    }
141
0
  while (val);
142
0
  return p;
143
0
}
144
145
/* Write attribute ATTR to butter P, and return a pointer to the following
146
   byte.  */
147
static bfd_byte *
148
write_obj_attribute (bfd_byte *p, unsigned int tag, obj_attribute *attr)
149
0
{
150
  /* Suppress default entries.  */
151
0
  if (is_default_attr (attr))
152
0
    return p;
153
154
0
  p = write_uleb128 (p, tag);
155
0
  if (ATTR_TYPE_HAS_INT_VAL (attr->type))
156
0
    p = write_uleb128 (p, attr->i);
157
0
  if (ATTR_TYPE_HAS_STR_VAL (attr->type))
158
0
    {
159
0
      int len;
160
161
0
      len = strlen (attr->s) + 1;
162
0
      memcpy (p, attr->s, len);
163
0
      p += len;
164
0
    }
165
166
0
  return p;
167
0
}
168
169
/* Write the contents of the object attributes section (length SIZE)
170
   for VENDOR to CONTENTS.  */
171
static void
172
vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
173
            int vendor)
174
0
{
175
0
  bfd_byte *p;
176
0
  obj_attribute *attr;
177
0
  obj_attribute_list *list;
178
0
  int i;
179
0
  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
180
0
  size_t vendor_length = strlen (vendor_name) + 1;
181
182
0
  p = contents;
183
0
  bfd_put_32 (abfd, size, p);
184
0
  p += 4;
185
0
  memcpy (p, vendor_name, vendor_length);
186
0
  p += vendor_length;
187
0
  *(p++) = Tag_File;
188
0
  bfd_put_32 (abfd, size - 4 - vendor_length, p);
189
0
  p += 4;
190
191
0
  attr = elf_known_obj_attributes (abfd)[vendor];
192
0
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
193
0
    {
194
0
      unsigned int tag = i;
195
0
      if (get_elf_backend_data (abfd)->obj_attrs_order)
196
0
  tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
197
0
      p = write_obj_attribute (p, tag, &attr[tag]);
198
0
    }
199
200
0
  for (list = elf_other_obj_attributes (abfd)[vendor];
201
0
       list;
202
0
       list = list->next)
203
0
    p = write_obj_attribute (p, list->tag, &list->attr);
204
0
}
205
206
/* Write the contents of the object attributes section to CONTENTS.  */
207
void
208
bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
209
0
{
210
0
  bfd_byte *p;
211
0
  int vendor;
212
0
  bfd_vma my_size;
213
214
0
  p = contents;
215
0
  *(p++) = 'A';
216
0
  my_size = 1;
217
0
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
218
0
    {
219
0
      bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor);
220
0
      if (vendor_size)
221
0
  vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor);
222
0
      p += vendor_size;
223
0
      my_size += vendor_size;
224
0
    }
225
226
0
  if (size != my_size)
227
0
    abort ();
228
0
}
229
230
/* Allocate/find an object attribute.  */
231
static obj_attribute *
232
elf_new_obj_attr (bfd *abfd, int vendor, unsigned int tag)
233
305k
{
234
305k
  obj_attribute *attr;
235
305k
  obj_attribute_list *list;
236
305k
  obj_attribute_list *p;
237
305k
  obj_attribute_list **lastp;
238
239
240
305k
  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
241
235k
    {
242
      /* Known tags are preallocated.  */
243
235k
      attr = &elf_known_obj_attributes (abfd)[vendor][tag];
244
235k
    }
245
69.5k
  else
246
69.5k
    {
247
      /* Create a new tag.  */
248
69.5k
      list = (obj_attribute_list *)
249
69.5k
  bfd_alloc (abfd, sizeof (obj_attribute_list));
250
69.5k
      if (list == NULL)
251
0
  return NULL;
252
69.5k
      memset (list, 0, sizeof (obj_attribute_list));
253
69.5k
      list->tag = tag;
254
      /* Keep the tag list in order.  */
255
69.5k
      lastp = &elf_other_obj_attributes (abfd)[vendor];
256
1.15M
      for (p = *lastp; p; p = p->next)
257
1.14M
  {
258
1.14M
    if (tag < p->tag)
259
57.8k
      break;
260
1.08M
    lastp = &p->next;
261
1.08M
  }
262
69.5k
      list->next = *lastp;
263
69.5k
      *lastp = list;
264
69.5k
      attr = &list->attr;
265
69.5k
    }
266
267
305k
  return attr;
268
305k
}
269
270
/* Return the value of an integer object attribute.  */
271
int
272
bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, unsigned int tag)
273
8.76k
{
274
8.76k
  obj_attribute_list *p;
275
276
8.76k
  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
277
8.76k
    {
278
      /* Known tags are preallocated.  */
279
8.76k
      return elf_known_obj_attributes (abfd)[vendor][tag].i;
280
8.76k
    }
281
0
  else
282
0
    {
283
0
      for (p = elf_other_obj_attributes (abfd)[vendor];
284
0
     p;
285
0
     p = p->next)
286
0
  {
287
0
    if (tag == p->tag)
288
0
      return p->attr.i;
289
0
    if (tag < p->tag)
290
0
      break;
291
0
  }
292
0
      return 0;
293
0
    }
294
8.76k
}
295
296
/* Add an integer object attribute.  */
297
obj_attribute *
298
bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, unsigned int tag, unsigned int i)
299
243k
{
300
243k
  obj_attribute *attr;
301
302
243k
  attr = elf_new_obj_attr (abfd, vendor, tag);
303
243k
  if (attr != NULL)
304
243k
    {
305
243k
      attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
306
243k
      attr->i = i;
307
243k
    }
308
243k
  return attr;
309
243k
}
310
311
/* Duplicate an object attribute string value.  */
312
static char *
313
elf_attr_strdup (bfd *abfd, const char *s, const char *end)
314
61.9k
{
315
61.9k
  char *p;
316
61.9k
  size_t len;
317
318
61.9k
  if (end)
319
61.9k
    len = strnlen (s, end - s);
320
0
  else
321
0
    len = strlen (s);
322
323
61.9k
  p = (char *) bfd_alloc (abfd, len + 1);
324
61.9k
  if (p != NULL)
325
61.9k
    {
326
61.9k
      memcpy (p, s, len);
327
61.9k
      p[len] = 0;
328
61.9k
    }
329
61.9k
  return p;
330
61.9k
}
331
332
char *
333
_bfd_elf_attr_strdup (bfd *abfd, const char *s)
334
0
{
335
0
  return elf_attr_strdup (abfd, s, NULL);
336
0
}
337
338
/* Add a string object attribute.  */
339
static obj_attribute *
340
elf_add_obj_attr_string (bfd *abfd, int vendor, unsigned int tag,
341
       const char *s, const char *end)
342
56.6k
{
343
56.6k
  obj_attribute *attr;
344
345
56.6k
  attr = elf_new_obj_attr (abfd, vendor, tag);
346
56.6k
  if (attr != NULL)
347
56.6k
    {
348
56.6k
      attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
349
56.6k
      attr->s = elf_attr_strdup (abfd, s, end);
350
56.6k
      if (attr->s == NULL)
351
0
  return NULL;
352
56.6k
    }
353
56.6k
  return attr;
354
56.6k
}
355
356
obj_attribute *
357
bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, unsigned int tag,
358
           const char *s)
359
0
{
360
0
  return elf_add_obj_attr_string (abfd, vendor, tag, s, NULL);
361
0
}
362
363
/* Add a int+string object attribute.  */
364
static obj_attribute *
365
elf_add_obj_attr_int_string (bfd *abfd, int vendor, unsigned int tag,
366
           unsigned int i, const char *s, const char *end)
367
5.20k
{
368
5.20k
  obj_attribute *attr;
369
370
5.20k
  attr = elf_new_obj_attr (abfd, vendor, tag);
371
5.20k
  if (attr != NULL)
372
5.20k
    {
373
5.20k
      attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
374
5.20k
      attr->i = i;
375
5.20k
      attr->s = elf_attr_strdup (abfd, s, end);
376
5.20k
      if (attr->s == NULL)
377
0
  return NULL;
378
5.20k
    }
379
5.20k
  return attr;
380
5.20k
}
381
382
obj_attribute *
383
bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, unsigned int tag,
384
         unsigned int i, const char *s)
385
0
{
386
0
  return elf_add_obj_attr_int_string (abfd, vendor, tag, i, s, NULL);
387
0
}
388
389
/* Copy the object attributes from IBFD to OBFD.  */
390
void
391
_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
392
27
{
393
27
  obj_attribute *in_attr;
394
27
  obj_attribute *out_attr;
395
27
  obj_attribute_list *list;
396
27
  int i;
397
27
  int vendor;
398
399
27
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
400
27
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
401
0
    return;
402
403
81
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
404
54
    {
405
54
      in_attr
406
54
  = &elf_known_obj_attributes (ibfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
407
54
      out_attr
408
54
  = &elf_known_obj_attributes (obfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
409
4.10k
      for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
410
4.05k
  {
411
4.05k
    out_attr->type = in_attr->type;
412
4.05k
    out_attr->i = in_attr->i;
413
4.05k
    if (in_attr->s && *in_attr->s)
414
0
      {
415
0
        out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
416
0
        if (out_attr->s == NULL)
417
0
    bfd_perror (_("error adding attribute"));
418
0
      }
419
4.05k
    in_attr++;
420
4.05k
    out_attr++;
421
4.05k
  }
422
423
54
      for (list = elf_other_obj_attributes (ibfd)[vendor];
424
54
     list;
425
54
     list = list->next)
426
0
  {
427
0
    bool ok = false;
428
0
    in_attr = &list->attr;
429
0
    switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
430
0
      {
431
0
      case ATTR_TYPE_FLAG_INT_VAL:
432
0
        ok = bfd_elf_add_obj_attr_int (obfd, vendor,
433
0
               list->tag, in_attr->i);
434
0
        break;
435
0
      case ATTR_TYPE_FLAG_STR_VAL:
436
0
        ok = bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
437
0
            in_attr->s);
438
0
        break;
439
0
      case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
440
0
        ok = bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
441
0
                in_attr->i, in_attr->s);
442
0
        break;
443
0
      default:
444
0
        abort ();
445
0
      }
446
0
    if (!ok)
447
0
      bfd_perror (_("error adding attribute"));
448
0
  }
449
54
    }
450
27
}
451
452
/* Determine whether a GNU object attribute tag takes an integer, a
453
   string or both.  */
454
static int
455
gnu_obj_attrs_arg_type (unsigned int tag)
456
478k
{
457
  /* Except for Tag_compatibility, for GNU attributes we follow the
458
     same rule ARM ones > 32 follow: odd-numbered tags take strings
459
     and even-numbered tags take integers.  In addition, tag & 2 is
460
     nonzero for architecture-independent tags and zero for
461
     architecture-dependent ones.  */
462
478k
  if (tag == Tag_compatibility)
463
10.4k
    return 3;
464
467k
  else
465
467k
    return (tag & 1) != 0 ? 2 : 1;
466
478k
}
467
468
/* Determine what arguments an attribute tag takes.  */
469
int
470
_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, unsigned int tag)
471
610k
{
472
610k
  switch (vendor)
473
610k
    {
474
132k
    case OBJ_ATTR_PROC:
475
132k
      return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
476
0
      break;
477
478k
    case OBJ_ATTR_GNU:
478
478k
      return gnu_obj_attrs_arg_type (tag);
479
0
      break;
480
0
    default:
481
0
      abort ();
482
610k
    }
483
610k
}
484
485
/* Parse an object attributes section.  */
486
void
487
_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
488
37.0k
{
489
37.0k
  bfd_byte *contents;
490
37.0k
  bfd_byte *p;
491
37.0k
  bfd_byte *p_end;
492
37.0k
  const char *std_sec;
493
37.0k
  ufile_ptr filesize;
494
495
  /* PR 17512: file: 2844a11d.  */
496
37.0k
  if (hdr->sh_size == 0)
497
8.61k
    return;
498
499
28.4k
  filesize = bfd_get_file_size (abfd);
500
28.4k
  if (filesize != 0 && hdr->sh_size > filesize)
501
8.51k
    {
502
      /* xgettext:c-format */
503
8.51k
      _bfd_error_handler (_("%pB: error: attribute section '%pA' too big: %#llx"),
504
8.51k
        abfd, hdr->bfd_section, (long long) hdr->sh_size);
505
8.51k
      bfd_set_error (bfd_error_invalid_operation);
506
8.51k
      return;
507
8.51k
    }
508
509
19.9k
  contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
510
19.9k
  if (!contents)
511
0
    return;
512
19.9k
  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
513
19.9k
         hdr->sh_size))
514
5.68k
    {
515
5.68k
      free (contents);
516
5.68k
      return;
517
5.68k
    }
518
14.2k
  p = contents;
519
14.2k
  p_end = p + hdr->sh_size;
520
14.2k
  std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
521
522
14.2k
  if (*p++ == 'A')
523
13.4k
    {
524
37.0k
      while (p_end - p >= 4)
525
26.5k
  {
526
26.5k
    size_t len = p_end - p;
527
26.5k
    size_t namelen;
528
26.5k
    size_t section_len;
529
26.5k
    int vendor;
530
531
26.5k
    section_len = bfd_get_32 (abfd, p);
532
26.5k
    p += 4;
533
26.5k
    if (section_len == 0)
534
1.56k
      break;
535
25.0k
    if (section_len > len)
536
11.9k
      section_len = len;
537
25.0k
    if (section_len <= 4)
538
502
      {
539
502
        _bfd_error_handler
540
502
    (_("%pB: error: attribute section length too small: %ld"),
541
502
     abfd, (long) section_len);
542
502
        break;
543
502
      }
544
24.5k
    section_len -= 4;
545
24.5k
    namelen = strnlen ((char *) p, section_len) + 1;
546
24.5k
    if (namelen >= section_len)
547
978
      break;
548
23.5k
    if (std_sec && strcmp ((char *) p, std_sec) == 0)
549
1.92k
      vendor = OBJ_ATTR_PROC;
550
21.6k
    else if (strcmp ((char *) p, "gnu") == 0)
551
5.47k
      vendor = OBJ_ATTR_GNU;
552
16.1k
    else
553
16.1k
      {
554
        /* Other vendor section.  Ignore it.  */
555
16.1k
        p += section_len;
556
16.1k
        continue;
557
16.1k
      }
558
559
7.39k
    p += namelen;
560
7.39k
    section_len -= namelen;
561
16.0k
    while (section_len > 0)
562
8.75k
      {
563
8.75k
        unsigned int tag;
564
8.75k
        unsigned int val;
565
8.75k
        size_t subsection_len;
566
8.75k
        bfd_byte *end, *orig_p;
567
568
8.75k
        orig_p = p;
569
8.75k
        tag = _bfd_safe_read_leb128 (abfd, &p, false, p_end);
570
8.75k
        if (p_end - p >= 4)
571
8.75k
    {
572
8.75k
      subsection_len = bfd_get_32 (abfd, p);
573
8.75k
      p += 4;
574
8.75k
    }
575
0
        else
576
0
    {
577
0
      p = p_end;
578
0
      break;
579
0
    }
580
8.75k
        if (subsection_len > section_len)
581
7.24k
    subsection_len = section_len;
582
8.75k
        section_len -= subsection_len;
583
8.75k
        end = orig_p + subsection_len;
584
8.75k
        if (end < p)
585
116
    break;
586
8.63k
        switch (tag)
587
8.63k
    {
588
8.18k
    case Tag_File:
589
313k
      while (p < end)
590
305k
        {
591
305k
          int type;
592
305k
          bool ok = false;
593
594
305k
          tag = _bfd_safe_read_leb128 (abfd, &p, false, end);
595
305k
          type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
596
305k
          switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
597
305k
      {
598
5.20k
      case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
599
5.20k
        val = _bfd_safe_read_leb128 (abfd, &p, false, end);
600
5.20k
        ok = elf_add_obj_attr_int_string (abfd, vendor, tag,
601
5.20k
                  val, (char *) p,
602
5.20k
                  (char *) end);
603
5.20k
        p += strnlen ((char *) p, end - p);
604
5.20k
        if (p < end)
605
3.46k
          p++;
606
5.20k
        break;
607
56.6k
      case ATTR_TYPE_FLAG_STR_VAL:
608
56.6k
        ok = elf_add_obj_attr_string (abfd, vendor, tag,
609
56.6k
              (char *) p,
610
56.6k
              (char *) end);
611
56.6k
        p += strnlen ((char *) p, end - p);
612
56.6k
        if (p < end)
613
52.5k
          p++;
614
56.6k
        break;
615
243k
      case ATTR_TYPE_FLAG_INT_VAL:
616
243k
        val = _bfd_safe_read_leb128 (abfd, &p, false, end);
617
243k
        ok = bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
618
243k
        break;
619
0
      default:
620
0
        abort ();
621
305k
      }
622
305k
          if (!ok)
623
0
      bfd_perror (_("error adding attribute"));
624
305k
        }
625
8.18k
      break;
626
8.18k
    case Tag_Section:
627
0
    case Tag_Symbol:
628
      /* Don't have anywhere convenient to attach these.
629
         Fall through for now.  */
630
457
    default:
631
      /* Ignore things we don't know about.  */
632
457
      p = end;
633
457
      break;
634
8.63k
    }
635
8.63k
      }
636
7.39k
  }
637
13.4k
    }
638
14.2k
  free (contents);
639
14.2k
}
640
641
/* Merge common object attributes from IBFD into OBFD.  Raise an error
642
   if there are conflicting attributes.  Any processor-specific
643
   attributes have already been merged.  This must be called from the
644
   bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
645
   target, along with any target-specific merging.  Because there are
646
   no common attributes other than Tag_compatibility at present, and
647
   non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
648
   is not presently called for targets without their own
649
   attributes.  */
650
651
bool
652
_bfd_elf_merge_object_attributes (bfd *ibfd, struct bfd_link_info *info)
653
0
{
654
0
  bfd *obfd = info->output_bfd;
655
0
  obj_attribute *in_attr;
656
0
  obj_attribute *out_attr;
657
0
  int vendor;
658
659
  /* The only common attribute is currently Tag_compatibility,
660
     accepted in both processor and "gnu" sections.  */
661
0
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
662
0
    {
663
      /* Handle Tag_compatibility.  The tags are only compatible if the flags
664
   are identical and, if the flags are '1', the strings are identical.
665
   If the flags are non-zero, then we can only use the string "gnu".  */
666
0
      in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
667
0
      out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];
668
669
0
      if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
670
0
  {
671
0
    _bfd_error_handler
672
      /* xgettext:c-format */
673
0
    (_("error: %pB: object has vendor-specific contents that "
674
0
       "must be processed by the '%s' toolchain"),
675
0
     ibfd, in_attr->s);
676
0
    return false;
677
0
  }
678
679
0
      if (in_attr->i != out_attr->i
680
0
    || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
681
0
  {
682
    /* xgettext:c-format */
683
0
    _bfd_error_handler (_("error: %pB: object tag '%d, %s' is "
684
0
        "incompatible with tag '%d, %s'"),
685
0
            ibfd,
686
0
            in_attr->i, in_attr->s ? in_attr->s : "",
687
0
            out_attr->i, out_attr->s ? out_attr->s : "");
688
0
    return false;
689
0
  }
690
0
    }
691
692
0
  return true;
693
0
}
694
695
/* Merge an unknown processor-specific attribute TAG, within the range
696
   of known attributes, from IBFD into OBFD; return TRUE if the link
697
   is OK, FALSE if it must fail.  */
698
699
bool
700
_bfd_elf_merge_unknown_attribute_low (bfd *ibfd, bfd *obfd, int tag)
701
0
{
702
0
  obj_attribute *in_attr;
703
0
  obj_attribute *out_attr;
704
0
  bfd *err_bfd = NULL;
705
0
  bool result = true;
706
707
0
  in_attr = elf_known_obj_attributes_proc (ibfd);
708
0
  out_attr = elf_known_obj_attributes_proc (obfd);
709
710
0
  if (out_attr[tag].i != 0 || out_attr[tag].s != NULL)
711
0
    err_bfd = obfd;
712
0
  else if (in_attr[tag].i != 0 || in_attr[tag].s != NULL)
713
0
    err_bfd = ibfd;
714
715
0
  if (err_bfd != NULL)
716
0
    result
717
0
      = get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, tag);
718
719
  /* Only pass on attributes that match in both inputs.  */
720
0
  if (in_attr[tag].i != out_attr[tag].i
721
0
      || (in_attr[tag].s == NULL) != (out_attr[tag].s == NULL)
722
0
      || (in_attr[tag].s != NULL && out_attr[tag].s != NULL
723
0
    && strcmp (in_attr[tag].s, out_attr[tag].s) != 0))
724
0
    {
725
0
      out_attr[tag].i = 0;
726
0
      out_attr[tag].s = NULL;
727
0
    }
728
729
0
  return result;
730
0
}
731
732
/* Merge the lists of unknown processor-specific attributes, outside
733
   the known range, from IBFD into OBFD; return TRUE if the link is
734
   OK, FALSE if it must fail.  */
735
736
bool
737
_bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd)
738
0
{
739
0
  obj_attribute_list *in_list;
740
0
  obj_attribute_list *out_list;
741
0
  obj_attribute_list **out_listp;
742
0
  bool result = true;
743
744
0
  in_list = elf_other_obj_attributes_proc (ibfd);
745
0
  out_listp = &elf_other_obj_attributes_proc (obfd);
746
0
  out_list = *out_listp;
747
748
0
  for (; in_list || out_list; )
749
0
    {
750
0
      bfd *err_bfd = NULL;
751
0
      unsigned int err_tag = 0;
752
753
      /* The tags for each list are in numerical order.  */
754
      /* If the tags are equal, then merge.  */
755
0
      if (out_list && (!in_list || in_list->tag > out_list->tag))
756
0
  {
757
    /* This attribute only exists in obfd.  We can't merge, and we don't
758
       know what the tag means, so delete it.  */
759
0
    err_bfd = obfd;
760
0
    err_tag = out_list->tag;
761
0
    *out_listp = out_list->next;
762
0
    out_list = *out_listp;
763
0
  }
764
0
      else if (in_list && (!out_list || in_list->tag < out_list->tag))
765
0
  {
766
    /* This attribute only exists in ibfd. We can't merge, and we don't
767
       know what the tag means, so ignore it.  */
768
0
    err_bfd = ibfd;
769
0
    err_tag = in_list->tag;
770
0
    in_list = in_list->next;
771
0
  }
772
0
      else /* The tags are equal.  */
773
0
  {
774
    /* As present, all attributes in the list are unknown, and
775
       therefore can't be merged meaningfully.  */
776
0
    err_bfd = obfd;
777
0
    err_tag = out_list->tag;
778
779
    /*  Only pass on attributes that match in both inputs.  */
780
0
    if (in_list->attr.i != out_list->attr.i
781
0
        || (in_list->attr.s == NULL) != (out_list->attr.s == NULL)
782
0
        || (in_list->attr.s && out_list->attr.s
783
0
      && strcmp (in_list->attr.s, out_list->attr.s) != 0))
784
0
      {
785
        /* No match.  Delete the attribute.  */
786
0
        *out_listp = out_list->next;
787
0
        out_list = *out_listp;
788
0
      }
789
0
    else
790
0
      {
791
        /* Matched.  Keep the attribute and move to the next.  */
792
0
        out_list = out_list->next;
793
0
        in_list = in_list->next;
794
0
      }
795
0
  }
796
797
0
      if (err_bfd)
798
0
  result = result
799
0
    && get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd,
800
0
                       err_tag);
801
0
    }
802
803
0
  return result;
804
0
}