Coverage Report

Created: 2025-06-24 06:45

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