Coverage Report

Created: 2023-08-28 06:26

/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-2023 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
0
{
234
0
  obj_attribute *attr;
235
0
  obj_attribute_list *list;
236
0
  obj_attribute_list *p;
237
0
  obj_attribute_list **lastp;
238
239
240
0
  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
241
0
    {
242
      /* Known tags are preallocated.  */
243
0
      attr = &elf_known_obj_attributes (abfd)[vendor][tag];
244
0
    }
245
0
  else
246
0
    {
247
      /* Create a new tag.  */
248
0
      list = (obj_attribute_list *)
249
0
  bfd_alloc (abfd, sizeof (obj_attribute_list));
250
0
      memset (list, 0, sizeof (obj_attribute_list));
251
0
      list->tag = tag;
252
      /* Keep the tag list in order.  */
253
0
      lastp = &elf_other_obj_attributes (abfd)[vendor];
254
0
      for (p = *lastp; p; p = p->next)
255
0
  {
256
0
    if (tag < p->tag)
257
0
      break;
258
0
    lastp = &p->next;
259
0
  }
260
0
      list->next = *lastp;
261
0
      *lastp = list;
262
0
      attr = &list->attr;
263
0
    }
264
265
0
  return attr;
266
0
}
267
268
/* Return the value of an integer object attribute.  */
269
int
270
bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, unsigned int tag)
271
0
{
272
0
  obj_attribute_list *p;
273
274
0
  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
275
0
    {
276
      /* Known tags are preallocated.  */
277
0
      return elf_known_obj_attributes (abfd)[vendor][tag].i;
278
0
    }
279
0
  else
280
0
    {
281
0
      for (p = elf_other_obj_attributes (abfd)[vendor];
282
0
     p;
283
0
     p = p->next)
284
0
  {
285
0
    if (tag == p->tag)
286
0
      return p->attr.i;
287
0
    if (tag < p->tag)
288
0
      break;
289
0
  }
290
0
      return 0;
291
0
    }
292
0
}
293
294
/* Add an integer object attribute.  */
295
void
296
bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, unsigned int tag, unsigned int i)
297
0
{
298
0
  obj_attribute *attr;
299
300
0
  attr = elf_new_obj_attr (abfd, vendor, tag);
301
0
  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
302
0
  attr->i = i;
303
0
}
304
305
/* Duplicate an object attribute string value.  */
306
static char *
307
elf_attr_strdup (bfd *abfd, const char *s, const char *end)
308
0
{
309
0
  char *p;
310
0
  size_t len;
311
312
0
  if (end)
313
0
    len = strnlen (s, end - s);
314
0
  else
315
0
    len = strlen (s);
316
317
0
  p = (char *) bfd_alloc (abfd, len + 1);
318
0
  if (p != NULL)
319
0
    {
320
0
      memcpy (p, s, len);
321
0
      p[len] = 0;
322
0
    }
323
0
  return p;
324
0
}
325
326
char *
327
_bfd_elf_attr_strdup (bfd *abfd, const char *s)
328
0
{
329
0
  return elf_attr_strdup (abfd, s, NULL);
330
0
}
331
332
/* Add a string object attribute.  */
333
static void
334
elf_add_obj_attr_string (bfd *abfd, int vendor, unsigned int tag,
335
       const char *s, const char *end)
336
0
{
337
0
  obj_attribute *attr;
338
339
0
  attr = elf_new_obj_attr (abfd, vendor, tag);
340
0
  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
341
0
  attr->s = elf_attr_strdup (abfd, s, end);
342
0
}
343
344
void
345
bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, unsigned int tag,
346
           const char *s)
347
0
{
348
0
  elf_add_obj_attr_string (abfd, vendor, tag, s, NULL);
349
0
}
350
351
/* Add a int+string object attribute.  */
352
static void
353
elf_add_obj_attr_int_string (bfd *abfd, int vendor, unsigned int tag,
354
           unsigned int i, const char *s, const char *end)
355
0
{
356
0
  obj_attribute *attr;
357
358
0
  attr = elf_new_obj_attr (abfd, vendor, tag);
359
0
  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
360
0
  attr->i = i;
361
0
  attr->s = elf_attr_strdup (abfd, s, end);
362
0
}
363
364
void
365
bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, unsigned int tag,
366
         unsigned int i, const char *s)
367
0
{
368
0
  elf_add_obj_attr_int_string (abfd, vendor, tag, i, s, NULL);
369
0
}
370
371
/* Copy the object attributes from IBFD to OBFD.  */
372
void
373
_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
374
0
{
375
0
  obj_attribute *in_attr;
376
0
  obj_attribute *out_attr;
377
0
  obj_attribute_list *list;
378
0
  int i;
379
0
  int vendor;
380
381
0
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
382
0
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
383
0
    return;
384
385
0
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
386
0
    {
387
0
      in_attr
388
0
  = &elf_known_obj_attributes (ibfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
389
0
      out_attr
390
0
  = &elf_known_obj_attributes (obfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
391
0
      for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
392
0
  {
393
0
    out_attr->type = in_attr->type;
394
0
    out_attr->i = in_attr->i;
395
0
    if (in_attr->s && *in_attr->s)
396
0
      out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
397
0
    in_attr++;
398
0
    out_attr++;
399
0
  }
400
401
0
      for (list = elf_other_obj_attributes (ibfd)[vendor];
402
0
     list;
403
0
     list = list->next)
404
0
  {
405
0
    in_attr = &list->attr;
406
0
    switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
407
0
      {
408
0
      case ATTR_TYPE_FLAG_INT_VAL:
409
0
        bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
410
0
        break;
411
0
      case ATTR_TYPE_FLAG_STR_VAL:
412
0
        bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
413
0
             in_attr->s);
414
0
        break;
415
0
      case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
416
0
        bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
417
0
                 in_attr->i, in_attr->s);
418
0
        break;
419
0
      default:
420
0
        abort ();
421
0
      }
422
0
  }
423
0
    }
424
0
}
425
426
/* Determine whether a GNU object attribute tag takes an integer, a
427
   string or both.  */
428
static int
429
gnu_obj_attrs_arg_type (unsigned int tag)
430
0
{
431
  /* Except for Tag_compatibility, for GNU attributes we follow the
432
     same rule ARM ones > 32 follow: odd-numbered tags take strings
433
     and even-numbered tags take integers.  In addition, tag & 2 is
434
     nonzero for architecture-independent tags and zero for
435
     architecture-dependent ones.  */
436
0
  if (tag == Tag_compatibility)
437
0
    return 3;
438
0
  else
439
0
    return (tag & 1) != 0 ? 2 : 1;
440
0
}
441
442
/* Determine what arguments an attribute tag takes.  */
443
int
444
_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, unsigned int tag)
445
0
{
446
0
  switch (vendor)
447
0
    {
448
0
    case OBJ_ATTR_PROC:
449
0
      return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
450
0
      break;
451
0
    case OBJ_ATTR_GNU:
452
0
      return gnu_obj_attrs_arg_type (tag);
453
0
      break;
454
0
    default:
455
0
      abort ();
456
0
    }
457
0
}
458
459
/* Parse an object attributes section.  */
460
void
461
_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
462
0
{
463
0
  bfd_byte *contents;
464
0
  bfd_byte *p;
465
0
  bfd_byte *p_end;
466
0
  const char *std_sec;
467
0
  ufile_ptr filesize;
468
469
  /* PR 17512: file: 2844a11d.  */
470
0
  if (hdr->sh_size == 0)
471
0
    return;
472
473
0
  filesize = bfd_get_file_size (abfd);
474
0
  if (filesize != 0 && hdr->sh_size > filesize)
475
0
    {
476
      /* xgettext:c-format */
477
0
      _bfd_error_handler (_("%pB: error: attribute section '%pA' too big: %#llx"),
478
0
        abfd, hdr->bfd_section, (long long) hdr->sh_size);
479
0
      bfd_set_error (bfd_error_invalid_operation);
480
0
      return;
481
0
    }
482
483
0
  contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
484
0
  if (!contents)
485
0
    return;
486
0
  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
487
0
         hdr->sh_size))
488
0
    {
489
0
      free (contents);
490
0
      return;
491
0
    }
492
0
  p = contents;
493
0
  p_end = p + hdr->sh_size;
494
0
  std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
495
496
0
  if (*p++ == 'A')
497
0
    {
498
0
      while (p_end - p >= 4)
499
0
  {
500
0
    size_t len = p_end - p;
501
0
    size_t namelen;
502
0
    size_t section_len;
503
0
    int vendor;
504
505
0
    section_len = bfd_get_32 (abfd, p);
506
0
    p += 4;
507
0
    if (section_len == 0)
508
0
      break;
509
0
    if (section_len > len)
510
0
      section_len = len;
511
0
    if (section_len <= 4)
512
0
      {
513
0
        _bfd_error_handler
514
0
    (_("%pB: error: attribute section length too small: %ld"),
515
0
     abfd, (long) section_len);
516
0
        break;
517
0
      }
518
0
    section_len -= 4;
519
0
    namelen = strnlen ((char *) p, section_len) + 1;
520
0
    if (namelen >= section_len)
521
0
      break;
522
0
    if (std_sec && strcmp ((char *) p, std_sec) == 0)
523
0
      vendor = OBJ_ATTR_PROC;
524
0
    else if (strcmp ((char *) p, "gnu") == 0)
525
0
      vendor = OBJ_ATTR_GNU;
526
0
    else
527
0
      {
528
        /* Other vendor section.  Ignore it.  */
529
0
        p += section_len;
530
0
        continue;
531
0
      }
532
533
0
    p += namelen;
534
0
    section_len -= namelen;
535
0
    while (section_len > 0)
536
0
      {
537
0
        unsigned int tag;
538
0
        unsigned int val;
539
0
        size_t subsection_len;
540
0
        bfd_byte *end, *orig_p;
541
542
0
        orig_p = p;
543
0
        tag = _bfd_safe_read_leb128 (abfd, &p, false, p_end);
544
0
        if (p_end - p >= 4)
545
0
    {
546
0
      subsection_len = bfd_get_32 (abfd, p);
547
0
      p += 4;
548
0
    }
549
0
        else
550
0
    {
551
0
      p = p_end;
552
0
      break;
553
0
    }
554
0
        if (subsection_len > section_len)
555
0
    subsection_len = section_len;
556
0
        section_len -= subsection_len;
557
0
        end = orig_p + subsection_len;
558
0
        if (end < p)
559
0
    break;
560
0
        switch (tag)
561
0
    {
562
0
    case Tag_File:
563
0
      while (p < end)
564
0
        {
565
0
          int type;
566
567
0
          tag = _bfd_safe_read_leb128 (abfd, &p, false, end);
568
0
          type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
569
0
          switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
570
0
      {
571
0
      case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
572
0
        val = _bfd_safe_read_leb128 (abfd, &p, false, end);
573
0
        elf_add_obj_attr_int_string (abfd, vendor, tag, val,
574
0
                   (char *) p,
575
0
                   (char *) end);
576
0
        p += strnlen ((char *) p, end - p);
577
0
        if (p < end)
578
0
          p++;
579
0
        break;
580
0
      case ATTR_TYPE_FLAG_STR_VAL:
581
0
        elf_add_obj_attr_string (abfd, vendor, tag,
582
0
               (char *) p,
583
0
               (char *) end);
584
0
        p += strnlen ((char *) p, end - p);
585
0
        if (p < end)
586
0
          p++;
587
0
        break;
588
0
      case ATTR_TYPE_FLAG_INT_VAL:
589
0
        val = _bfd_safe_read_leb128 (abfd, &p, false, end);
590
0
        bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
591
0
        break;
592
0
      default:
593
0
        abort ();
594
0
      }
595
0
        }
596
0
      break;
597
0
    case Tag_Section:
598
0
    case Tag_Symbol:
599
      /* Don't have anywhere convenient to attach these.
600
         Fall through for now.  */
601
0
    default:
602
      /* Ignore things we don't know about.  */
603
0
      p = end;
604
0
      break;
605
0
    }
606
0
      }
607
0
  }
608
0
    }
609
0
  free (contents);
610
0
}
611
612
/* Merge common object attributes from IBFD into OBFD.  Raise an error
613
   if there are conflicting attributes.  Any processor-specific
614
   attributes have already been merged.  This must be called from the
615
   bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
616
   target, along with any target-specific merging.  Because there are
617
   no common attributes other than Tag_compatibility at present, and
618
   non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
619
   is not presently called for targets without their own
620
   attributes.  */
621
622
bool
623
_bfd_elf_merge_object_attributes (bfd *ibfd, struct bfd_link_info *info)
624
0
{
625
0
  bfd *obfd = info->output_bfd;
626
0
  obj_attribute *in_attr;
627
0
  obj_attribute *out_attr;
628
0
  int vendor;
629
630
  /* The only common attribute is currently Tag_compatibility,
631
     accepted in both processor and "gnu" sections.  */
632
0
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
633
0
    {
634
      /* Handle Tag_compatibility.  The tags are only compatible if the flags
635
   are identical and, if the flags are '1', the strings are identical.
636
   If the flags are non-zero, then we can only use the string "gnu".  */
637
0
      in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
638
0
      out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];
639
640
0
      if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
641
0
  {
642
0
    _bfd_error_handler
643
      /* xgettext:c-format */
644
0
    (_("error: %pB: object has vendor-specific contents that "
645
0
       "must be processed by the '%s' toolchain"),
646
0
     ibfd, in_attr->s);
647
0
    return false;
648
0
  }
649
650
0
      if (in_attr->i != out_attr->i
651
0
    || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
652
0
  {
653
    /* xgettext:c-format */
654
0
    _bfd_error_handler (_("error: %pB: object tag '%d, %s' is "
655
0
        "incompatible with tag '%d, %s'"),
656
0
            ibfd,
657
0
            in_attr->i, in_attr->s ? in_attr->s : "",
658
0
            out_attr->i, out_attr->s ? out_attr->s : "");
659
0
    return false;
660
0
  }
661
0
    }
662
663
0
  return true;
664
0
}
665
666
/* Merge an unknown processor-specific attribute TAG, within the range
667
   of known attributes, from IBFD into OBFD; return TRUE if the link
668
   is OK, FALSE if it must fail.  */
669
670
bool
671
_bfd_elf_merge_unknown_attribute_low (bfd *ibfd, bfd *obfd, int tag)
672
0
{
673
0
  obj_attribute *in_attr;
674
0
  obj_attribute *out_attr;
675
0
  bfd *err_bfd = NULL;
676
0
  bool result = true;
677
678
0
  in_attr = elf_known_obj_attributes_proc (ibfd);
679
0
  out_attr = elf_known_obj_attributes_proc (obfd);
680
681
0
  if (out_attr[tag].i != 0 || out_attr[tag].s != NULL)
682
0
    err_bfd = obfd;
683
0
  else if (in_attr[tag].i != 0 || in_attr[tag].s != NULL)
684
0
    err_bfd = ibfd;
685
686
0
  if (err_bfd != NULL)
687
0
    result
688
0
      = get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, tag);
689
690
  /* Only pass on attributes that match in both inputs.  */
691
0
  if (in_attr[tag].i != out_attr[tag].i
692
0
      || (in_attr[tag].s == NULL) != (out_attr[tag].s == NULL)
693
0
      || (in_attr[tag].s != NULL && out_attr[tag].s != NULL
694
0
    && strcmp (in_attr[tag].s, out_attr[tag].s) != 0))
695
0
    {
696
0
      out_attr[tag].i = 0;
697
0
      out_attr[tag].s = NULL;
698
0
    }
699
700
0
  return result;
701
0
}
702
703
/* Merge the lists of unknown processor-specific attributes, outside
704
   the known range, from IBFD into OBFD; return TRUE if the link is
705
   OK, FALSE if it must fail.  */
706
707
bool
708
_bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd)
709
0
{
710
0
  obj_attribute_list *in_list;
711
0
  obj_attribute_list *out_list;
712
0
  obj_attribute_list **out_listp;
713
0
  bool result = true;
714
715
0
  in_list = elf_other_obj_attributes_proc (ibfd);
716
0
  out_listp = &elf_other_obj_attributes_proc (obfd);
717
0
  out_list = *out_listp;
718
719
0
  for (; in_list || out_list; )
720
0
    {
721
0
      bfd *err_bfd = NULL;
722
0
      unsigned int err_tag = 0;
723
724
      /* The tags for each list are in numerical order.  */
725
      /* If the tags are equal, then merge.  */
726
0
      if (out_list && (!in_list || in_list->tag > out_list->tag))
727
0
  {
728
    /* This attribute only exists in obfd.  We can't merge, and we don't
729
       know what the tag means, so delete it.  */
730
0
    err_bfd = obfd;
731
0
    err_tag = out_list->tag;
732
0
    *out_listp = out_list->next;
733
0
    out_list = *out_listp;
734
0
  }
735
0
      else if (in_list && (!out_list || in_list->tag < out_list->tag))
736
0
  {
737
    /* This attribute only exists in ibfd. We can't merge, and we don't
738
       know what the tag means, so ignore it.  */
739
0
    err_bfd = ibfd;
740
0
    err_tag = in_list->tag;
741
0
    in_list = in_list->next;
742
0
  }
743
0
      else /* The tags are equal.  */
744
0
  {
745
    /* As present, all attributes in the list are unknown, and
746
       therefore can't be merged meaningfully.  */
747
0
    err_bfd = obfd;
748
0
    err_tag = out_list->tag;
749
750
    /*  Only pass on attributes that match in both inputs.  */
751
0
    if (in_list->attr.i != out_list->attr.i
752
0
        || (in_list->attr.s == NULL) != (out_list->attr.s == NULL)
753
0
        || (in_list->attr.s && out_list->attr.s
754
0
      && strcmp (in_list->attr.s, out_list->attr.s) != 0))
755
0
      {
756
        /* No match.  Delete the attribute.  */
757
0
        *out_listp = out_list->next;
758
0
        out_list = *out_listp;
759
0
      }
760
0
    else
761
0
      {
762
        /* Matched.  Keep the attribute and move to the next.  */
763
0
        out_list = out_list->next;
764
0
        in_list = in_list->next;
765
0
      }
766
0
  }
767
768
0
      if (err_bfd)
769
0
  result = result
770
0
    && get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd,
771
0
                       err_tag);
772
0
    }
773
774
0
  return result;
775
0
}