Coverage Report

Created: 2026-03-10 08:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/bfd/elf-attrs.c
Line
Count
Source
1
/* ELF attributes support (based on ARM EABI attributes).
2
   Copyright (C) 2005-2026 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
/* Design note regarding the merge of Object Attributes v2 during linkage
22
23
   Entry point: _bfd_elf_link_setup_object_attributes
24
25
   The linker is an "advanced" consumer of OAv2.  After parsing, it deduplicates
26
   them, merges them, detects any compatibility issues, and finally translates
27
   them to GNU properties.
28
29
   ** Overall design
30
31
   The OAv2 processing pipeline follows a map-reduce pattern.  Obviously, the
32
   actual processing in GNU ld is not multi-threaded, and the operations are not
33
   necessarily executed directly one after another.
34
35
   * Phase 1, map: successive per-file operations applied on the list of
36
     compatible input objects.
37
     1. Parsing of the OAv2 section's data (also used by objcopy).
38
     2. Translation of relevant GNU properties to OAv2. This is required for the
39
        backward-compatibility with input objects only marked using GNU
40
        properties.
41
     3. Sorting of the subsections and object attributes. Further operations
42
        rely on the ordering to perform some optimization in the processing of
43
        the data.
44
     4. Deduplication of subsections and object attributes, and detection of any
45
        conflict between duplicated subsections or tags.
46
     5. Translation of relevant OAv2 to GNU properties for a forward
47
        -compatibility with the GNU properties merge.
48
     6. Marking of unknown subsections to skip them during the merge (in
49
        phase 2), and to prune them before the output object's serialization
50
        (in phase 3).
51
52
   * Phase 2, reduce: OAv2 in input objects are merged together.
53
     1. Gathering of "frozen" values (=coming from the command-line arguments)
54
        into a virtual read-only list of subsections and attributes.
55
     2. Merging of OAv2 from an input file and the frozen input.
56
     3. Merging of the results of step 2 together. Since the OAv2 merge is
57
        commutative and associative, it can be implemented as a reduce.
58
        However, GNU ld implements it as an accumulate because it does not
59
        support multithreading.
60
     Notes: the two merge phases also perform a marking of unsupported / invalid
61
     subsections and attributes.  This marking can be used for debugging, and
62
     also more practically to drop unsupported optional subsections from the
63
     output.
64
65
   * Phase 3, finalization of the output.
66
     1. Pruning of the unknown / unsupported / invalid subsections and
67
        attributes.
68
     2. Serialization of OAv2 data (also used by objcopy).
69
     Notes:
70
      - There is no translation of the merged OAv2 to GNU properties at this
71
        stage, as the GNU properties merge process has already all the needed
72
        information (translated in step 5 of stage 1) to produce the GNU
73
        properties.
74
      - The GNU properties are currently required as the runtime linker does
75
        not understand OAv2 yet.
76
      - Phase 3 should also include a compatibility check between the final
77
        merge result of the current link unit and input shared objects.  I opted
78
        for postponing this compatibility check, and GNU properties merge will
79
        take care of it as it already does.
80
81
   The Object Ottributes merge process must handle both optional and required
82
   subsections.  It also treats the first merge of the frozen set specially, as
83
   the OAv2 list in the input BFD serves as the accumulator for subsequent
84
   merges.
85
86
   ** Optional subsections
87
88
   Optional subsections are processed as if merging two ordered sets — by
89
   iterating linearly through both, checking whether an element of a given
90
   ordinality is present in the opposite set, and adding it to the accumulator.
91
   The added diffuculty with subsections and attributes lies in the fact that
92
   missing elements have default values, and these must be merged with existing
93
   ones to produce the final value to be stored.
94
95
   ** Required subsections
96
97
   Required subsections are processed slightly differently from the optional
98
   subsections, as they cannot be pruned since they are mandatory, hence an
99
   error will be raised by the linker if it is not recognized.
100
101
   For now, the subsection for PAuth ABI is the only one use case, and no merge
102
   is applied on the values.  The values simply need to match.
103
   This implementation choice might be challenged in the future if required
104
   subsections can have the same diversity as optional subsections.  If the case
105
   arises, the refactoring to handle this new behavior should consist in adding
106
   a new merge policy MERGE-EQUAL, or something similar.  Some "if required"
107
   should be added in the optional subsections merge logic to error on any
108
   missing elements, or mismatch, and messages should also be rephrased to point
109
   out that the error is for a required subsection.
110
111
   ** Important note regarding support for testing
112
113
   In order to test this generic logic, AArch64's use cases are not offering
114
   enough coverage, so a "GNU testing namespace" which corresponds to the name
115
   of the subsection was introduced.  It follows the following pattern:
116
     gnu_testing_<XXXXXX>_MERGE_<POLICY>
117
   with:
118
     - <XXXXXX>: an arbitrary name for your testing subsection.
119
     - <POLICY>: the name of the merging policy to apply on the values in the
120
       subsection.  The currently supported merge policy are:
121
         * _MERGE_AND: bitwise AND applied on numerical values.
122
         * _MERGE_OR: bitwise OR applied on numerical values.
123
         * _MERGE_ADD: concatenates strings together with a '+' in-between.
124
       Note: "_MERGE_ADD" does not make really sense, and will very likely never
125
       be used for a real merge.  Its only purpose is to test the correct
126
       handling of merges with strings.
127
   Any subsection name matching neither names supported by the backend, nor
128
   following the pattern corresponding GNU testing namespace will be considered
129
   unknown and its status set to obj_attr_subsection_v2_unknown.  This will have
130
   for consequence the pruning of this subsection.
131
132
   Additionally, the first two tags in gnu_testing namespace, GNUTestTag_0 and
133
   GNUTestTag_1, are known, and so have a name and can be initialized to the
134
   default value ('0' or NULL) depending on the encoding specified on the
135
   subsection.  Any tags above 1 will be considered unknown, so will be default
136
   -initialized in the same way but its status will be set to obj_attr_v2_unknown.
137
   This behavior of the testing tags allows to test the pruning of unknown
138
   attributes.  */
139
140
#include "sysdep.h"
141
#include "bfd.h"
142
#include "doubly-linked-list.h"
143
#include "libiberty.h"
144
#include "libbfd.h"
145
#include "elf-bfd.h"
146
147
/* Decode the encoded version number corresponding to the Object Attribute
148
   version.  Return the version on success, UNSUPPORTED on failure.  */
149
obj_attr_version_t
150
_bfd_obj_attrs_version_dec (uint8_t encoded_version)
151
2.39k
{
152
2.39k
  if (encoded_version == 'A')
153
2.18k
    return OBJ_ATTR_V1;
154
204
  return OBJ_ATTR_VERSION_UNSUPPORTED;
155
2.39k
}
156
157
/* Encode the Object Attribute version into a byte.  */
158
uint8_t
159
_bfd_obj_attrs_version_enc (obj_attr_version_t version)
160
0
{
161
0
  if (version == OBJ_ATTR_V1)
162
0
    return 'A';
163
0
  abort ();
164
0
}
165
166
/* Return the number of bytes needed by I in uleb128 format.  */
167
static uint32_t
168
uleb128_size (uint32_t i)
169
0
{
170
0
  uint32_t size = 1;
171
0
  while (i >= 0x80)
172
0
    {
173
0
      i >>= 7;
174
0
      size++;
175
0
    }
176
0
  return size;
177
0
}
178
179
/* Return TRUE if the attribute has the default value (0/"").  */
180
static bool
181
is_default_attr (obj_attribute *attr)
182
0
{
183
0
  if (ATTR_TYPE_HAS_ERROR (attr->type))
184
0
    return true;
185
0
  if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0)
186
0
    return false;
187
0
  if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s)
188
0
    return false;
189
0
  if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type))
190
0
    return false;
191
192
0
  return true;
193
0
}
194
195
/* Return the vendor name for a given object attributes section.  */
196
static const char *
197
obj_attr_v1_vendor_name (bfd *abfd, int vendor)
198
0
{
199
0
  return (vendor == OBJ_ATTR_PROC
200
0
    ? get_elf_backend_data (abfd)->obj_attrs_vendor
201
0
    : "gnu");
202
0
}
203
204
/* Return the size of a single attribute.  */
205
static bfd_vma
206
obj_attr_v1_size (unsigned int tag, obj_attribute *attr)
207
0
{
208
0
  bfd_vma size;
209
210
0
  if (is_default_attr (attr))
211
0
    return 0;
212
213
0
  size = uleb128_size (tag);
214
0
  if (ATTR_TYPE_HAS_INT_VAL (attr->type))
215
0
    size += uleb128_size (attr->i);
216
0
  if (ATTR_TYPE_HAS_STR_VAL (attr->type))
217
0
    size += strlen ((char *)attr->s) + 1;
218
0
  return size;
219
0
}
220
221
/* Return the size of the object attributes section for VENDOR
222
   (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
223
   for that vendor to record and the vendor is OBJ_ATTR_GNU.  */
224
static bfd_vma
225
vendor_obj_attrs_v1_size (bfd *abfd, int vendor)
226
0
{
227
0
  bfd_vma size;
228
0
  obj_attribute *attr;
229
0
  obj_attribute_list *list;
230
0
  int i;
231
0
  const char *vendor_name = obj_attr_v1_vendor_name (abfd, vendor);
232
233
0
  if (!vendor_name)
234
0
    return 0;
235
236
0
  attr = elf_known_obj_attributes (abfd)[vendor];
237
0
  size = 0;
238
0
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
239
0
    size += obj_attr_v1_size (i, &attr[i]);
240
241
0
  for (list = elf_other_obj_attributes (abfd)[vendor];
242
0
       list;
243
0
       list = list->next)
244
0
    size += obj_attr_v1_size (list->tag, &list->attr);
245
246
  /* <size> <vendor_name> NUL 0x1 <size> */
247
0
  return (size
248
0
    ? size + 10 + strlen (vendor_name)
249
0
    : 0);
250
0
}
251
252
static bfd_vma
253
oav1_section_size (bfd *abfd)
254
0
{
255
0
  bfd_vma size = 0;
256
0
  size = vendor_obj_attrs_v1_size (abfd, OBJ_ATTR_PROC);
257
0
  size += vendor_obj_attrs_v1_size (abfd, OBJ_ATTR_GNU);
258
0
  if (size > 0)
259
0
    size += sizeof (uint8_t); /* <format-version: uint8>  */
260
0
  return size;
261
0
}
262
263
/* Return the size of a single attribute.  */
264
static bfd_vma
265
oav2_attr_size (const obj_attr_v2_t *attr, obj_attr_encoding_v2_t type)
266
0
{
267
0
  bfd_vma size = uleb128_size (attr->tag);
268
0
  switch (type)
269
0
    {
270
0
    case OA_ENC_ULEB128:
271
0
      size += uleb128_size (attr->val.uint);
272
0
      break;
273
0
    case OA_ENC_NTBS:
274
0
      size += strlen (attr->val.string) + 1; /* +1 for '\0'.  */
275
0
      break;
276
0
    default:
277
0
      abort ();
278
0
    }
279
0
  return size;
280
0
}
281
282
/* Return the size of a subsection.  */
283
static bfd_vma
284
oav2_subsection_size (const obj_attr_subsection_v2_t *subsec)
285
0
{
286
0
  bfd_vma size = sizeof (uint32_t); /* <subsection-length: uint32>  */
287
0
  size += strlen (subsec->name) + 1; /* <subsection-name: NTBS>  so +1 for '\0'.  */
288
0
  size += 2 * sizeof (uint8_t); /* <optional: uint8> <encoding: uint8>  */
289
  /* <attribute>*  */
290
0
  for (const obj_attr_v2_t *attr = subsec->first;
291
0
       attr != NULL;
292
0
       attr = attr->next)
293
0
    size += oav2_attr_size (attr, subsec->encoding);
294
0
  return size;
295
0
}
296
297
/* Return the size of a object attributes section.  */
298
static bfd_vma
299
oav2_section_size (bfd *abfd)
300
0
{
301
0
  const obj_attr_subsection_v2_t *subsec
302
0
    = elf_obj_attr_subsections (abfd).first;
303
0
  if (subsec == NULL)
304
0
    return 0;
305
306
0
  bfd_vma size = sizeof (uint8_t); /* <format-version: uint8>  */
307
0
  for (; subsec != NULL; subsec = subsec->next)
308
0
    size += oav2_subsection_size (subsec);
309
0
  return size;
310
0
}
311
312
/* Return the size of the object attributes section.  */
313
bfd_vma
314
bfd_elf_obj_attr_size (bfd *abfd)
315
0
{
316
0
  obj_attr_version_t version = elf_obj_attr_version (abfd);
317
0
  switch (version)
318
0
    {
319
0
    case OBJ_ATTR_V1:
320
0
      return oav1_section_size (abfd);
321
0
    case OBJ_ATTR_V2:
322
0
      return oav2_section_size (abfd);
323
0
    case OBJ_ATTR_VERSION_NONE:
324
0
      return 0;
325
0
    default:
326
0
      abort ();
327
0
    }
328
0
}
329
330
/* Write VAL in uleb128 format to P, returning a pointer to the
331
   following byte.  */
332
static bfd_byte *
333
write_uleb128 (bfd_byte *p, uint32_t val)
334
0
{
335
0
  bfd_byte c;
336
0
  do
337
0
    {
338
0
      c = val & 0x7f;
339
0
      val >>= 7;
340
0
      if (val)
341
0
  c |= 0x80;
342
0
      *(p++) = c;
343
0
    }
344
0
  while (val);
345
0
  return p;
346
0
}
347
348
/* Write attribute ATTR to butter P, and return a pointer to the following
349
   byte.  */
350
static bfd_byte *
351
write_obj_attr_v1 (bfd_byte *p, unsigned int tag, obj_attribute *attr)
352
0
{
353
  /* Suppress default entries.  */
354
0
  if (is_default_attr (attr))
355
0
    return p;
356
357
0
  p = write_uleb128 (p, tag);
358
0
  if (ATTR_TYPE_HAS_INT_VAL (attr->type))
359
0
    p = write_uleb128 (p, attr->i);
360
0
  if (ATTR_TYPE_HAS_STR_VAL (attr->type))
361
0
    {
362
0
      int len;
363
364
0
      len = strlen (attr->s) + 1;
365
0
      memcpy (p, attr->s, len);
366
0
      p += len;
367
0
    }
368
369
0
  return p;
370
0
}
371
372
/* Write the contents of the object attributes section (length SIZE)
373
   for VENDOR to CONTENTS.  */
374
static void
375
write_vendor_obj_attrs_v1 (bfd *abfd, bfd_byte *contents, bfd_vma size,
376
         int vendor)
377
0
{
378
0
  bfd_byte *p;
379
0
  obj_attribute *attr;
380
0
  obj_attribute_list *list;
381
0
  int i;
382
0
  const char *vendor_name = obj_attr_v1_vendor_name (abfd, vendor);
383
0
  size_t vendor_length = strlen (vendor_name) + 1;
384
385
0
  p = contents;
386
0
  bfd_put_32 (abfd, size, p);
387
0
  p += 4;
388
0
  memcpy (p, vendor_name, vendor_length);
389
0
  p += vendor_length;
390
0
  *(p++) = Tag_File;
391
0
  bfd_put_32 (abfd, size - 4 - vendor_length, p);
392
0
  p += 4;
393
394
0
  attr = elf_known_obj_attributes (abfd)[vendor];
395
0
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
396
0
    {
397
0
      unsigned int tag = i;
398
0
      if (get_elf_backend_data (abfd)->obj_attrs_order)
399
0
  tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
400
0
      p = write_obj_attr_v1 (p, tag, &attr[tag]);
401
0
    }
402
403
0
  for (list = elf_other_obj_attributes (abfd)[vendor];
404
0
       list;
405
0
       list = list->next)
406
0
    p = write_obj_attr_v1 (p, list->tag, &list->attr);
407
0
}
408
409
static void
410
oav1_write_section (bfd *abfd, bfd_byte *buffer, bfd_vma size)
411
0
{
412
  /* This function should only be called for object attributes version 1.  */
413
0
  BFD_ASSERT (elf_obj_attr_version (abfd) == OBJ_ATTR_V1);
414
415
0
  bfd_byte *p = buffer;
416
417
0
  const struct elf_backend_data *be = get_elf_backend_data (abfd);
418
  /* <format-version: uint8>  */
419
0
  *(p++) = be->obj_attrs_version_enc (elf_obj_attr_version (abfd));
420
421
0
  for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
422
0
    {
423
0
      bfd_vma vendor_size = vendor_obj_attrs_v1_size (abfd, vendor);
424
0
      if (vendor_size > 0)
425
0
  write_vendor_obj_attrs_v1 (abfd, p, vendor_size, vendor);
426
0
      p += vendor_size;
427
0
    }
428
429
  /* We didn't overrun the buffer.  */
430
0
  BFD_ASSERT (p <= buffer + size);
431
0
}
432
433
static bfd_byte *
434
oav2_write_attr (bfd_byte *p,
435
     const obj_attr_v2_t *attr,
436
     obj_attr_encoding_v2_t type)
437
0
{
438
0
  p = write_uleb128 (p, attr->tag);
439
0
  switch (type)
440
0
    {
441
0
    case OA_ENC_ULEB128:
442
0
      p = write_uleb128 (p, attr->val.uint);
443
0
      break;
444
0
    case OA_ENC_NTBS:
445
      /* +1 for '\0'.  */
446
0
      p = (bfd_byte *) stpcpy ((char *) p, attr->val.string) + 1;
447
0
      break;
448
0
    default:
449
0
      abort ();
450
0
    }
451
0
  return p;
452
0
}
453
454
static bfd_byte *
455
oav2_write_subsection (bfd *abfd,
456
           const obj_attr_subsection_v2_t *subsec,
457
           bfd_byte *p)
458
0
{
459
  /* <subsection-length: uint32>  */
460
0
  bfd_vma subsec_size = oav2_subsection_size (subsec);
461
0
  bfd_put_32 (abfd, subsec_size, p);
462
0
  p += sizeof (uint32_t);
463
464
  /* <vendor-name: NTBS>  */
465
0
  size_t vendor_name_size = strlen (subsec->name) + 1; /* +1 for '\0'.  */
466
0
  memcpy (p, subsec->name, vendor_name_size);
467
0
  p += vendor_name_size;
468
469
  /* -- <vendor-data: bytes> --  */
470
  /* <optional: uint8>  */
471
0
  bfd_put_8 (abfd, subsec->optional, p);
472
0
  ++p;
473
  /* <encoding: uint8>  */
474
0
  bfd_put_8 (abfd, obj_attr_encoding_v2_to_u8 (subsec->encoding), p);
475
0
  ++p;
476
  /* <attribute>*  */
477
0
  for (const obj_attr_v2_t *attr = subsec->first;
478
0
       attr != NULL;
479
0
       attr = attr->next)
480
0
    p = oav2_write_attr (p, attr, subsec->encoding);
481
0
  return p;
482
0
}
483
484
static bfd_vma
485
oav2_write_section (bfd *abfd, bfd_byte *buffer, bfd_vma size)
486
0
{
487
  /* This function should only be called for object attributes version 2.  */
488
0
  BFD_ASSERT (elf_obj_attr_version (abfd) == OBJ_ATTR_V2);
489
490
0
  bfd_vma section_size = oav2_section_size (abfd);
491
0
  if (section_size == 0)
492
0
    return 0;
493
494
0
  bfd_byte *p = buffer;
495
496
0
  const struct elf_backend_data *be = get_elf_backend_data (abfd);
497
  /* <format-version: uint8>  */
498
0
  *(p++) = be->obj_attrs_version_enc (elf_obj_attr_version (abfd));
499
500
  /* [ <subsection-length: uint32> <vendor-name: NTBS> <vendor-data: bytes> ]*  */
501
0
  for (const obj_attr_subsection_v2_t *subsec
502
0
   = elf_obj_attr_subsections (abfd).first;
503
0
       subsec != NULL;
504
0
       subsec = subsec->next)
505
0
    p = oav2_write_subsection (abfd, subsec, p);
506
507
  /* We didn't overrun the buffer.  */
508
0
  BFD_ASSERT (p <= buffer + size);
509
  /* We wrote as many data as it was computed by
510
     vendor_section_obj_attr_using_subsections_size().  */
511
0
  BFD_ASSERT (section_size == (bfd_vma) (p - buffer));
512
513
0
  return section_size;
514
0
}
515
516
static void
517
oav2_sort_subsections (obj_attr_subsection_list_t *plist)
518
0
{
519
0
  for (obj_attr_subsection_v2_t *subsec = plist->first;
520
0
       subsec != NULL;
521
0
       subsec = subsec->next)
522
0
    LINKED_LIST_MERGE_SORT (obj_attr_v2_t) (subsec, _bfd_elf_obj_attr_v2_cmp);
523
524
0
  LINKED_LIST_MERGE_SORT (obj_attr_subsection_v2_t)
525
0
    (plist, _bfd_elf_obj_attr_subsection_v2_cmp);
526
0
}
527
528
/* Write the contents of the object attributes section to CONTENTS.  */
529
void
530
bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *buffer, bfd_vma size)
531
0
{
532
0
  if (! abfd->is_linker_output
533
0
      && elf_obj_attr_version (abfd) == OBJ_ATTR_V2)
534
    /* Before dumping the data, sort subsections in alphabetical order, and
535
       attributes according to their tag in numerical order.  This is useful
536
       for diagnostic tools so that they dump the same output even if the
537
       subsections or their attributes were not declared in the same order in
538
       different files.
539
       This sorting is only performed in the case of the assembler.  In the
540
       case of the linker, the subsections and attributes are already sorted
541
       by the merge process.  */
542
0
    oav2_sort_subsections (&elf_obj_attr_subsections (abfd));
543
544
0
  obj_attr_version_t version = elf_obj_attr_version (abfd);
545
0
  switch (version)
546
0
    {
547
0
    case OBJ_ATTR_V1:
548
0
      oav1_write_section (abfd, buffer, size);
549
0
      break;
550
0
    case OBJ_ATTR_V2:
551
0
      oav2_write_section (abfd, buffer, size);
552
0
      break;
553
0
    default:
554
0
      abort ();
555
0
    }
556
0
}
557
558
/* The first two tags in gnu-testing namespace are known (from the perspective
559
   of GNU ld), and so have a name and can be initialized to the default value
560
   ('0' or NULL) depending on the encoding specified on the subsection.  Any
561
   tags above 1 will be considered unknown, so will be default initialized in
562
   the same way but its status will be set to obj_attr_subsection_v2_unknown.
563
   If the tag is unknown, ld can drop it if it is inside an optional subsection,
564
   whereas ld will raise an error in a required subsection.
565
   Note: the array below has to be sorted by the tag's integer value.  */
566
static const obj_attr_info_t known_attrs_gnu_testing[] =
567
{
568
  { .tag = {"GNUTestTag_0", 0} },
569
  { .tag = {"GNUTestTag_1", 1} },
570
};
571
572
/* List of known GNU subsections.
573
   Note: this array has to be sorted using the same criteria as in
574
   _bfd_elf_obj_attr_subsection_v2_cmp().  */
575
static const known_subsection_v2_t obj_attr_v2_known_gnu_subsections[] =
576
{
577
  {
578
    /* Note: the currently set values for the subsection name, its optionality,
579
       and encoding are irrelevant for a testing subsection.  These values are
580
       unused.  This entry is only a placeholder for list of known GNU testing
581
       tags.  */
582
    .subsec_name = NULL,
583
    .known_attrs = known_attrs_gnu_testing,
584
    .optional = true,
585
    .encoding = OA_ENC_ULEB128,
586
    .len = ARRAY_SIZE (known_attrs_gnu_testing),
587
  },
588
  /* Note for the future: GNU subsections can be added here below.  */
589
};
590
591
/* Return True if the given subsection name is part of the reserved testing
592
   namespace, i.e. SUBSEC_NAME begins with "gnu-testing".  */
593
static bool
594
gnu_testing_namespace (const char *subsec_name)
595
19
{
596
19
  return strncmp ("gnu_testing_", subsec_name, 12) == 0;
597
19
}
598
599
/* Identify the scope of a subsection from its name.
600
   Note: the code below needs to be kept in sync with the code of
601
   elf_parse_attrs_subsection_v2() in binutils/readelf.c.  */
602
obj_attr_subsection_scope_v2_t
603
bfd_elf_obj_attr_subsection_v2_scope (const bfd *abfd, const char *subsec_name)
604
287
{
605
287
  const char *vendor_name = get_elf_backend_data (abfd)->obj_attrs_vendor;
606
287
  obj_attr_subsection_scope_v2_t scope = OA_SUBSEC_PRIVATE;
607
287
  size_t vendor_name_len = strlen (vendor_name);
608
287
  if ((strncmp (subsec_name, vendor_name, vendor_name_len) == 0
609
9
       && subsec_name[vendor_name_len] == '_')
610
287
      || (strncmp (subsec_name, "gnu_", 4) == 0
611
19
    && !gnu_testing_namespace (subsec_name)))
612
19
    scope = OA_SUBSEC_PUBLIC;
613
287
  return scope;
614
287
}
615
616
/* Search for a subsection matching NAME in the list of subsections known from
617
   bfd (generic or backend-specific).  Return the subsection information if it
618
   is found, or NULL otherwise.  */
619
const known_subsection_v2_t *
620
bfd_obj_attr_v2_identify_subsection (const struct elf_backend_data *bed,
621
             const char *name)
622
0
{
623
  /* Check known backend subsections.  */
624
0
  const known_subsection_v2_t *known_subsections
625
0
    = bed->obj_attr_v2_known_subsections;
626
0
  const size_t known_subsections_size = bed->obj_attr_v2_known_subsections_size;
627
628
0
  for (unsigned i = 0; i < known_subsections_size; ++i)
629
0
    {
630
0
      int cmp = strcmp (known_subsections[i].subsec_name, name);
631
0
      if (cmp == 0)
632
0
  return &known_subsections[i];
633
0
      else if (cmp > 0)
634
0
  break;
635
0
    }
636
637
  /* Check known GNU subsections.  */
638
  /* Note for the future: search known GNU subsections here.  Don't forget to
639
     skip the first entry (placeholder for GNU testing subsection).  */
640
641
  /* Check whether this subsection is a GNU testing subsection.  */
642
0
  if (gnu_testing_namespace (name))
643
0
    return &obj_attr_v2_known_gnu_subsections[0];
644
645
0
  return NULL;
646
0
}
647
648
/* Search for the attribute information associated to TAG in the list of known
649
   tags registered in the known subsection SUBSEC.  Return the tag information
650
   if it is found, NULL otherwise.  */
651
static const obj_attr_info_t *
652
identify_tag (const known_subsection_v2_t *subsec, obj_attr_tag_t tag)
653
0
{
654
0
  for (unsigned i = 0; i < subsec->len; ++i)
655
0
    {
656
0
      const obj_attr_info_t *known_attr = &subsec->known_attrs[i];
657
0
      if (known_attr->tag.value == tag)
658
0
  return known_attr;
659
0
      else if (known_attr->tag.value > tag)
660
0
  break;
661
0
    }
662
0
  return NULL;
663
0
}
664
665
/* Return the attribute information associated to the pair SUBSEC, TAG if it
666
   exists, NULL otherwise.  */
667
const obj_attr_info_t *
668
_bfd_obj_attr_v2_find_known_by_tag (const struct elf_backend_data *bed,
669
            const char *subsec_name,
670
            obj_attr_tag_t tag)
671
0
{
672
0
  const known_subsection_v2_t *subsec_info
673
0
    = bfd_obj_attr_v2_identify_subsection (bed, subsec_name);
674
0
  if (subsec_info != NULL)
675
0
    return identify_tag (subsec_info, tag);
676
0
  return NULL;
677
0
}
678
679
/* To-string function for the pair <SUBSEC, TAG>.
680
   Returns the attribute information associated to TAG if it is found,
681
   or "Tag_unknown_<N>" otherwise.  */
682
const char *
683
_bfd_obj_attr_v2_tag_to_string (const struct elf_backend_data *bed,
684
        const char *subsec_name,
685
        obj_attr_tag_t tag)
686
0
{
687
0
  const obj_attr_info_t *attr_info
688
0
    = _bfd_obj_attr_v2_find_known_by_tag (bed, subsec_name, tag);
689
0
  if (attr_info != NULL)
690
0
    return xstrdup (attr_info->tag.name);
691
0
  return xasprintf ("Tag_unknown_%"PRIu64, tag);
692
0
}
693
694
/* To-string function for the subsection parameter "comprehension".  */
695
const char *
696
bfd_oav2_comprehension_to_string (bool comprehension)
697
0
{
698
0
  return comprehension ? "optional" : "required";
699
0
}
700
701
/* To-string function for the subsection parameter "encoding".  */
702
const char *
703
bfd_oav2_encoding_to_string (obj_attr_encoding_v2_t encoding)
704
0
{
705
0
  return (encoding == OA_ENC_ULEB128) ? "ULEB128" : "NTBS";
706
0
}
707
708
/* Return True if the given BFD is an ELF object with the target backend
709
   machine code, non-dynamic (i.e. not a shared library), non-executable, not a
710
   plugin or created by the linker.  False otherwise.  */
711
static bool
712
oav2_relevant_elf_object (const struct bfd_link_info *info,
713
        const bfd *const abfd)
714
0
{
715
0
  const struct elf_backend_data *output_bed
716
0
    = get_elf_backend_data (info->output_bfd);
717
0
  unsigned int elfclass = output_bed->s->elfclass;
718
0
  int elf_machine_code = output_bed->elf_machine_code;
719
0
  return ((abfd->flags & (DYNAMIC | EXEC_P | BFD_PLUGIN | BFD_LINKER_CREATED)) == 0
720
0
    && bfd_get_flavour (abfd) == bfd_target_elf_flavour
721
0
    && elf_machine_code == get_elf_backend_data (abfd)->elf_machine_code
722
0
    && elfclass == get_elf_backend_data (abfd)->s->elfclass);
723
0
}
724
725
/* Structure storing the result of a search in the list of input BFDs.  */
726
typedef struct
727
{
728
  /* A pointer to a BFD.  This BFD can either point to a file having
729
     object attributes, or a candidate file which does not have any.  */
730
  bfd *pbfd;
731
732
  /* A boolean indicating whether the file actually contains object
733
     attributes.  */
734
  bool has_object_attributes;
735
736
  /* A pointer to the section containing the object attributes, if any
737
     were found.  */
738
  asection *sec;
739
} bfd_search_result_t;
740
741
/* Checks whether a BFD contains object attributes, and if so search for the
742
   relevant section storing them.  The name and type of the section have to
743
   match with what the backend expects, i.e. elf_backend_obj_attrs_section and
744
   elf_backend_obj_attrs_section_type, otherwise the object attributes section
745
   won't be recognized as such, and will be skipped.
746
   Return True if an object attribute section is found, False otherwise.  */
747
static bool
748
input_bfd_has_object_attributes (const struct bfd_link_info *info,
749
         bfd *abfd,
750
         bfd_search_result_t *res)
751
0
{
752
  /* The file may contain object attributes.  Save this candidate.  */
753
0
  res->pbfd = abfd;
754
755
0
  if (elf_obj_attr_subsections (abfd).size == 0)
756
0
    return false;
757
758
0
  res->has_object_attributes = true;
759
760
0
  uint32_t sec_type = get_elf_backend_data (abfd)->obj_attrs_section_type;
761
0
  const char *sec_name = get_elf_backend_data (abfd)->obj_attrs_section;
762
0
  res->sec = bfd_get_section_by_name (abfd, sec_name);
763
0
  if (res->sec != NULL)
764
0
    {
765
0
      if (elf_section_type (res->sec) != sec_type)
766
0
  {
767
0
    info->callbacks->minfo
768
0
      (_("%X%pB: warning: ignoring section '%s' with unexpected type %#x\n"),
769
0
       abfd, sec_name, elf_section_type (res->sec));
770
0
    res->sec = NULL;
771
0
  }
772
0
    }
773
0
  return (res->sec != NULL);
774
0
}
775
776
/* Search for the first input object file containing object attributes.
777
   If no such object is found, the result structure's PBFD points to the
778
   last object file that could have contained object attributes.  The
779
   result structure's HAS_OBJECT_ATTRIBUTES allows to distinguish the
780
   cases when PBFD contains or does not contain object attributes.  If no
781
   candidate file is found, PBFD will stay NULL.  */
782
static bfd_search_result_t
783
bfd_linear_find_first_with_obj_attrs (const struct bfd_link_info *info)
784
0
{
785
0
  bfd_search_result_t res = { .has_object_attributes = false };
786
0
  for (bfd *abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
787
0
    {
788
0
      if (oav2_relevant_elf_object (info, abfd)
789
0
    && abfd->section_count != 0
790
0
    && input_bfd_has_object_attributes (info, abfd, &res))
791
0
  break;
792
0
    }
793
0
  return res;
794
0
}
795
796
/* Create a object attributes section for the given bfd input.  */
797
static asection *
798
create_object_attributes_section (struct bfd_link_info *info,
799
          bfd *abfd)
800
0
{
801
0
  asection *sec;
802
0
  const char *sec_name = get_elf_backend_data (abfd)->obj_attrs_section;
803
0
  sec = bfd_make_section_with_flags (abfd,
804
0
             sec_name,
805
0
             (SEC_READONLY
806
0
              | SEC_HAS_CONTENTS
807
0
              | SEC_DATA));
808
0
  if (sec == NULL)
809
0
    info->callbacks->fatal (_("%P: failed to create %s section\n"), sec_name);
810
811
0
  if (!bfd_set_section_alignment (sec, 2))
812
0
    info->callbacks->fatal (_("%pA: failed to align section\n"), sec);
813
814
0
  elf_section_type (sec) = get_elf_backend_data (abfd)->obj_attrs_section_type;
815
816
0
  bfd_set_section_size (sec, bfd_elf_obj_attr_size (abfd));
817
818
0
  return sec;
819
0
}
820
821
/* Translate GNU properties that have object attributes v2 equivalents.  */
822
static void
823
oav2_translate_gnu_props_to_obj_attrs (const bfd *abfd)
824
0
{
825
0
  const struct elf_backend_data *be = get_elf_backend_data (abfd);
826
0
  if (be->translate_gnu_props_to_obj_attrs == NULL)
827
0
    return;
828
829
0
  for (const elf_property_list *p = elf_properties (abfd);
830
0
       p != NULL;
831
0
       p = p->next)
832
0
    be->translate_gnu_props_to_obj_attrs (abfd, p);
833
0
}
834
835
/* Translate object attributes v2 that have GNU properties equivalents.  */
836
static void
837
oav2_translate_obj_attrs_to_gnu_props (bfd *abfd)
838
0
{
839
0
  const struct elf_backend_data *be = get_elf_backend_data (abfd);
840
0
  if (be->translate_obj_attrs_to_gnu_props == NULL)
841
0
    return;
842
843
0
  for (const obj_attr_subsection_v2_t *subsec
844
0
   = elf_obj_attr_subsections (abfd).first;
845
0
       subsec != NULL;
846
0
       subsec = subsec->next)
847
0
    be->translate_obj_attrs_to_gnu_props (abfd, subsec);
848
0
}
849
850
/* Compact duplicated tag declarations in a subsection.
851
   Return True on success, False if any issue is found during the compaction,
852
   i.e. conflicting values for the same tag.  */
853
static bool
854
oav2_compact_tags (const bfd *abfd, obj_attr_subsection_v2_t *subsec)
855
0
{
856
0
  bool success = true;
857
858
0
  for (obj_attr_v2_t *a = subsec->first;
859
0
       a != NULL && a->next != NULL;)
860
0
    {
861
0
      if (a->tag != a->next->tag)
862
0
  {
863
0
    a = a->next;
864
0
    continue;
865
0
  }
866
867
      /* For NTBS encoding, ensure that the string value of the attributes is
868
   not NULL.
869
   Note: a string attribute can only be NULL if it was created during the
870
   merge process.  Since tag compaction occurs before merging begins, this
871
   assertion guarantees that the function is never called in a context
872
   where the assumption does not hold.  */
873
0
      BFD_ASSERT
874
0
  (subsec->encoding == OA_ENC_ULEB128 ||
875
0
   (a->val.string != NULL && a->next->val.string != NULL));
876
877
      /* Values of a tag are the same, we remove the duplicate.  */
878
0
      if ((subsec->encoding == OA_ENC_ULEB128
879
0
     && a->val.uint == a->next->val.uint)
880
0
    || (subsec->encoding == OA_ENC_NTBS
881
0
        && strcmp (a->val.string, a->next->val.string) == 0))
882
0
  {
883
0
    obj_attr_v2_t *dup_attr = a->next;
884
0
    LINKED_LIST_REMOVE (obj_attr_v2_t) (subsec, dup_attr);
885
0
    _bfd_elf_obj_attr_v2_free (dup_attr, subsec->encoding);
886
0
    continue;
887
0
  }
888
889
      /* The values of a tag are different, there are various options:
890
   - the tag values can be merged.  This requires a knowledge of a tag
891
     merge policy, sometimes generic, sometimes only known from the
892
     target backend.  Since no such complex case exists for now, it is
893
     not implemented.
894
   - values for a given tag have to be the same in the same subsection,
895
     or it raises an error.  This will be the default handling for now.  */
896
0
      success = false;
897
898
0
      const char *tag_s = _bfd_obj_attr_v2_tag_to_string
899
0
  (get_elf_backend_data (abfd), subsec->name, a->tag);
900
901
0
      if (subsec->encoding == OA_ENC_ULEB128)
902
0
  _bfd_error_handler
903
0
    (_("%pB: error: found duplicated attributes '%s' with conflicting "
904
0
       "values (%#x vs %#x) in subsection %s"),
905
0
     abfd, tag_s, a->val.uint, a->next->val.uint, subsec->name);
906
0
      else /* (subsec->encoding == OA_ENC_NTBS)  */
907
0
  _bfd_error_handler
908
0
    (_("%pB: error: found duplicated attributes '%s' with conflicting "
909
0
       "values ('%s' vs '%s') in subsection %s"),
910
0
     abfd, tag_s, a->val.string, a->next->val.string, subsec->name);
911
912
0
      free ((char *) tag_s);
913
914
      /* We skip the tag, and continue the compaction of tags to find further
915
   issues (if any).  */
916
0
      a = a->next;
917
0
    }
918
919
0
  return success;
920
0
}
921
922
/* Merge two subsections together (object attributes v2 only).
923
   The result is stored into subsec1.  subsec2 is destroyed.
924
   Return true if the merge was successful, false otherwise.
925
   Note: subsec1 and subsec2 are expected to be sorted before the call to this
926
   function.  */
927
static bool
928
oav2_subsection_destructive_merge (const bfd *abfd,
929
           obj_attr_subsection_v2_t *subsec1,
930
           obj_attr_subsection_v2_t *subsec2)
931
0
{
932
0
  BFD_ASSERT (subsec1->encoding == subsec2->encoding
933
0
        && subsec1->optional == subsec2->optional);
934
935
0
  bool success = true;
936
937
0
  success &= oav2_compact_tags (abfd, subsec1);
938
0
  success &= oav2_compact_tags (abfd, subsec2);
939
940
0
  obj_attr_v2_t *a1 = subsec1->first;
941
0
  obj_attr_v2_t *a2 = subsec2->first;
942
0
  while (a1 != NULL && a2 != NULL)
943
0
    {
944
0
      if (a1->tag < a2->tag)
945
0
  {} /* Nothing to do, a1 is already in subsec1.  */
946
0
      else if (a1->tag > a2->tag)
947
0
  {
948
    /* a2 is missing in subsec1, add it.  */
949
0
    obj_attr_v2_t *previous
950
0
      = LINKED_LIST_REMOVE (obj_attr_v2_t) (subsec2, a2);
951
0
    LINKED_LIST_INSERT_BEFORE (obj_attr_v2_t) (subsec1, a2, a1);
952
0
    a2 = previous;
953
0
  }
954
0
      else
955
0
  {
956
0
    const char *tag_s = NULL;
957
0
    if (subsec1->encoding == OA_ENC_ULEB128
958
0
        && a1->val.uint != a2->val.uint)
959
0
      {
960
0
        success = false;
961
0
        tag_s = _bfd_obj_attr_v2_tag_to_string
962
0
    (get_elf_backend_data (abfd), subsec1->name, a1->tag);
963
0
        _bfd_error_handler
964
0
    (_("%pB: error: found 2 subsections with the same name '%s' "
965
0
       "and found conflicting values (%#x vs %#x) for object "
966
0
       "attribute '%s'"),
967
0
     abfd, subsec1->name, a1->val.uint, a2->val.uint, tag_s);
968
0
      }
969
0
    else if (subsec1->encoding == OA_ENC_NTBS
970
0
       && strcmp (a1->val.string, a2->val.string) != 0)
971
0
      {
972
0
        success = false;
973
0
        tag_s = _bfd_obj_attr_v2_tag_to_string
974
0
    (get_elf_backend_data (abfd), subsec1->name, a1->tag);
975
0
        _bfd_error_handler
976
0
    (_("%pB: error: found 2 subsections with the same name '%s' "
977
0
       "and found conflicting values ('%s' vs '%s') for object "
978
0
       "attribute '%s"),
979
0
     abfd, subsec1->name, a1->val.string, a2->val.string, tag_s);
980
0
      }
981
0
    free ((char *) tag_s);
982
0
  }
983
0
      a1 = a1->next;
984
0
      a2 = a2->next;
985
0
    }
986
987
0
  for (; a2 != NULL; a2 = a2->next)
988
0
    {
989
      /* a2 is missing in subsec1, add it.  */
990
0
      obj_attr_v2_t *previous
991
0
  = LINKED_LIST_REMOVE (obj_attr_v2_t) (subsec2, a2);
992
0
      LINKED_LIST_INSERT_BEFORE (obj_attr_v2_t) (subsec1, a2, a1);
993
0
      a2 = previous;
994
0
    }
995
996
  /* If a1 != NULL, we don't care since it is already in subsec1.  */
997
998
  /* Destroy subsec2 before exiting.  */
999
0
  _bfd_elf_obj_attr_subsection_v2_free (subsec2);
1000
1001
0
  return success;
1002
0
}
1003
1004
/* Merge duplicated subsections and object attributes inside a same object
1005
   file.  After a call to this function, the subsections and object attributes
1006
   are sorted.
1007
   Note: this function allows to handle in a best effort exotic objects produced
1008
   by a non-GNU assembler.  Duplicated subsections could come from the same
1009
   section, or different ones.  Indeed, the deserializer deserializes the
1010
   content of a section if its type matches the object attributes type specified
1011
   by the backend, regardless of the section name.  The behavior for such cases
1012
   is not specified by the Object Attributes specification, and are a question
1013
   of implementation.  Non-GNU linkers might have a different behavior with such
1014
   exotic objects. */
1015
static bool
1016
oav2_file_scope_merge_subsections (const bfd *abfd)
1017
0
{
1018
0
  obj_attr_subsection_list_t *subsecs = &elf_obj_attr_subsections (abfd);
1019
1020
  /* Sort all the subsections and object attributes as they might not have been
1021
     inserted in the right order.  From now on, the subsections and attributes
1022
     will be assumed to be always sorted.  Any additive mutation will need to
1023
     preserve the order.  */
1024
0
  oav2_sort_subsections (subsecs);
1025
1026
0
  bool success = true;
1027
1028
0
  obj_attr_subsection_v2_t *subsec = subsecs->first;
1029
0
  while (subsec != NULL && subsec->next != NULL)
1030
0
    {
1031
0
      obj_attr_subsection_v2_t *dup_subsec
1032
0
  = bfd_obj_attr_subsection_v2_find_by_name (subsec->next,
1033
0
               subsec->name,
1034
0
               false);
1035
0
      if (dup_subsec != NULL)
1036
0
  {
1037
0
    LINKED_LIST_REMOVE (obj_attr_subsection_v2_t) (subsecs, dup_subsec);
1038
0
    success &= oav2_subsection_destructive_merge (abfd, subsec, dup_subsec);
1039
0
  }
1040
0
      else
1041
0
  subsec = subsec->next;
1042
0
    }
1043
1044
0
  return success;
1045
0
}
1046
1047
/* If an Object Attribute subsection inside ABFD cannot be identified neither
1048
   as a GNU subsection or a backend-specific one, set the status of this
1049
   subsection to UNKNOWN.  The unknown subsection will be skipped during the
1050
   merge process, and will be pruned from the output.  */
1051
static void
1052
oav2_subsections_mark_unknown (const bfd *abfd)
1053
0
{
1054
0
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1055
0
  for (obj_attr_subsection_v2_t *subsec = elf_obj_attr_subsections (abfd).first;
1056
0
       subsec != NULL;
1057
0
       subsec = subsec->next)
1058
0
    {
1059
0
      if (bfd_obj_attr_v2_identify_subsection (bed, subsec->name) == NULL)
1060
0
  subsec->status = obj_attr_subsection_v2_unknown;
1061
0
    }
1062
0
}
1063
1064
/* Assign the merge result to REF.
1065
   The only reason to exist for this helper is when the manipulated value is a
1066
   string.  In this case, the value in REF must be freed before assigning.  */
1067
static void
1068
oav2_assign_value (obj_attr_encoding_v2_t encoding,
1069
       obj_attr_v2_t *a_ref,
1070
       union obj_attr_value_v2 res)
1071
0
{
1072
0
  if (encoding == OA_ENC_NTBS)
1073
0
    free ((void *) a_ref->val.string);
1074
0
  a_ref->val = res;
1075
0
}
1076
1077
/* Initialize the given ATTR with its default value coming from the known tag
1078
   registry.  */
1079
static void
1080
oav2_attr_overwrite_with_default (const struct bfd_link_info *info,
1081
          const obj_attr_subsection_v2_t *subsec,
1082
          obj_attr_v2_t *attr)
1083
0
{
1084
0
  const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
1085
1086
0
  union obj_attr_value_v2 default_value;
1087
0
  memset (&default_value, 0, sizeof (default_value));
1088
1089
0
  const obj_attr_info_t *attr_info
1090
0
    = _bfd_obj_attr_v2_find_known_by_tag (bed, subsec->name, attr->tag);
1091
0
  if (attr_info == NULL)
1092
0
    {
1093
0
      attr->status = obj_attr_v2_unknown;
1094
0
      oav2_assign_value (subsec->encoding, attr, default_value);
1095
0
      return;
1096
0
    }
1097
1098
0
  if (bed->obj_attr_v2_default_value != NULL
1099
0
      && bed->obj_attr_v2_default_value (info, attr_info, subsec, attr))
1100
0
    return;
1101
1102
0
  if (subsec->encoding == OA_ENC_NTBS)
1103
0
    {
1104
0
      if (attr_info->default_value.string != NULL)
1105
0
  default_value.string = xstrdup (attr_info->default_value.string);
1106
0
    }
1107
0
  else
1108
0
    default_value.uint = attr_info->default_value.uint;
1109
0
  oav2_assign_value (subsec->encoding, attr, default_value);
1110
0
}
1111
1112
/* Create a new attribute with the same key (=tag) as ATTR, and initialized with
1113
   its default value from the known tag registry.  */
1114
static obj_attr_v2_t *
1115
oav2_attr_default (const struct bfd_link_info *info,
1116
       const obj_attr_subsection_v2_t *subsec,
1117
       const obj_attr_v2_t *attr)
1118
0
{
1119
0
  obj_attr_v2_t *new_attr = _bfd_elf_obj_attr_v2_copy (attr, subsec->encoding);
1120
0
  oav2_attr_overwrite_with_default (info, subsec, new_attr);
1121
0
  return new_attr;
1122
0
}
1123
1124
/* The currently supported merge policy in the testing GNU namespace.
1125
   - bitwise AND: apply bitwise AND.
1126
   - bitwise OR: apply bitwise OR.
1127
   - String-ADD: concatenates strings together with a '+' in-between.
1128
   Note: Such policies should only be used for testing.  */
1129
typedef enum {
1130
  SUBSECTION_TESTING_MERGE_UNSUPPORTED = 0,
1131
  SUBSECTION_TESTING_MERGE_AND_POLICY = 1,
1132
  SUBSECTION_TESTING_MERGE_OR_POLICY = 2,
1133
  SUBSECTION_TESTING_MERGE_ADD_POLICY = 3,
1134
} gnu_testing_merge_policy;
1135
1136
/* Determine which merge policy will be applied to SUBSEC.  The GNU policy are
1137
   detected from the name of the subsection.  It should follow the following
1138
   pattern: "gnu_testing_XXXXXX_MERGE_<POLICY>".
1139
   Return one of the known merge policy if recognised, UNSUPPORTED otherwise.  */
1140
static gnu_testing_merge_policy
1141
gnu_testing_merge_subsection (const char *subsec_name)
1142
0
{
1143
0
  if (! gnu_testing_namespace (subsec_name))
1144
0
    return SUBSECTION_TESTING_MERGE_UNSUPPORTED;
1145
1146
0
  size_t subsec_name_len = strlen (subsec_name);
1147
0
  if (strcmp ("_MERGE_AND", subsec_name + subsec_name_len - 10) == 0)
1148
0
    return SUBSECTION_TESTING_MERGE_AND_POLICY;
1149
0
  else if (strcmp ("_MERGE_OR", subsec_name + subsec_name_len - 9) == 0)
1150
0
    return SUBSECTION_TESTING_MERGE_OR_POLICY;
1151
0
  else if (strcmp ("_MERGE_ADD", subsec_name + subsec_name_len - 10) == 0)
1152
0
    return SUBSECTION_TESTING_MERGE_ADD_POLICY;
1153
0
  else
1154
0
    return SUBSECTION_TESTING_MERGE_UNSUPPORTED;
1155
0
}
1156
1157
/* Merge policy Integer-AND: apply bitwise AND between REF and RHS.  */
1158
obj_attr_v2_merge_result_t
1159
_bfd_obj_attr_v2_merge_AND (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
1160
          const bfd *abfd ATTRIBUTE_UNUSED,
1161
          const obj_attr_subsection_v2_t *subsec,
1162
          const obj_attr_v2_t *ref, const obj_attr_v2_t *rhs,
1163
          const obj_attr_v2_t *frozen ATTRIBUTE_UNUSED)
1164
0
{
1165
0
  BFD_ASSERT (subsec->encoding == OA_ENC_ULEB128);
1166
1167
0
  obj_attr_v2_merge_result_t res;
1168
1169
0
  res.val.uint = (ref->val.uint & rhs->val.uint);
1170
0
  res.merge = (res.val.uint != ref->val.uint);
1171
0
  res.reason = (!res.merge
1172
0
    ? OAv2_MERGE_SAME_VALUE_AS_REF
1173
0
    : OAv2_MERGE_OK);
1174
1175
0
  return res;
1176
0
}
1177
1178
/* Merge policy Integer-OR: apply bitwise OR between REF and RHS.  */
1179
static obj_attr_v2_merge_result_t
1180
obj_attr_v2_merge_OR (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
1181
          const bfd *abfd ATTRIBUTE_UNUSED,
1182
          const obj_attr_subsection_v2_t *subsec,
1183
          const obj_attr_v2_t *ref, const obj_attr_v2_t *rhs,
1184
          const obj_attr_v2_t *frozen ATTRIBUTE_UNUSED)
1185
0
{
1186
0
  BFD_ASSERT (subsec->encoding == OA_ENC_ULEB128);
1187
1188
0
  obj_attr_v2_merge_result_t res;
1189
1190
0
  res.val.uint = (ref->val.uint | rhs->val.uint);
1191
0
  res.merge = (res.val.uint != ref->val.uint);
1192
0
  res.reason = (!res.merge
1193
0
    ? OAv2_MERGE_SAME_VALUE_AS_REF
1194
0
    : OAv2_MERGE_OK);
1195
1196
0
  return res;
1197
0
}
1198
1199
/* Merge policy String-ADD: concatenates strings from REF and RHS together
1200
   adding a '+' character in-between.  */
1201
static obj_attr_v2_merge_result_t
1202
obj_attr_v2_merge_ADD (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
1203
           const bfd *abfd ATTRIBUTE_UNUSED,
1204
           const obj_attr_subsection_v2_t *subsec,
1205
           const obj_attr_v2_t *ref, const obj_attr_v2_t *rhs,
1206
           const obj_attr_v2_t *frozen ATTRIBUTE_UNUSED)
1207
0
{
1208
0
  BFD_ASSERT (subsec->encoding == OA_ENC_NTBS);
1209
1210
0
  obj_attr_v2_merge_result_t res = {
1211
0
    .merge = false,
1212
0
    .val.string = NULL,
1213
0
    .reason = OAv2_MERGE_OK,
1214
0
  };
1215
1216
  /* Note: FROZEN is unused for this "concatenating" merge because it is
1217
     either passed as RHS when coming from oav2_subsections_merge_frozen(),
1218
     or passed as FROZEN when coming from oav2_subsections_merge() and was
1219
     already merged.  */
1220
1221
  /* REF and RHS have both a value.  Concatenate RHS to REF.  */
1222
0
  if (ref->val.string && rhs->val.string)
1223
0
    {
1224
0
      res.merge = true;
1225
0
      size_t ref_s_size = strlen (ref->val.string);
1226
0
      size_t rhs_s_size = strlen (rhs->val.string);
1227
0
      char *buffer = xmalloc (ref_s_size + 1 + rhs_s_size + 1);
1228
0
      res.val.string = buffer;
1229
0
      memcpy (buffer, ref->val.string, ref_s_size);
1230
0
      buffer += ref_s_size;
1231
0
      *buffer = '+';
1232
0
      ++buffer;
1233
0
      memcpy (buffer, rhs->val.string, rhs_s_size + 1);
1234
0
    }
1235
  /* REF has a value, but RHS does not.  Nothing to do.  */
1236
0
  else if (ref->val.string)
1237
0
    res.reason = OAv2_MERGE_SAME_VALUE_AS_REF;
1238
  /* No previous value in REF.  RHS is the new value.  */
1239
0
  else if (rhs->val.string)
1240
0
    {
1241
      /* This case could be optimized to avoid the dynamic allocation by moving
1242
   the value from RHS to RES, but then, we need to distinguish the case
1243
   when RHS and FROZEN are the same, and in this case, the value should
1244
   not be moved but copied.  The little benefit is not worth the added
1245
   complexity.  */
1246
0
      res.merge = true;
1247
0
      res.val.string = xstrdup (rhs->val.string);
1248
0
    }
1249
0
  return res;
1250
0
}
1251
1252
/* Return the merge result between attributes LHS, RHS and FROZEN.
1253
   Note: FROZEN_IS_RHS indicates that FROZEN is in RHS's position.  This happens
1254
   when this function is called from oav2_subsections_merge_frozen().  When this
1255
   boolean is true, arguments are swapped to get the correct diagnostic messages
1256
   in case of issues.  */
1257
static obj_attr_v2_merge_result_t
1258
oav2_attr_merge (const struct bfd_link_info *info,
1259
     const bfd *abfd,
1260
     const obj_attr_subsection_v2_t *subsec,
1261
     const obj_attr_v2_t *lhs, const obj_attr_v2_t *rhs,
1262
     const obj_attr_v2_t *frozen, bool frozen_is_rhs)
1263
0
{
1264
0
  obj_attr_v2_merge_result_t res = {
1265
0
    .merge = false,
1266
0
    .val.uint = 0,
1267
0
    .reason = OAv2_MERGE_OK,
1268
0
  };
1269
1270
0
  gnu_testing_merge_policy policy;
1271
1272
0
  if (get_elf_backend_data (abfd)->obj_attr_v2_tag_merge != NULL)
1273
0
    {
1274
      /* If FROZEN is RHS (i.e. called from oav2_subsections_merge_frozen()), it
1275
   means that the merged value of LHS (the REF) and FROZEN is going to
1276
   be merged by the caller into LHS.  However, since diagnostic messages
1277
   always point to RHS, we need to swap LHS and RHS, so that ABFD is not
1278
   associated wrongly to FROZEN.  */
1279
0
      if (frozen_is_rhs)
1280
0
  {
1281
0
    const obj_attr_v2_t *tmp = lhs;
1282
0
    lhs = rhs;
1283
0
    rhs = tmp;
1284
0
  }
1285
0
      res = get_elf_backend_data (abfd)->obj_attr_v2_tag_merge (info, abfd,
1286
0
  subsec, lhs, rhs, frozen);
1287
0
      if (res.merge || res.reason == OAv2_MERGE_SAME_VALUE_AS_REF)
1288
0
  return res;
1289
0
    }
1290
1291
  /* Note for the future: the merge of generic object attributes should be
1292
     added here, between the architecture-specific merge, and the reserved GNU
1293
     testing namespace.  */
1294
1295
  /* GNU testing merge policies are looked up last.  */
1296
0
  if ((res.reason == OAv2_MERGE_UNSUPPORTED || res.reason == OAv2_MERGE_OK)
1297
0
      && (policy = gnu_testing_merge_subsection (subsec->name))
1298
0
    != SUBSECTION_TESTING_MERGE_UNSUPPORTED)
1299
0
    {
1300
      /* Only the first two attributes can be merged, others won't and will
1301
   be discarded.  */
1302
0
      if (lhs->tag <= 1)
1303
0
  {
1304
0
    if (policy == SUBSECTION_TESTING_MERGE_AND_POLICY)
1305
0
      res = _bfd_obj_attr_v2_merge_AND (info, abfd, subsec, lhs, rhs, frozen);
1306
0
    else if (policy == SUBSECTION_TESTING_MERGE_OR_POLICY)
1307
0
      res = obj_attr_v2_merge_OR (info, abfd, subsec, lhs, rhs, frozen);
1308
0
    else if (policy == SUBSECTION_TESTING_MERGE_ADD_POLICY)
1309
0
      res = obj_attr_v2_merge_ADD (info, abfd, subsec, lhs, rhs, frozen);
1310
1311
0
    return res;
1312
0
  }
1313
0
    }
1314
1315
  /* Nothing matched, thus the merge of this tag is unsupported.  */
1316
0
  res.reason = OAv2_MERGE_UNSUPPORTED;
1317
0
  return res;
1318
0
}
1319
1320
/* Append a new default-initialized attribute with the same key as AREF to the
1321
   given subsection.  */
1322
static void
1323
oav2_subsection_append_attr_default (const struct bfd_link_info *info,
1324
             obj_attr_subsection_v2_t *s_abfd_missing,
1325
             const obj_attr_v2_t *a_ref)
1326
0
{
1327
0
  obj_attr_v2_t *new_attr = oav2_attr_default (info, s_abfd_missing, a_ref);
1328
0
  LINKED_LIST_APPEND (obj_attr_v2_t) (s_abfd_missing, new_attr);
1329
0
}
1330
1331
/* Return a new default-initialized subsection with the same parameters as
1332
   SUBSEC.  */
1333
static obj_attr_subsection_v2_t *
1334
oav2_subsection_default_new (const struct bfd_link_info *info,
1335
           const obj_attr_subsection_v2_t *subsec)
1336
0
{
1337
0
  obj_attr_subsection_v2_t *new_subsec = bfd_elf_obj_attr_subsection_v2_init
1338
0
    (xstrdup (subsec->name), subsec->scope, subsec->optional, subsec->encoding);
1339
1340
0
  for (const obj_attr_v2_t *attr = subsec->first;
1341
0
       attr != NULL;
1342
0
       attr = attr->next)
1343
0
    oav2_subsection_append_attr_default (info, new_subsec, attr);
1344
1345
0
  return new_subsec;
1346
0
}
1347
1348
/* Report missing required attribute with key TAG in subsection SREF.  */
1349
static void
1350
report_missing_required_obj_attr (const struct bfd_link_info *info,
1351
          const bfd *abfd,
1352
          const obj_attr_subsection_v2_t *s_ref,
1353
          const obj_attr_tag_t tag)
1354
0
{
1355
0
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1356
0
  const char *tag_s = _bfd_obj_attr_v2_tag_to_string (bed, s_ref->name, tag);
1357
0
  info->callbacks->einfo (
1358
0
    _("%X%pB: error: missing required object attribute '%s' in subsection '%s'\n"),
1359
0
    abfd, tag_s, s_ref->name);
1360
0
  free ((char *) tag_s);
1361
0
}
1362
1363
/* Report required attribute A_ABFD mismatching with A_REF.  */
1364
static void
1365
report_mismatching_required_obj_attr (const struct bfd_link_info *info,
1366
              const bfd *ref_bfd,
1367
              const bfd *abfd,
1368
              const obj_attr_subsection_v2_t *s_ref,
1369
              const obj_attr_v2_t *a_ref,
1370
              const obj_attr_v2_t *a_abfd)
1371
0
{
1372
0
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1373
0
  const char *tag_s
1374
0
    = _bfd_obj_attr_v2_tag_to_string (bed, s_ref->name, a_ref->tag);
1375
0
  if (s_ref->encoding == OA_ENC_ULEB128)
1376
0
    {
1377
0
      info->callbacks->einfo (
1378
0
  _("%X%pB: error: mismatching value for required object attribute '%s' "
1379
0
    "in subsection '%s': %#x\n"),
1380
0
  abfd, tag_s, s_ref->name, a_abfd->val.uint);
1381
0
      info->callbacks->info (
1382
0
  _("%pB: info: conflicting value '%#x' lives here\n"),
1383
0
  ref_bfd, a_ref->val.uint);
1384
0
    }
1385
0
  else
1386
0
    {
1387
0
      info->callbacks->einfo (
1388
0
  _("%X%pB: error: mismatching value for required object attribute '%s' "
1389
0
    "in subsection '%s': \"%s\"\n"),
1390
0
  abfd, tag_s, s_ref->name, a_abfd->val.string);
1391
0
      info->callbacks->info (
1392
0
  _("%pB: info: conflicting value \"%s\" lives here\n"),
1393
0
  ref_bfd, a_ref->val.string);
1394
0
    }
1395
0
  free ((char *) tag_s);
1396
0
}
1397
1398
/* Attempt a perfect match between subsections S_REF and S_ABFD, and reports
1399
   errors for any mismatch.  Return S_REF if the subsections match, NULL
1400
   otherwise.*/
1401
static obj_attr_subsection_v2_t *
1402
oav2_subsection_perfect_match (const struct bfd_link_info *info,
1403
             const bfd *ref_bfd, const bfd *abfd,
1404
             obj_attr_subsection_v2_t *s_ref,
1405
             const obj_attr_subsection_v2_t *s_abfd)
1406
0
{
1407
0
  bool success = true;
1408
0
  const obj_attr_v2_t *a_ref = s_ref->first;
1409
0
  const obj_attr_v2_t *a_abfd = s_abfd->first;
1410
0
  while (a_ref != NULL && a_abfd != NULL)
1411
0
    {
1412
0
      if (a_ref->tag < a_abfd->tag)
1413
0
  {
1414
0
    success = false;
1415
0
    report_missing_required_obj_attr (info, abfd, s_ref, a_ref->tag);
1416
0
    a_ref = a_ref->next;
1417
0
  }
1418
0
      else if (a_ref->tag > a_abfd->tag)
1419
0
  {
1420
0
    success = false;
1421
0
    report_missing_required_obj_attr (info, ref_bfd, s_ref, a_abfd->tag);
1422
0
    a_abfd = a_abfd->next;
1423
0
  }
1424
0
      else
1425
0
  {
1426
0
    if (s_ref->encoding == OA_ENC_ULEB128)
1427
0
      {
1428
0
        if (a_ref->val.uint != a_abfd->val.uint)
1429
0
    {
1430
0
      success = false;
1431
0
      report_mismatching_required_obj_attr (info, ref_bfd, abfd,
1432
0
        s_ref, a_ref, a_abfd);
1433
0
    }
1434
0
      }
1435
0
    else if (s_ref->encoding == OA_ENC_NTBS)
1436
0
      {
1437
0
        if (strcmp (a_ref->val.string, a_abfd->val.string) != 0)
1438
0
    {
1439
0
      success = false;
1440
0
      report_mismatching_required_obj_attr (info, ref_bfd, abfd,
1441
0
        s_ref, a_ref, a_abfd);
1442
0
    }
1443
0
      }
1444
0
    a_ref = a_ref->next;
1445
0
    a_abfd = a_abfd->next;
1446
0
  }
1447
0
    }
1448
1449
0
  for (; a_abfd != NULL; a_abfd = a_abfd->next)
1450
0
    {
1451
0
      success = false;
1452
0
      report_missing_required_obj_attr (info, ref_bfd, s_ref, a_abfd->tag);
1453
0
    }
1454
1455
0
  for (; a_ref != NULL; a_ref = a_ref->next)
1456
0
    {
1457
0
      success = false;
1458
0
      report_missing_required_obj_attr (info, abfd, s_ref, a_ref->tag);
1459
0
    }
1460
1461
0
  return success ? s_ref : NULL;
1462
0
}
1463
1464
/* Search for the attribute with TAG into a list of attributes.  The attributes
1465
   list is assumed to be sorted.  Return the pointer to the attribute with TAG
1466
   if found, NULL otherwise.  */
1467
static obj_attr_v2_t *
1468
oav2_search_by_tag (obj_attr_v2_t *attr_first, obj_attr_tag_t tag)
1469
0
{
1470
0
  for (obj_attr_v2_t *attr = attr_first; attr != NULL; attr = attr->next)
1471
0
    {
1472
0
      if (attr->tag == tag)
1473
0
  return attr;
1474
0
      else if (attr->tag > tag)
1475
0
  break;
1476
0
    }
1477
0
  return NULL;
1478
0
}
1479
1480
/* Merge optional subsection S_ABFD into S_REF.  S_FROZEN is used to report any
1481
   issue with the selected configuration, and to force the merge value to a
1482
   specific value if needed.  */
1483
static
1484
obj_attr_subsection_v2_t *
1485
handle_optional_subsection_merge (const struct bfd_link_info *info,
1486
          const bfd *ref_bfd, const bfd *abfd,
1487
          obj_attr_subsection_v2_t *s_ref,
1488
          const obj_attr_subsection_v2_t *s_abfd,
1489
          const obj_attr_subsection_v2_t *s_frozen)
1490
0
{
1491
0
  (void) info;
1492
  /* REF_BFD and ABFD are the same only when the call originated from
1493
     oav2_subsections_merge_frozen(), when FROZEN is merged into ABFD
1494
     (the future REF_BFD).  See detailed explanation in oav2_attr_merge().  */
1495
0
  bool frozen_is_abfd = (ref_bfd == abfd);
1496
0
  obj_attr_v2_t *a_ref = s_ref->first;
1497
0
  const obj_attr_v2_t *a_abfd = s_abfd->first;
1498
0
  obj_attr_v2_t *a_frozen_first = (s_frozen != NULL) ? s_frozen->first : NULL;
1499
0
  while (a_ref != NULL && a_abfd != NULL)
1500
0
    {
1501
0
      uint32_t searched_frozen_tag
1502
0
  = (a_ref->tag < a_abfd->tag
1503
0
     ? a_ref->tag
1504
0
     : a_abfd->tag);
1505
0
      obj_attr_v2_t *a_frozen
1506
0
  = oav2_search_by_tag (a_frozen_first, searched_frozen_tag);
1507
0
      if (a_frozen != NULL)
1508
0
  a_frozen_first = a_frozen;
1509
1510
0
      if (a_ref->tag < a_abfd->tag)
1511
0
  {
1512
0
    obj_attr_v2_t *a_default = oav2_attr_default (info, s_abfd, a_ref);
1513
0
    obj_attr_v2_merge_result_t res
1514
0
      = oav2_attr_merge (info, abfd, s_ref, a_ref, a_default, a_frozen,
1515
0
             frozen_is_abfd);
1516
0
    _bfd_elf_obj_attr_v2_free (a_default, s_ref->encoding);
1517
0
    if (res.merge)
1518
0
      oav2_assign_value (s_ref->encoding, a_ref, res.val);
1519
0
    else if (res.reason == OAv2_MERGE_UNSUPPORTED)
1520
0
      a_ref->status = obj_attr_v2_unknown;
1521
0
    a_ref = a_ref->next;
1522
0
  }
1523
0
      else if (a_ref->tag > a_abfd->tag)
1524
0
  {
1525
0
    obj_attr_v2_t *a_default = oav2_attr_default (info, s_ref, a_abfd);
1526
0
    obj_attr_v2_merge_result_t res
1527
0
      = oav2_attr_merge (info, abfd, s_ref, a_default, a_abfd, a_frozen,
1528
0
             frozen_is_abfd);
1529
0
    if (res.merge || res.reason == OAv2_MERGE_SAME_VALUE_AS_REF)
1530
0
      {
1531
0
        oav2_assign_value (s_ref->encoding, a_default, res.val);
1532
0
        LINKED_LIST_INSERT_BEFORE (obj_attr_v2_t)
1533
0
    (s_ref, a_default, a_ref);
1534
0
      }
1535
0
    else
1536
0
      _bfd_elf_obj_attr_v2_free (a_default, s_ref->encoding);
1537
0
    a_abfd = a_abfd->next;
1538
0
  }
1539
0
      else
1540
0
  {
1541
0
    obj_attr_v2_merge_result_t res
1542
0
      = oav2_attr_merge (info, abfd, s_ref, a_ref, a_abfd, a_frozen,
1543
0
             frozen_is_abfd);
1544
0
    if (res.merge)
1545
0
      oav2_assign_value (s_ref->encoding, a_ref, res.val);
1546
0
    else if (res.reason == OAv2_MERGE_UNSUPPORTED)
1547
0
      a_ref->status = obj_attr_v2_unknown;
1548
0
    a_ref = a_ref->next;
1549
0
    a_abfd = a_abfd->next;
1550
0
  }
1551
0
    }
1552
1553
0
  for (; a_abfd != NULL; a_abfd = a_abfd->next)
1554
0
    {
1555
0
      obj_attr_v2_t *a_default = oav2_attr_default (info, s_ref, a_abfd);
1556
0
      obj_attr_v2_merge_result_t res
1557
0
  = oav2_attr_merge (info, abfd, s_ref, a_default, a_abfd, NULL, false);
1558
0
      if (res.merge || res.reason == OAv2_MERGE_SAME_VALUE_AS_REF)
1559
0
  {
1560
0
    oav2_assign_value (s_ref->encoding, a_default, res.val);
1561
0
    LINKED_LIST_APPEND (obj_attr_v2_t) (s_ref, a_default);
1562
0
  }
1563
0
      else
1564
0
  _bfd_elf_obj_attr_v2_free (a_default, s_ref->encoding);
1565
0
    }
1566
1567
0
  for (; a_ref != NULL; a_ref = a_ref->next)
1568
0
    {
1569
0
      obj_attr_v2_t *a_frozen = oav2_search_by_tag (a_frozen_first, a_ref->tag);
1570
0
      if (a_frozen != NULL)
1571
0
  a_frozen_first = a_frozen;
1572
1573
0
      obj_attr_v2_t *a_default = oav2_attr_default (info, s_abfd, a_ref);
1574
0
      obj_attr_v2_merge_result_t res
1575
0
  = oav2_attr_merge (info, abfd, s_ref, a_ref, a_default, a_frozen,
1576
0
         frozen_is_abfd);
1577
0
      _bfd_elf_obj_attr_v2_free (a_default, s_ref->encoding);
1578
0
      if (res.merge)
1579
0
  oav2_assign_value (s_ref->encoding, a_ref, res.val);
1580
0
      else if (res.reason == OAv2_MERGE_UNSUPPORTED)
1581
0
  a_ref->status = obj_attr_v2_unknown;
1582
0
    }
1583
1584
0
  return s_ref;
1585
0
}
1586
1587
/* Merge case 1: S_ABFD and S_REF exists, so merge S_ABFD into S_REF.  */
1588
static obj_attr_subsection_v2_t *
1589
handle_subsection_merge (const struct bfd_link_info *info,
1590
       const bfd *ref_bfd, const bfd *abfd,
1591
       obj_attr_subsection_v2_t *s_ref,
1592
       const obj_attr_subsection_v2_t *s_abfd,
1593
       const obj_attr_subsection_v2_t *s_frozen)
1594
0
{
1595
0
  if (! s_ref->optional)
1596
0
    return oav2_subsection_perfect_match (info, ref_bfd, abfd, s_ref, s_abfd);
1597
0
  return handle_optional_subsection_merge
1598
0
    (info, ref_bfd, abfd, s_ref, s_abfd, s_frozen);
1599
0
}
1600
1601
/* Merge case 2: S_ABFD does not exist, but S_REF does.
1602
   1. Create a new default-initialized S_ABFD.
1603
   2. Merge S_ABFD into S_REF.  */
1604
static bool
1605
handle_subsection_missing (const struct bfd_link_info *info,
1606
         const bfd *ref_bfd, const bfd *abfd,
1607
         obj_attr_subsection_v2_t *s_ref,
1608
         const obj_attr_subsection_v2_t *s_frozen)
1609
0
{
1610
0
  if (! s_ref->optional)
1611
0
    {
1612
0
      info->callbacks->einfo
1613
0
  (_("%X%pB: error: missing required object attributes subsection %s\n"),
1614
0
   abfd, s_ref->name);
1615
0
      return false;
1616
0
    }
1617
1618
  /* Compute default values of the missing attributes in ABFD, but present in
1619
     REF, and merge ABFD's generated subsection with the one of REF.  */
1620
0
  obj_attr_subsection_v2_t *s_abfd = oav2_subsection_default_new (info, s_ref);
1621
0
  const obj_attr_subsection_v2_t *merged
1622
0
    = handle_subsection_merge (info, ref_bfd, abfd, s_ref, s_abfd, s_frozen);
1623
0
  _bfd_elf_obj_attr_subsection_v2_free (s_abfd);
1624
0
  return merged != NULL;
1625
0
}
1626
1627
/* Merge case 3: S_ABFD does not have a S_REF equivalent.
1628
   1. Create a new default-initialized S_REF subsection.
1629
   2. Merge S_ABFD into S_REF.
1630
   3. Insert S_REF into REF before S_REF_NEXT.  */
1631
static bool
1632
handle_subsection_additional (const struct bfd_link_info *info,
1633
            const bfd *ref_bfd, const bfd *abfd,
1634
            obj_attr_subsection_v2_t *s_ref_next,
1635
            const obj_attr_subsection_v2_t *s_abfd,
1636
            const obj_attr_subsection_v2_t *s_frozen)
1637
0
{
1638
0
  if (! s_abfd->optional)
1639
0
    {
1640
0
      info->callbacks->einfo
1641
0
  (_("%X%pB: error: missing required object attributes subsection %s\n"),
1642
0
   ref_bfd, s_abfd->name);
1643
0
      return false;
1644
0
    }
1645
1646
  /* Compute default values of the missing attributes in REF, but present in
1647
     ABFD, and merge REF's generated subsection with the one of ABFD.  */
1648
0
  obj_attr_subsection_v2_t *s_ref = oav2_subsection_default_new (info, s_abfd);
1649
0
  obj_attr_subsection_v2_t *s_merged
1650
0
    = handle_subsection_merge (info, ref_bfd, abfd, s_ref, s_abfd, s_frozen);
1651
0
  if (s_merged != NULL)
1652
0
    {
1653
0
      LINKED_LIST_INSERT_BEFORE (obj_attr_subsection_v2_t)
1654
0
  (&elf_obj_attr_subsections (ref_bfd), s_merged, s_ref_next);
1655
0
    }
1656
0
  else
1657
    /* An issue occurred during the merge. s_ref won't be saved so it needs to
1658
       be freed.  */
1659
0
    _bfd_elf_obj_attr_subsection_v2_free (s_ref);
1660
0
  return (s_merged != NULL);
1661
0
}
1662
1663
/* Check whether a subsection is known, and if so, whether the current
1664
   properties of the subsection match the expected ones.
1665
   Return True if the subsection is known, AND all the properties of the
1666
   subsection match the expected.  False otherwise.  */
1667
static bool
1668
oav2_subsection_match_known (const struct bfd_link_info *info,
1669
           const bfd *abfd,
1670
           const obj_attr_subsection_v2_t *subsec)
1671
0
{
1672
0
  const known_subsection_v2_t *subsec_info
1673
0
    = bfd_obj_attr_v2_identify_subsection (get_elf_backend_data (abfd),
1674
0
             subsec->name);
1675
1676
0
  if (subsec_info == NULL)
1677
0
    return false;
1678
1679
0
  bool match = true;
1680
0
  if (subsec_info->encoding != subsec->encoding)
1681
0
    {
1682
0
      info->callbacks->einfo
1683
0
  (_("%X%pB: error: <%s> property of subsection '%s' was "
1684
0
     "incorrectly set.  Got '%s', expected '%s'\n"),
1685
0
   abfd, "encoding", subsec->name,
1686
0
   bfd_oav2_encoding_to_string (subsec->encoding),
1687
0
   bfd_oav2_encoding_to_string (subsec_info->encoding));
1688
0
      match = false;
1689
0
    }
1690
0
  if (subsec_info->optional != subsec->optional)
1691
0
    {
1692
0
      info->callbacks->einfo
1693
0
  (_("%X%pB: error: <%s> property of subsection '%s' was "
1694
0
     "incorrectly set.  Got '%s', expected '%s'\n"),
1695
0
   abfd, "comprehension", subsec->name,
1696
0
   bfd_oav2_comprehension_to_string (subsec->optional),
1697
0
   bfd_oav2_comprehension_to_string (subsec_info->optional));
1698
0
      match = false;
1699
0
    }
1700
0
  return match;
1701
0
}
1702
1703
/* Check whether the properties of the subsections S1 and S2 match.
1704
   Return True if the properties match, False otherwise.  */
1705
static bool
1706
oav2_subsection_generic_params_match (const struct bfd_link_info *info,
1707
              const bfd *f1, const bfd *f2,
1708
              const obj_attr_subsection_v2_t *s1,
1709
              const obj_attr_subsection_v2_t *s2)
1710
0
{
1711
0
  bool match = (s1->encoding == s2->encoding && s1->optional == s2->optional);
1712
0
  if (! match)
1713
0
    {
1714
0
      if (f1 != NULL)
1715
0
  {
1716
0
    info->callbacks->einfo (
1717
0
      _("%X%pB: error: mismatching properties of subsection '%s'\n"),
1718
0
      f2, s1->name);
1719
0
    info->callbacks->info (
1720
0
       _("%pB: info: conflicting properties (%s, %s) live here\n"), f1,
1721
0
       bfd_oav2_comprehension_to_string (s1->optional),
1722
0
       bfd_oav2_encoding_to_string (s1->encoding));
1723
0
    info->callbacks->info (
1724
0
      _("info: (%s, %s) VS (%s, %s)\n"),
1725
0
      bfd_oav2_comprehension_to_string (s2->optional),
1726
0
      bfd_oav2_encoding_to_string (s2->encoding),
1727
0
      bfd_oav2_comprehension_to_string (s1->optional),
1728
0
      bfd_oav2_encoding_to_string (s1->encoding));
1729
0
  }
1730
0
      else
1731
0
  {
1732
0
    info->callbacks->einfo (
1733
0
      _("%X%pB: error: corrupted properties in subsection '%s'\n"),
1734
0
      f2, s1->name);
1735
0
    info->callbacks->info (
1736
0
      _("info: (%s, %s) VS (%s, %s)\n"),
1737
0
      bfd_oav2_comprehension_to_string (s2->optional),
1738
0
      bfd_oav2_encoding_to_string (s2->encoding),
1739
0
      bfd_oav2_comprehension_to_string (s1->optional),
1740
0
      bfd_oav2_encoding_to_string (s1->encoding));
1741
0
  }
1742
0
    }
1743
0
  return match;
1744
0
}
1745
1746
/* Check for mismatch between the parameters of subsections S1 and S2.
1747
   Return True if the parameters mismatch, False otherwise.
1748
   Note: F1 can be null when comparing FROZEN and the first object file used to
1749
   store the merge result.  If an error is reported, it means that one of the
1750
   definition of S1 or S2 is corrupted.  Most likely S2 because it is a user
1751
   input, or S1 if it is a programmation error of FROZEN.  In the second case,
1752
   please raise a bug to binutils bug tracker.  */
1753
static bool
1754
oav2_subsection_mismatching_params (const struct bfd_link_info *info,
1755
            const bfd *f1, const bfd *f2,
1756
            const obj_attr_subsection_v2_t *s1,
1757
            const obj_attr_subsection_v2_t *s2)
1758
0
{
1759
0
  if (gnu_testing_namespace (s2->name))
1760
0
    return ! oav2_subsection_generic_params_match (info, f1, f2, s1, s2);
1761
1762
  /* Check whether the subsection is known, and if so, match against the
1763
     expected properties.
1764
     Note: this piece of code must be guarded against gnu-testing subsections,
1765
     as oav2_subsection_match_known() looks up at the known subsections.
1766
     Since the "fictive" entry for gnu-testing known subsection has random
1767
     values for its encoding and optionality, it won't be able to detect
1768
     mismatching parameters correctly.  */
1769
0
  return ! oav2_subsection_match_known (info, f2, s2);
1770
0
}
1771
1772
/* Merge object attributes from FROZEN into the object file ABFD.
1773
   Note: this function is called only once before starting the merge process
1774
   between the object files.  ABFD corresponds to the future REF_BFD, and is
1775
   used to store the result of the merge.  ABFD is also an input file, so any
1776
   mismatch against FROZEN should be raised before the values of ABFD be
1777
   modified.  */
1778
static bool
1779
oav2_subsections_merge_frozen (const struct bfd_link_info *info,
1780
             const bfd *abfd,
1781
             const obj_attr_subsection_list_t *frozen_cfg)
1782
0
{
1783
0
  const obj_attr_subsection_v2_t *s_frozen = frozen_cfg->first;
1784
0
  if (s_frozen == NULL)
1785
0
    return true;
1786
1787
0
  bool success = true;
1788
1789
  /* Note: all the handle_subsection_* functions call oav2_attr_merge() down the
1790
     stack.  Passing ABFD as REF_BFD allows to detect that this function is
1791
     the caller.  Then a special behavior in oav2_attr_merge() is triggered for
1792
     this specific use case, so that we can obtain the right diagnostics.  */
1793
1794
0
  obj_attr_subsection_v2_t *s_abfd = elf_obj_attr_subsections (abfd).first;
1795
0
  while (s_frozen != NULL && s_abfd != NULL)
1796
0
    {
1797
0
      int cmp = strcmp (s_abfd->name, s_frozen->name);
1798
0
      if (cmp < 0) /* ABFD has a subsection that FROZEN doesn't have.  */
1799
0
  {
1800
    /* No need to try to merge anything here.  */
1801
0
    s_abfd = s_abfd->next;
1802
0
  }
1803
0
      else if (cmp > 0) /* FROZEN has a subsection that ABFD doesn't have.  */
1804
0
  {
1805
0
    success &= handle_subsection_additional (info, abfd, abfd,
1806
0
      s_abfd, s_frozen, s_frozen);
1807
0
    s_frozen = s_frozen->next;
1808
0
  }
1809
0
      else /* Both ABFD and frozen have the subsection.  */
1810
0
  {
1811
0
    bool mismatch = oav2_subsection_mismatching_params (info, NULL, abfd,
1812
0
      s_frozen, s_abfd);
1813
0
    success &= ! mismatch;
1814
0
    if (mismatch)
1815
      /* FROZEN cannot be corrupted as it is generated from the command
1816
         line arguments.  If it is corrupted, it is a bug.  */
1817
0
      s_abfd->status = obj_attr_subsection_v2_corrupted;
1818
0
    else
1819
0
      success &= (handle_subsection_merge (info, abfd, abfd,
1820
0
        s_abfd, s_frozen, s_frozen) != NULL);
1821
1822
0
    s_abfd = s_abfd->next;
1823
0
    s_frozen = s_frozen->next;
1824
0
  }
1825
0
    }
1826
1827
  /* No need to go through the remaining sections of ABFD, only mismatches
1828
     against FROZEN are interesting.  */
1829
1830
0
  for (; s_frozen != NULL; s_frozen = s_frozen->next)
1831
0
    success &= handle_subsection_additional (info, abfd, abfd,
1832
0
      elf_obj_attr_subsections (abfd).last, s_frozen, s_frozen);
1833
1834
0
  return success;
1835
0
}
1836
1837
/* Merge object attributes from object file ABFD and FROZEN_CFG into REF_BFD.  */
1838
static bool
1839
oav2_subsections_merge (const struct bfd_link_info *info,
1840
      const bfd *ref_bfd, bfd *abfd,
1841
      const obj_attr_subsection_list_t *frozen_cfg)
1842
0
{
1843
0
  bool success = true;
1844
0
  obj_attr_subsection_list_t *abfd_subsecs = &elf_obj_attr_subsections (abfd);
1845
0
  obj_attr_subsection_list_t *ref_subsecs = &elf_obj_attr_subsections (ref_bfd);
1846
1847
0
  obj_attr_subsection_v2_t *s_frozen_first = frozen_cfg->first;
1848
0
  obj_attr_subsection_v2_t *s_abfd = abfd_subsecs->first;
1849
0
  obj_attr_subsection_v2_t *s_ref = ref_subsecs->first;
1850
1851
0
  while (s_abfd != NULL && s_ref != NULL)
1852
0
    {
1853
0
      int cmp = strcmp (s_ref->name, s_abfd->name);
1854
1855
0
      if (cmp < 0) /* REF has a subsection that ABFD doesn't have.  */
1856
0
  {
1857
0
    if (s_ref->status != obj_attr_subsection_v2_ok)
1858
0
      {
1859
0
        s_ref = s_ref->next;
1860
0
        continue;
1861
0
      }
1862
1863
0
    obj_attr_subsection_v2_t *s_frozen
1864
0
      = bfd_obj_attr_subsection_v2_find_by_name (s_frozen_first,
1865
0
                   s_ref->name,
1866
0
                   true);
1867
1868
    /* Mismatching between REF and FROZEN already done in
1869
       oav2_subsections_merge_frozen.  */
1870
0
    success &= handle_subsection_missing (info, ref_bfd, abfd, s_ref,
1871
0
      s_frozen);
1872
1873
0
    if (s_frozen != NULL)
1874
0
      s_frozen_first = s_frozen->next;
1875
0
    s_ref = s_ref->next;
1876
0
  }
1877
0
      else if (cmp > 0) /* ABFD has a subsection that REF doesn't have.  */
1878
0
  {
1879
0
    if (s_abfd->status != obj_attr_subsection_v2_ok)
1880
0
      {
1881
0
        s_abfd = s_abfd->next;
1882
0
        continue;
1883
0
      }
1884
1885
0
    obj_attr_subsection_v2_t *s_frozen
1886
0
      = bfd_obj_attr_subsection_v2_find_by_name (s_frozen_first,
1887
0
                   s_abfd->name,
1888
0
                   true);
1889
0
    if (s_frozen != NULL)
1890
0
      {
1891
        /* Check any mismatch against ABFD and FROZEN.  */
1892
0
        bool mismatch = oav2_subsection_mismatching_params (info, NULL,
1893
0
    abfd, s_frozen, s_abfd);
1894
0
        success &= ! mismatch;
1895
0
        if (mismatch)
1896
0
    s_abfd->status = obj_attr_subsection_v2_corrupted;
1897
0
        else
1898
0
    success &= handle_subsection_additional (info, ref_bfd, abfd,
1899
0
      s_ref, s_abfd, s_frozen);
1900
0
      }
1901
0
    else
1902
0
      success &= handle_subsection_additional (info, ref_bfd, abfd, s_ref,
1903
0
        s_abfd, NULL);
1904
1905
0
    if (s_frozen != NULL)
1906
0
      s_frozen_first = s_frozen->next;
1907
0
    s_abfd = s_abfd->next;
1908
0
  }
1909
0
      else /* Both REF and ABFD have the subsection.  */
1910
0
  {
1911
0
    if (s_ref->status != obj_attr_subsection_v2_ok)
1912
0
      {
1913
0
        s_ref = s_ref->next;
1914
0
        s_abfd = s_abfd->next;
1915
0
        continue;
1916
0
      }
1917
1918
0
    obj_attr_subsection_v2_t *s_frozen
1919
0
      = bfd_obj_attr_subsection_v2_find_by_name (s_frozen_first,
1920
0
                   s_ref->name,
1921
0
                   true);
1922
1923
0
    bool mismatch = oav2_subsection_mismatching_params
1924
0
      (info, ref_bfd, abfd, s_ref, s_abfd);
1925
0
    success &= ! mismatch;
1926
0
    if (mismatch)
1927
0
      s_abfd->status = obj_attr_subsection_v2_corrupted;
1928
0
    else
1929
0
      success &= (handle_subsection_merge (info, ref_bfd, abfd, s_ref,
1930
0
             s_abfd, s_frozen) != NULL);
1931
1932
0
    if (s_frozen != NULL)
1933
0
      s_frozen_first = s_frozen->next;
1934
0
    s_ref = s_ref->next;
1935
0
    s_abfd = s_abfd->next;
1936
0
  }
1937
0
    }
1938
1939
0
  for (; s_abfd != NULL; s_abfd = s_abfd->next)
1940
0
    {
1941
0
      if (s_abfd->status != obj_attr_subsection_v2_ok)
1942
0
  continue;
1943
1944
0
      obj_attr_subsection_v2_t *s_frozen
1945
0
  = bfd_obj_attr_subsection_v2_find_by_name (s_frozen_first,
1946
0
               s_abfd->name,
1947
0
               true);
1948
0
      if (s_frozen != NULL)
1949
0
  {
1950
0
    bool mismatch = oav2_subsection_mismatching_params (info, NULL, abfd,
1951
0
                    s_frozen, s_abfd);
1952
0
    success &= ! mismatch;
1953
0
    if (mismatch)
1954
0
      s_abfd->status = obj_attr_subsection_v2_corrupted;
1955
0
    else
1956
0
      success &= handle_subsection_additional (info, ref_bfd, abfd,
1957
0
                 ref_subsecs->last, s_abfd,
1958
0
                 s_frozen);
1959
0
  }
1960
0
      else
1961
0
  success &= handle_subsection_additional (info, ref_bfd, abfd,
1962
0
             ref_subsecs->last, s_abfd,
1963
0
             NULL);
1964
0
    }
1965
1966
0
  for (; s_ref != NULL; s_ref = s_ref->next)
1967
0
    {
1968
0
      if (s_ref->status != obj_attr_subsection_v2_ok)
1969
0
  continue;
1970
1971
0
      obj_attr_subsection_v2_t *s_frozen
1972
0
  = bfd_obj_attr_subsection_v2_find_by_name (s_frozen_first,
1973
0
               s_ref->name,
1974
0
               true);
1975
      /* No need to check for matching parameters here as frozen has already
1976
   been checked against ref.  */
1977
0
      success &= handle_subsection_missing (info, ref_bfd, abfd, s_ref, s_frozen);
1978
0
    }
1979
1980
0
  return success;
1981
0
}
1982
1983
/* Wrapper for the high-level logic of merging a single file.
1984
   It handles both of the following cases:
1985
   - ABFD (future REF_BFD) merged against FROZEN.
1986
   - ABFD (input) and FROZEN_CFG merged into REF_BFD.
1987
   If has_obj_attrs_after_translation is non-NULL, the caller is responsible for
1988
   the distinction between the cases where attributes are already present, or
1989
   where attributes were added as a result of a translation of GNU properties.
1990
   The first step translates existing GNU properties to object attributes. Next,
1991
   any duplicates entries in the input are merged, and the resulting object
1992
   attributes are written back into GNU properties so that the GNU properties
1993
   merge process can correctly diagnose potential issues. Before merging,
1994
   unknown subsections and attributes are marked so they can be skipped during
1995
   processing.
1996
   Return True on success, False on failure.  */
1997
static bool
1998
oav2_merge_one (const struct bfd_link_info *info,
1999
    bfd *ref_bfd, bfd *abfd,
2000
    const obj_attr_subsection_list_t *frozen_cfg,
2001
    bool *has_obj_attrs_after_translation)
2002
0
{
2003
  /* ABFD is an input file that may contain GNU properties, object
2004
     attributes, or both.  Before merging object attributes, we must first
2005
     translate any GNU properties into their equivalent object attributes
2006
     (if such equivalents exist) since they may not already be present.  */
2007
0
  oav2_translate_gnu_props_to_obj_attrs (abfd);
2008
0
  if (has_obj_attrs_after_translation
2009
0
      && elf_obj_attr_subsections (abfd).size > 0)
2010
0
    *has_obj_attrs_after_translation = true;
2011
2012
  /* Merge duplicates subsections and attributes.  */
2013
0
  if (! oav2_file_scope_merge_subsections (abfd))
2014
0
    return false;
2015
2016
  /* ABFD is an input file that may contain GNU properties, object
2017
     attributes, or both.  Before merging GNU properties, we must first
2018
     translate any object attributes into their equivalent GNU properties
2019
     (if such equivalents exist) since they may not already be present.  */
2020
0
  oav2_translate_obj_attrs_to_gnu_props (abfd);
2021
2022
  /* Note: object attributes are always merged before GNU properties.
2023
     Ideally, there would be a single internal representation, with an
2024
     abstraction level flexible enough to capture both GNU properties and
2025
     object attributes without loss.  In such a design, merge order would
2026
     be irrelevant, and translation would occur only at the I/O boundaries
2027
     during deserialization of GNU properties and object attributes.  */
2028
2029
  /* Mark unknown subsections and attributes to skip them during
2030
     the merge.  */
2031
0
  oav2_subsections_mark_unknown (abfd);
2032
2033
0
  if (ref_bfd == NULL)
2034
    /* When REF_BFD is null, it means that ABFD is the future REF_BFD, and
2035
       will be accumulating the merge result.
2036
       It means that we will lose information from ABFD beyond this stage,
2037
       so we need to emit warnings / errors (if any) when merging ABFD
2038
       against FROZEN.  */
2039
0
    return oav2_subsections_merge_frozen (info, abfd, frozen_cfg);
2040
2041
  /* Common merge case.  */
2042
0
  return oav2_subsections_merge (info, ref_bfd, abfd, frozen_cfg);
2043
0
}
2044
2045
/* Merge all the object attributes in INPUT_BFDS (REF_BFD excluded) into
2046
   REF_BFD.  Return True on success, False otherwise.  */
2047
static bool
2048
oav2_merge_all (const struct bfd_link_info *info,
2049
    bfd *ref_bfd, bfd *input_bfds,
2050
    obj_attr_subsection_list_t *frozen_cfg)
2051
0
{
2052
0
  bool success = true;
2053
0
  for (bfd *abfd = input_bfds; abfd != NULL; abfd = abfd->link.next)
2054
0
    {
2055
0
      if (abfd != ref_bfd && oav2_relevant_elf_object (info, abfd))
2056
0
  success &= oav2_merge_one (info, ref_bfd, abfd, frozen_cfg, NULL);
2057
0
    }
2058
0
  return success;
2059
0
}
2060
2061
/* Prune the given attribute, and return the next one in the list.  */
2062
static obj_attr_v2_t *
2063
oav2_attr_delete (obj_attr_subsection_v2_t *subsec,
2064
      obj_attr_v2_t *attr)
2065
0
{
2066
0
  obj_attr_v2_t *next = attr->next;
2067
0
  LINKED_LIST_REMOVE (obj_attr_v2_t) (subsec, attr);
2068
0
  _bfd_elf_obj_attr_v2_free (attr, subsec->encoding);
2069
0
  return next;
2070
0
}
2071
2072
/* Prune the given subsection, and return the next one in the list.  */
2073
static obj_attr_subsection_v2_t *
2074
oav2_subsec_delete (obj_attr_subsection_list_t *plist,
2075
        obj_attr_subsection_v2_t *subsec)
2076
224
{
2077
224
  obj_attr_subsection_v2_t *next = subsec->next;
2078
224
  LINKED_LIST_REMOVE (obj_attr_subsection_v2_t) (plist, subsec);
2079
224
  _bfd_elf_obj_attr_subsection_v2_free (subsec);
2080
224
  return next;
2081
224
}
2082
2083
/* Prune any attributes with a status different from obj_attr_v2_ok in the
2084
   given subsection.  */
2085
static void
2086
oav2_attrs_prune_nok (const struct bfd_link_info *info,
2087
          obj_attr_subsection_v2_t *subsec)
2088
0
{
2089
0
  const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
2090
0
  for (obj_attr_v2_t *attr = subsec->first;
2091
0
       attr != NULL;)
2092
0
    {
2093
0
      if (attr->status != obj_attr_v2_ok)
2094
0
  {
2095
0
    const char *tag_s
2096
0
      = _bfd_obj_attr_v2_tag_to_string (bed, subsec->name, attr->tag);
2097
0
    info->callbacks->minfo
2098
0
      (_("Removed attribute '%s' from '%s'\n"), tag_s, subsec->name);
2099
0
    free ((char *) tag_s);
2100
0
    attr = oav2_attr_delete (subsec, attr);
2101
0
  }
2102
0
      else
2103
0
  attr = attr->next;
2104
0
    }
2105
0
}
2106
2107
/* Prune any subsection with a status different from obj_attr_subsection_v2_ok
2108
   in the given list of subsections.  */
2109
static void
2110
oav2_subsecs_prune_nok (const struct bfd_link_info *info,
2111
      obj_attr_subsection_list_t *plist)
2112
0
{
2113
0
  for (obj_attr_subsection_v2_t *subsec = plist->first;
2114
0
       subsec != NULL;)
2115
0
    {
2116
0
      if (subsec->status == obj_attr_subsection_v2_ok)
2117
0
  oav2_attrs_prune_nok (info, subsec);
2118
2119
0
      if (subsec->size == 0 || subsec->status != obj_attr_subsection_v2_ok)
2120
0
  {
2121
0
    info->callbacks->minfo (_("Removed subsection '%s'\n"), subsec->name);
2122
0
    subsec = oav2_subsec_delete (plist, subsec);
2123
0
  }
2124
0
      else
2125
0
  subsec = subsec->next;
2126
0
    }
2127
0
}
2128
2129
/* Prune any subsection or attribute with a status different from OK.  */
2130
static bool
2131
oav2_prune_nok_attrs (const struct bfd_link_info *info, bfd *abfd)
2132
0
{
2133
0
  obj_attr_subsection_list_t *plist = &elf_obj_attr_subsections (abfd);
2134
0
  oav2_subsecs_prune_nok (info, plist);
2135
0
  return (plist->size != 0);
2136
0
}
2137
2138
/* Set up object attributes coming from configuration, and merge them with the
2139
   ones from the input object files.  Return a pointer to the input object file
2140
   containing the merge result on success, NULL otherwise.  */
2141
bfd *
2142
_bfd_elf_link_setup_object_attributes (struct bfd_link_info *info)
2143
0
{
2144
0
  obj_attr_subsection_list_t *frozen_cfg
2145
0
    = &elf_obj_attr_subsections (info->output_bfd);
2146
2147
0
  bfd_search_result_t res
2148
0
    = bfd_linear_find_first_with_obj_attrs (info);
2149
2150
  /* If res.pbfd is NULL, it means that it didn't find any ELF object files.  */
2151
0
  if (res.pbfd == NULL)
2152
0
    return NULL;
2153
2154
  /* Sort the frozen subsections and attributes in case that they were not
2155
     inserted in the correct order.  */
2156
0
  oav2_sort_subsections (frozen_cfg);
2157
2158
  /* Merge object attributes sections.  */
2159
0
  info->callbacks->minfo ("\n");
2160
0
  info->callbacks->minfo (_("Merging object attributes\n"));
2161
0
  info->callbacks->minfo ("\n");
2162
2163
0
  bool success = oav2_merge_one (info, NULL, res.pbfd, frozen_cfg,
2164
0
         &res.has_object_attributes);
2165
2166
  /* No frozen object attributes and no object file, so nothing to do.  */
2167
0
  if (!res.has_object_attributes && frozen_cfg->size == 0)
2168
0
    return NULL;
2169
  /* If frozen object attributes were set by some command-line options, we still
2170
     need to emit warnings / errors if incompatibilities exist.  */
2171
2172
  /* Set the object attribute version for the output object to the recommended
2173
     value by the backend.  */
2174
0
  elf_obj_attr_version (info->output_bfd)
2175
0
    = get_elf_backend_data (info->output_bfd)->default_obj_attr_version;
2176
2177
0
  if (res.sec == NULL)
2178
0
    {
2179
      /* This input object has no object attribute section matching the name and
2180
   type specified by the backend, i.e. elf_backend_obj_attrs_section and
2181
   elf_backend_obj_attrs_section_type.
2182
   One of the two following cases is possible:
2183
   1. No object attribute were found in this file, so the object attribute
2184
      version was never set by the deserializer.
2185
   2. The deserializer might have found attributes in another section with
2186
      the correct type but the wrong name.  The object attribute version
2187
      should have been set correctly in this case.
2188
   Whatever of those two cases, we set the object attribute version to the
2189
   backend's recommended value, and create a new section with the expected
2190
   name and type.  */
2191
0
      elf_obj_attr_version (res.pbfd)
2192
0
  = get_elf_backend_data (res.pbfd)->default_obj_attr_version;
2193
0
      res.sec = create_object_attributes_section (info, res.pbfd);
2194
0
    }
2195
2196
  /* Merge all the input object files againt res.pbfd and frozen_cfg, and
2197
     accumulate the merge result in res.pbfd.  */
2198
0
  success &= oav2_merge_all (info, res.pbfd, info->input_bfds, frozen_cfg);
2199
0
  if (! success)
2200
0
    return NULL;
2201
2202
  /* Prune all subsections and attributes with a status different from OK.  */
2203
0
  if (! oav2_prune_nok_attrs (info, res.pbfd))
2204
0
    return NULL;
2205
0
  BFD_ASSERT (elf_obj_attr_subsections (res.pbfd).size > 0);
2206
2207
  /* Swap the old object attributes stored in output_bfd (i.e. the frozen
2208
     config) with the final merge result.  */
2209
0
  LINKED_LIST_SWAP_LISTS (obj_attr_subsection_list_t)
2210
0
    (&elf_obj_attr_subsections (info->output_bfd),
2211
0
     &elf_obj_attr_subsections (res.pbfd));
2212
2213
  /* Note: the object attributes section in the output object is copied from
2214
     the input object which was used for the merge (res.pbfd).  No need to
2215
     create it here.  However, so that the section is copied to the output
2216
     object, the size must be different from 0.  For now, we will set this
2217
     size to 1.  The real size will be set later.  */
2218
0
  res.sec->size = 1;
2219
2220
0
  return res.pbfd;
2221
0
}
2222
2223
/* Allocate/find an object attribute.  */
2224
obj_attribute *
2225
bfd_elf_new_obj_attr (bfd *abfd, obj_attr_vendor_t vendor, obj_attr_tag_t tag)
2226
190k
{
2227
190k
  obj_attribute *attr;
2228
190k
  obj_attribute_list *list;
2229
190k
  obj_attribute_list *p;
2230
190k
  obj_attribute_list **lastp;
2231
2232
2233
190k
  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
2234
157k
    {
2235
      /* Known tags are preallocated.  */
2236
157k
      attr = &elf_known_obj_attributes (abfd)[vendor][tag];
2237
157k
    }
2238
33.1k
  else
2239
33.1k
    {
2240
      /* Create a new tag.  */
2241
33.1k
      list = (obj_attribute_list *)
2242
33.1k
  bfd_alloc (abfd, sizeof (obj_attribute_list));
2243
33.1k
      if (list == NULL)
2244
0
  return NULL;
2245
33.1k
      memset (list, 0, sizeof (obj_attribute_list));
2246
33.1k
      list->tag = tag;
2247
      /* Keep the tag list in order.  */
2248
33.1k
      lastp = &elf_other_obj_attributes (abfd)[vendor];
2249
956k
      for (p = *lastp; p; p = p->next)
2250
951k
  {
2251
951k
    if (tag < p->tag)
2252
28.1k
      break;
2253
923k
    lastp = &p->next;
2254
923k
  }
2255
33.1k
      list->next = *lastp;
2256
33.1k
      *lastp = list;
2257
33.1k
      attr = &list->attr;
2258
33.1k
    }
2259
2260
190k
  return attr;
2261
190k
}
2262
2263
/* Return the value of an integer object attribute.  */
2264
int
2265
bfd_elf_get_obj_attr_int (bfd *abfd,
2266
        obj_attr_vendor_t vendor,
2267
        obj_attr_tag_t tag)
2268
946
{
2269
946
  obj_attribute_list *p;
2270
2271
946
  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
2272
946
    {
2273
      /* Known tags are preallocated.  */
2274
946
      return elf_known_obj_attributes (abfd)[vendor][tag].i;
2275
946
    }
2276
0
  else
2277
0
    {
2278
0
      for (p = elf_other_obj_attributes (abfd)[vendor];
2279
0
     p;
2280
0
     p = p->next)
2281
0
  {
2282
0
    if (tag == p->tag)
2283
0
      return p->attr.i;
2284
0
    if (tag < p->tag)
2285
0
      break;
2286
0
  }
2287
0
      return 0;
2288
0
    }
2289
946
}
2290
2291
/* Add an integer object attribute.  */
2292
obj_attribute *
2293
bfd_elf_add_obj_attr_int (bfd *abfd,
2294
        obj_attr_vendor_t vendor,
2295
        obj_attr_tag_t tag,
2296
        unsigned int value)
2297
155k
{
2298
155k
  obj_attribute *attr;
2299
2300
155k
  attr = bfd_elf_new_obj_attr (abfd, vendor, tag);
2301
155k
  if (attr != NULL)
2302
155k
    {
2303
155k
      attr->type = bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
2304
155k
      attr->i = value;
2305
155k
    }
2306
155k
  return attr;
2307
155k
}
2308
2309
/* Duplicate an object attribute string value.  */
2310
static char *
2311
elf_attr_strdup (bfd *abfd, const char *s, const char *end)
2312
35.0k
{
2313
35.0k
  char *p;
2314
35.0k
  size_t len;
2315
2316
35.0k
  if (end)
2317
35.0k
    len = strnlen (s, end - s);
2318
0
  else
2319
0
    len = strlen (s);
2320
2321
35.0k
  p = (char *) bfd_alloc (abfd, len + 1);
2322
35.0k
  if (p != NULL)
2323
35.0k
    {
2324
35.0k
      memcpy (p, s, len);
2325
35.0k
      p[len] = 0;
2326
35.0k
    }
2327
35.0k
  return p;
2328
35.0k
}
2329
2330
char *
2331
_bfd_elf_attr_strdup (bfd *abfd, const char *s)
2332
0
{
2333
0
  return elf_attr_strdup (abfd, s, NULL);
2334
0
}
2335
2336
/* Add a string object attribute.  */
2337
static obj_attribute *
2338
elf_add_obj_attr_string (bfd *abfd, obj_attr_vendor_t vendor, obj_attr_tag_t tag,
2339
       const char *s, const char *end)
2340
31.3k
{
2341
31.3k
  obj_attribute *attr;
2342
2343
31.3k
  attr = bfd_elf_new_obj_attr (abfd, vendor, tag);
2344
31.3k
  if (attr != NULL)
2345
31.3k
    {
2346
31.3k
      attr->type = bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
2347
31.3k
      attr->s = elf_attr_strdup (abfd, s, end);
2348
31.3k
      if (attr->s == NULL)
2349
0
  return NULL;
2350
31.3k
    }
2351
31.3k
  return attr;
2352
31.3k
}
2353
2354
obj_attribute *
2355
bfd_elf_add_obj_attr_string (bfd *abfd,
2356
           obj_attr_vendor_t vendor,
2357
           obj_attr_tag_t tag,
2358
           const char *s)
2359
0
{
2360
0
  return elf_add_obj_attr_string (abfd, vendor, tag, s, NULL);
2361
0
}
2362
2363
/* Add a int+string object attribute.  */
2364
static obj_attribute *
2365
elf_add_obj_attr_int_string (bfd *abfd,
2366
           obj_attr_vendor_t vendor,
2367
           obj_attr_tag_t tag,
2368
           unsigned int i,
2369
           const char *s,
2370
           const char *end)
2371
3.64k
{
2372
3.64k
  obj_attribute *attr;
2373
2374
3.64k
  attr = bfd_elf_new_obj_attr (abfd, vendor, tag);
2375
3.64k
  if (attr != NULL)
2376
3.64k
    {
2377
3.64k
      attr->type = bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
2378
3.64k
      attr->i = i;
2379
3.64k
      attr->s = elf_attr_strdup (abfd, s, end);
2380
3.64k
      if (attr->s == NULL)
2381
0
  return NULL;
2382
3.64k
    }
2383
3.64k
  return attr;
2384
3.64k
}
2385
2386
obj_attribute *
2387
bfd_elf_add_obj_attr_int_string (bfd *abfd,
2388
         obj_attr_vendor_t vendor,
2389
         obj_attr_tag_t tag,
2390
         unsigned int i,
2391
         const char *s)
2392
0
{
2393
0
  return elf_add_obj_attr_int_string (abfd, vendor, tag, i, s, NULL);
2394
0
}
2395
2396
/* Copy object attributes v1 from IBFD to OBFD.  */
2397
static void
2398
oav1_copy_attributes (bfd *ibfd, bfd *obfd)
2399
0
{
2400
0
  obj_attribute *in_attr;
2401
0
  obj_attribute *out_attr;
2402
0
  obj_attribute_list *list;
2403
0
  int i;
2404
0
  obj_attr_vendor_t vendor;
2405
2406
0
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
2407
0
    {
2408
0
      in_attr
2409
0
  = &elf_known_obj_attributes (ibfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
2410
0
      out_attr
2411
0
  = &elf_known_obj_attributes (obfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
2412
0
      for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
2413
0
  {
2414
0
    out_attr->type = in_attr->type;
2415
0
    out_attr->i = in_attr->i;
2416
0
    if (in_attr->s && *in_attr->s)
2417
0
      {
2418
0
        out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
2419
0
        if (out_attr->s == NULL)
2420
0
    bfd_perror (_("error adding attribute"));
2421
0
      }
2422
0
    in_attr++;
2423
0
    out_attr++;
2424
0
  }
2425
2426
0
      for (list = elf_other_obj_attributes (ibfd)[vendor];
2427
0
     list;
2428
0
     list = list->next)
2429
0
  {
2430
0
    bool ok = false;
2431
0
    in_attr = &list->attr;
2432
0
    switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
2433
0
      {
2434
0
      case ATTR_TYPE_FLAG_INT_VAL:
2435
0
        ok = bfd_elf_add_obj_attr_int (obfd, vendor,
2436
0
               list->tag, in_attr->i);
2437
0
        break;
2438
0
      case ATTR_TYPE_FLAG_STR_VAL:
2439
0
        ok = bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
2440
0
            in_attr->s);
2441
0
        break;
2442
0
      case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
2443
0
        ok = bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
2444
0
                in_attr->i, in_attr->s);
2445
0
        break;
2446
0
      default:
2447
0
        abort ();
2448
0
      }
2449
0
    if (!ok)
2450
0
      bfd_perror (_("error adding attribute"));
2451
0
  }
2452
0
    }
2453
0
}
2454
2455
static obj_attr_subsection_v2_t *
2456
oav2_obj_attr_subsection_v2_copy (const obj_attr_subsection_v2_t *);
2457
2458
/* Copy object attributes v2 from IBFD to OBFD.  */
2459
static void
2460
oav2_copy_attributes (bfd *ibfd, bfd *obfd)
2461
0
{
2462
0
  const obj_attr_subsection_list_t *in_attr_subsecs
2463
0
    = &elf_obj_attr_subsections (ibfd);
2464
0
  obj_attr_subsection_list_t *out_attr_subsecs
2465
0
    = &elf_obj_attr_subsections (obfd);
2466
2467
0
  for (const obj_attr_subsection_v2_t *isubsec = in_attr_subsecs->first;
2468
0
       isubsec != NULL;
2469
0
       isubsec = isubsec->next)
2470
0
    {
2471
0
      obj_attr_subsection_v2_t *osubsec
2472
0
  = oav2_obj_attr_subsection_v2_copy (isubsec);
2473
0
      LINKED_LIST_APPEND (obj_attr_subsection_v2_t) (out_attr_subsecs, osubsec);
2474
0
    }
2475
0
}
2476
2477
/* Copy the object attributes from IBFD to OBFD.  */
2478
void
2479
_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
2480
315
{
2481
315
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2482
315
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
2483
0
    return;
2484
2485
315
  obj_attr_version_t version = elf_obj_attr_version (ibfd);
2486
315
  elf_obj_attr_version (obfd) = version;
2487
2488
315
  switch (version)
2489
315
    {
2490
315
    case OBJ_ATTR_VERSION_NONE:
2491
315
      break;
2492
0
    case OBJ_ATTR_V1:
2493
0
      oav1_copy_attributes (ibfd, obfd);
2494
0
      break;
2495
0
    case OBJ_ATTR_V2:
2496
0
      oav2_copy_attributes (ibfd, obfd);
2497
0
      break;
2498
0
    default:
2499
0
      abort ();
2500
315
    }
2501
315
}
2502
2503
/* Determine whether a GNU object attribute tag takes an integer, a
2504
   string or both.  */
2505
static int
2506
gnu_obj_attrs_arg_type (obj_attr_tag_t tag)
2507
373k
{
2508
  /* Except for Tag_compatibility, for GNU attributes we follow the
2509
     same rule ARM ones > 32 follow: odd-numbered tags take strings
2510
     and even-numbered tags take integers.  In addition, tag & 2 is
2511
     nonzero for architecture-independent tags and zero for
2512
     architecture-dependent ones.  */
2513
373k
  if (tag == Tag_compatibility)
2514
7.29k
    return 3;
2515
365k
  else
2516
365k
    return (tag & 1) != 0 ? 2 : 1;
2517
373k
}
2518
2519
/* Determine what arguments an attribute tag takes.  */
2520
int
2521
bfd_elf_obj_attrs_arg_type (bfd *abfd,
2522
          obj_attr_vendor_t vendor,
2523
          obj_attr_tag_t tag)
2524
381k
{
2525
  /* This function should only be called for object attributes version 1.  */
2526
381k
  BFD_ASSERT (elf_obj_attr_version (abfd) == OBJ_ATTR_V1);
2527
381k
  switch (vendor)
2528
381k
    {
2529
8.34k
    case OBJ_ATTR_PROC:
2530
8.34k
      return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
2531
0
      break;
2532
373k
    case OBJ_ATTR_GNU:
2533
373k
      return gnu_obj_attrs_arg_type (tag);
2534
0
      break;
2535
0
    default:
2536
0
      abort ();
2537
381k
    }
2538
381k
}
2539
2540
static void
2541
oav1_parse_section (bfd *abfd, bfd_byte *p, bfd_byte *p_end)
2542
2.18k
{
2543
2.18k
  const char *std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
2544
2545
6.13k
  while (p_end - p >= 4)
2546
4.40k
    {
2547
4.40k
      size_t len = p_end - p;
2548
4.40k
      size_t namelen;
2549
4.40k
      size_t section_len;
2550
4.40k
      int vendor;
2551
2552
4.40k
      section_len = bfd_get_32 (abfd, p);
2553
4.40k
      p += 4;
2554
4.40k
      if (section_len == 0)
2555
200
  break;
2556
4.20k
      if (section_len > len)
2557
1.97k
  section_len = len;
2558
4.20k
      if (section_len <= 4)
2559
98
  {
2560
98
    _bfd_error_handler
2561
98
      (_("%pB: error: attribute section length too small: %ld"),
2562
98
       abfd, (long) section_len);
2563
98
    break;
2564
98
  }
2565
4.10k
      section_len -= 4;
2566
4.10k
      namelen = strnlen ((char *) p, section_len) + 1;
2567
4.10k
      if (namelen >= section_len)
2568
162
  break;
2569
3.94k
      if (std_sec && strcmp ((char *) p, std_sec) == 0)
2570
119
  vendor = OBJ_ATTR_PROC;
2571
3.82k
      else if (strcmp ((char *) p, "gnu") == 0)
2572
1.13k
  vendor = OBJ_ATTR_GNU;
2573
2.69k
      else
2574
2.69k
  {
2575
    /* Other vendor section.  Ignore it.  */
2576
2.69k
    p += section_len;
2577
2.69k
    continue;
2578
2.69k
  }
2579
2580
1.24k
      p += namelen;
2581
1.24k
      section_len -= namelen;
2582
3.04k
      while (section_len > 0)
2583
2.03k
  {
2584
2.03k
    unsigned int tag;
2585
2.03k
    unsigned int val;
2586
2.03k
    size_t subsection_len;
2587
2.03k
    bfd_byte *end, *orig_p;
2588
2589
2.03k
    orig_p = p;
2590
2.03k
    tag = _bfd_safe_read_leb128 (abfd, &p, false, p_end);
2591
2.03k
    if (p_end - p >= 4)
2592
1.96k
      {
2593
1.96k
        subsection_len = bfd_get_32 (abfd, p);
2594
1.96k
        p += 4;
2595
1.96k
      }
2596
70
    else
2597
70
      {
2598
70
        p = p_end;
2599
70
        break;
2600
70
      }
2601
1.96k
    if (subsection_len > section_len)
2602
1.01k
      subsection_len = section_len;
2603
1.96k
    section_len -= subsection_len;
2604
1.96k
    end = orig_p + subsection_len;
2605
1.96k
    if (end < p)
2606
163
      break;
2607
1.79k
    switch (tag)
2608
1.79k
      {
2609
1.16k
      case Tag_File:
2610
191k
        while (p < end)
2611
190k
    {
2612
190k
      int type;
2613
190k
      bool ok = false;
2614
2615
190k
      tag = _bfd_safe_read_leb128 (abfd, &p, false, end);
2616
190k
      type = bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
2617
190k
      switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
2618
190k
        {
2619
3.64k
        case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
2620
3.64k
          val = _bfd_safe_read_leb128 (abfd, &p, false, end);
2621
3.64k
          ok = elf_add_obj_attr_int_string (abfd, vendor, tag,
2622
3.64k
              val, (char *) p,
2623
3.64k
              (char *) end);
2624
3.64k
          p += strnlen ((char *) p, end - p);
2625
3.64k
          if (p < end)
2626
3.51k
      p++;
2627
3.64k
          break;
2628
31.3k
        case ATTR_TYPE_FLAG_STR_VAL:
2629
31.3k
          ok = elf_add_obj_attr_string (abfd, vendor, tag,
2630
31.3k
                (char *) p,
2631
31.3k
                (char *) end);
2632
31.3k
          p += strnlen ((char *) p, end - p);
2633
31.3k
          if (p < end)
2634
31.0k
      p++;
2635
31.3k
          break;
2636
155k
        case ATTR_TYPE_FLAG_INT_VAL:
2637
155k
          val = _bfd_safe_read_leb128 (abfd, &p, false, end);
2638
155k
          ok = bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
2639
155k
          break;
2640
0
        default:
2641
0
          abort ();
2642
190k
        }
2643
190k
      if (!ok)
2644
0
        bfd_perror (_("error adding attribute"));
2645
190k
    }
2646
1.16k
        break;
2647
1.16k
      case Tag_Section:
2648
8
      case Tag_Symbol:
2649
        /* Don't have anywhere convenient to attach these.
2650
     Fall through for now.  */
2651
637
      default:
2652
        /* Ignore things we don't know about.  */
2653
637
        p = end;
2654
637
        break;
2655
1.79k
      }
2656
1.79k
  }
2657
1.24k
    }
2658
2.18k
}
2659
2660
#define READ_ULEB128(abfd, var, cursor, end, total_read)    \
2661
61.6k
  do                  \
2662
61.6k
    {                 \
2663
61.6k
      bfd_byte *begin = (cursor);         \
2664
61.6k
      (var) = _bfd_safe_read_leb128 (abfd, &(cursor), false, end);  \
2665
61.6k
      (total_read) += (cursor) - begin;         \
2666
61.6k
    }                  \
2667
61.6k
  while (0)
2668
2669
static int
2670
read_ntbs (bfd *abfd,
2671
     const bfd_byte *cursor,
2672
     const bfd_byte *end,
2673
     char **s)
2674
15.6k
{
2675
15.6k
  *s = NULL;
2676
15.6k
  const size_t MAX_STR_LEN = end - cursor; /* Including \0.  */
2677
15.6k
  const size_t s_len = strnlen ((const char *) cursor, MAX_STR_LEN);
2678
15.6k
  if (s_len == MAX_STR_LEN)
2679
63
    {
2680
63
      bfd_set_error (bfd_error_malformed_archive);
2681
63
      _bfd_error_handler (_("%pB: error: NTBS value seems corrupted "
2682
63
          "(missing '\\0')"),
2683
63
        abfd);
2684
63
      return -1;
2685
63
    }
2686
15.6k
  *s = xmemdup (cursor, s_len + 1, s_len + 1);
2687
15.6k
  return s_len + 1;
2688
15.6k
}
2689
2690
/* Parse an object attribute (v2 only).  */
2691
static ssize_t
2692
oav2_parse_attr (bfd *abfd,
2693
     bfd_byte *cursor,
2694
     const bfd_byte *end,
2695
     obj_attr_encoding_v2_t attr_type,
2696
     obj_attr_v2_t **attr)
2697
38.5k
{
2698
38.5k
  *attr = NULL;
2699
38.5k
  ssize_t total_read = 0;
2700
2701
38.5k
  obj_attr_tag_t attr_tag;
2702
38.5k
  READ_ULEB128 (abfd, attr_tag, cursor, end, total_read);
2703
2704
38.5k
  union obj_attr_value_v2 attr_val;
2705
38.5k
  switch (attr_type)
2706
38.5k
    {
2707
15.3k
    case OA_ENC_NTBS:
2708
15.3k
      {
2709
15.3k
  int read = read_ntbs (abfd, cursor, end, (char **) &attr_val.string);
2710
15.3k
  if (read <= 0)
2711
63
    return -1;
2712
15.2k
  total_read += read;
2713
15.2k
      }
2714
0
      break;
2715
23.1k
    case OA_ENC_ULEB128:
2716
23.1k
      READ_ULEB128 (abfd, attr_val.uint, cursor, end, total_read);
2717
23.1k
      break;
2718
0
    default:
2719
0
      abort ();
2720
38.5k
    }
2721
2722
38.4k
  *attr = bfd_elf_obj_attr_v2_init (attr_tag, attr_val);
2723
38.4k
  return total_read;
2724
38.5k
}
2725
2726
/* Parse a subsection (object attributes v2 only).  */
2727
static ssize_t
2728
oav2_parse_subsection (bfd *abfd,
2729
           bfd_byte *cursor,
2730
           const uint64_t max_read,
2731
           obj_attr_subsection_v2_t **subsec)
2732
517
{
2733
517
  *subsec = NULL;
2734
517
  ssize_t total_read = 0;
2735
2736
517
  char *subsection_name = NULL;
2737
517
  const uint32_t F_SUBSECTION_LEN = sizeof(uint32_t);
2738
517
  const uint32_t F_SUBSECTION_COMPREHENSION = sizeof(uint8_t);
2739
517
  const uint32_t F_SUBSECTION_ENCODING = sizeof(uint8_t);
2740
  /* The minimum subsection length is 7: 4 bytes for the length itself, and 1
2741
     byte for an empty NUL-terminated string, 1 byte for the comprehension,
2742
     1 byte for the encoding, and no vendor-data.  */
2743
517
  const uint32_t F_MIN_SUBSECTION_DATA_LEN
2744
517
    = F_SUBSECTION_LEN + 1 /* for '\0' */
2745
517
      + F_SUBSECTION_COMPREHENSION + F_SUBSECTION_ENCODING;
2746
2747
  /* Similar to the issues reported in PR 17531, we need to check all the sizes
2748
     and offsets as we parse the section.  */
2749
517
  if (max_read < F_MIN_SUBSECTION_DATA_LEN)
2750
14
    {
2751
14
      _bfd_error_handler (_("%pB: error: attributes subsection ends "
2752
14
          "prematurely"),
2753
14
        abfd);
2754
14
      goto error;
2755
14
    }
2756
2757
503
  const unsigned int subsection_len = bfd_get_32 (abfd, cursor);
2758
503
  const bfd_byte *const end = cursor + subsection_len;
2759
503
  total_read += F_SUBSECTION_LEN;
2760
503
  cursor += F_SUBSECTION_LEN;
2761
503
  if (subsection_len > max_read)
2762
118
    {
2763
118
      _bfd_error_handler
2764
118
  (_("%pB: error: bad subsection length (%u > max=%" PRIu64 ")"),
2765
118
   abfd, subsection_len, max_read);
2766
118
      goto error;
2767
118
    }
2768
385
  else if (subsection_len < F_MIN_SUBSECTION_DATA_LEN)
2769
37
    {
2770
37
      _bfd_error_handler (_("%pB: error: subsection length of %u is too small"),
2771
37
        abfd, subsection_len);
2772
37
      goto error;
2773
37
    }
2774
2775
348
  const size_t max_subsection_name_len
2776
348
    = subsection_len - F_SUBSECTION_LEN
2777
348
      - F_SUBSECTION_COMPREHENSION - F_SUBSECTION_ENCODING;
2778
348
  const bfd_byte *subsection_name_end
2779
348
    = memchr (cursor, '\0', max_subsection_name_len);
2780
348
  if (subsection_name_end == NULL)
2781
14
    {
2782
14
      _bfd_error_handler (_("%pB: error: subsection name seems corrupted "
2783
14
          "(missing '\\0')"),
2784
14
        abfd);
2785
14
      goto error;
2786
14
    }
2787
334
  else
2788
    /* Move the end pointer after '\0'.  */
2789
334
    ++subsection_name_end;
2790
2791
  /* Note: if the length of the subsection name is 0 (i.e. the string is '\0'),
2792
     it is still considered a valid name, even if it is not particularly
2793
     useful.  */
2794
2795
  /* Note: at this stage,
2796
     1. the length of the subsection name is validated, as the presence of '\0'
2797
  at the end of the string, so no risk of buffer overrun.
2798
     2. the data for comprehension and encoding can also safely be read.  */
2799
334
  {
2800
    /* Note: read_ntbs() assigns a dynamically allocated string to
2801
       subsection_name.  Either the string has to be freed in case of errors,
2802
       or its ownership must be transferred.  */
2803
334
    int read = read_ntbs (abfd, cursor, subsection_name_end, &subsection_name);
2804
334
    if (read <= 0)
2805
0
      goto error;
2806
334
    total_read += read;
2807
334
    cursor += read;
2808
334
  }
2809
2810
334
  uint8_t comprehension_raw = bfd_get_8 (abfd, cursor);
2811
334
  ++cursor;
2812
334
  ++total_read;
2813
2814
  /* Comprehension is supposed to be a boolean, so any value greater than 1 is
2815
     considered invalid.  */
2816
334
  if (comprehension_raw > 1)
2817
28
    {
2818
28
      _bfd_error_handler (_("%pB: error: '%s' seems corrupted, got %u but only "
2819
28
          "0 ('%s') or 1 ('%s') are valid values"),
2820
28
        abfd, "comprehension", comprehension_raw,
2821
28
        "required", "optional");
2822
28
      goto error;
2823
28
    }
2824
2825
306
  uint8_t value_encoding_raw = bfd_get_8 (abfd, cursor);
2826
306
  ++cursor;
2827
306
  ++total_read;
2828
2829
  /* Encoding cannot be greater than OA_ENC_MAX, otherwise it means that either
2830
     there is a new encoding that was introduced in the spec, and this
2831
     implementation in binutils is older, and not aware of it so does not
2832
     support it; or the stored value for encoding is garbage.  */
2833
306
  enum obj_attr_encoding_v2 value_encoding
2834
306
    = obj_attr_encoding_v2_from_u8 (value_encoding_raw);
2835
306
  if (value_encoding > OA_ENC_MAX)
2836
19
    {
2837
19
      _bfd_error_handler (_("%pB: error: attribute type seems corrupted, got"
2838
19
          " %u but only 0 (ULEB128) or 1 (NTBS) are "
2839
19
          "valid types"),
2840
19
        abfd, value_encoding);
2841
19
      goto error;
2842
19
    }
2843
2844
287
  obj_attr_subsection_scope_v2_t scope
2845
287
    = bfd_elf_obj_attr_subsection_v2_scope (abfd, subsection_name);
2846
2847
  /* Note: ownership of 'subsection_name' is transfered to the callee when
2848
     initializing the subsection.  That is why we skip free() at the end.  */
2849
287
  *subsec = bfd_elf_obj_attr_subsection_v2_init
2850
287
    (subsection_name, scope, comprehension_raw, value_encoding);
2851
2852
  /* A subsection can be empty, so 'cursor' can be equal to 'end' here.  */
2853
38.7k
  while (cursor < end)
2854
38.5k
    {
2855
38.5k
      obj_attr_v2_t *attr;
2856
38.5k
      ssize_t read = oav2_parse_attr (abfd, cursor, end, value_encoding, &attr);
2857
38.5k
      if (read <= 0)
2858
63
  {
2859
63
    _bfd_elf_obj_attr_subsection_v2_free (*subsec);
2860
63
    *subsec = NULL;
2861
63
    return -1;
2862
63
  }
2863
38.4k
      if (attr != NULL)
2864
38.4k
  LINKED_LIST_APPEND (obj_attr_v2_t) (*subsec, attr);
2865
38.4k
      total_read += read;
2866
38.4k
      cursor += read;
2867
38.4k
    }
2868
2869
224
  BFD_ASSERT (cursor == end);
2870
224
  return total_read;
2871
2872
230
 error:
2873
230
  bfd_set_error (bfd_error_malformed_archive);
2874
230
  if (subsection_name)
2875
47
    free (subsection_name);
2876
230
  return -1;
2877
287
}
2878
2879
/* Parse the list of subsections (object attributes v2 only).  */
2880
static void
2881
oav2_parse_section (bfd *abfd,
2882
        const Elf_Internal_Shdr *hdr,
2883
        bfd_byte *cursor)
2884
302
{
2885
302
  obj_attr_subsection_list_t *subsecs = &elf_obj_attr_subsections (abfd);
2886
302
  ssize_t read = 0;
2887
302
  for (uint64_t remaining = hdr->sh_size - 1; /* Already read 'A'.  */
2888
526
       remaining > 0;
2889
302
       remaining -= read, cursor += read)
2890
517
    {
2891
517
      obj_attr_subsection_v2_t *subsec = NULL;
2892
517
      read = oav2_parse_subsection (abfd, cursor, remaining, &subsec);
2893
517
      if (read < 0)
2894
293
  {
2895
293
    _bfd_error_handler
2896
293
      (_("%pB: error: could not parse subsection at offset %" PRIx64),
2897
293
       abfd, hdr->sh_size - remaining);
2898
293
    bfd_set_error (bfd_error_wrong_format);
2899
293
    break;
2900
293
  }
2901
224
      else
2902
224
  LINKED_LIST_APPEND (obj_attr_subsection_v2_t) (subsecs, subsec);
2903
517
    }
2904
302
}
2905
2906
/* Parse an object attributes section.
2907
   Note: The parsing setup is common between object attributes v1 and v2.  */
2908
void
2909
_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
2910
4.78k
{
2911
4.78k
  elf_obj_attr_version (abfd) = OBJ_ATTR_VERSION_NONE;
2912
2913
  /* PR 17512: file: 2844a11d.  */
2914
4.78k
  if (hdr->sh_size == 0)
2915
132
    return;
2916
2917
4.65k
  ufile_ptr filesize = bfd_get_file_size (abfd);
2918
4.65k
  if (filesize != 0 && hdr->sh_size > filesize)
2919
1.24k
    {
2920
1.24k
      _bfd_error_handler
2921
1.24k
  (_("%pB: error: attribute section '%pA' too big: %" PRIu64),
2922
1.24k
   abfd, hdr->bfd_section, (uint64_t) hdr->sh_size);
2923
1.24k
      bfd_set_error (bfd_error_invalid_operation);
2924
1.24k
      return;
2925
1.24k
    }
2926
2927
3.41k
  bfd_byte *data = (bfd_byte *) bfd_malloc (hdr->sh_size);
2928
3.41k
  if (!data)
2929
0
    return;
2930
2931
3.41k
  if (!bfd_get_section_contents (abfd, hdr->bfd_section, data, 0, hdr->sh_size))
2932
694
    goto free_data;
2933
2934
2.71k
  unsigned char *cursor = data;
2935
2936
  /* The first character is the version of the attributes.  */
2937
2.71k
  obj_attr_version_t version
2938
2.71k
    = get_elf_backend_data (abfd)->obj_attrs_version_dec (*cursor);
2939
2.71k
  if (version == OBJ_ATTR_VERSION_UNSUPPORTED || version > OBJ_ATTR_VERSION_MAX)
2940
230
    {
2941
230
      _bfd_error_handler (_("%pB: error: unknown attributes version '%c'(%d)\n"),
2942
230
        abfd, *cursor, *cursor);
2943
230
      bfd_set_error (bfd_error_wrong_format);
2944
230
      goto free_data;
2945
230
    }
2946
2947
2.48k
  ++cursor;
2948
2949
2.48k
  elf_obj_attr_version (abfd) = version;
2950
2.48k
  switch (version)
2951
2.48k
    {
2952
2.18k
    case OBJ_ATTR_V1:
2953
2.18k
      oav1_parse_section (abfd, cursor, data + hdr->sh_size);
2954
2.18k
      break;
2955
302
    case OBJ_ATTR_V2:
2956
302
      oav2_parse_section (abfd, hdr, cursor);
2957
302
      break;
2958
0
    default:
2959
0
      abort ();
2960
2.48k
    }
2961
2962
3.41k
 free_data:
2963
3.41k
  free (data);
2964
3.41k
}
2965
2966
/* Clean-up all the object attributes in a file.  */
2967
void
2968
_bfd_elf_cleanup_object_attributes (bfd *abfd)
2969
51.1k
{
2970
51.1k
  obj_attr_subsection_list_t *plist = &elf_obj_attr_subsections (abfd);
2971
51.1k
  obj_attr_subsection_v2_t *subsec = plist->first;
2972
51.4k
  while (subsec != NULL)
2973
224
    subsec = oav2_subsec_delete (plist, subsec);
2974
51.1k
}
2975
2976
/* Merge common object attributes from IBFD into OBFD.  Raise an error
2977
   if there are conflicting attributes.  Any processor-specific
2978
   attributes have already been merged.  This must be called from the
2979
   bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
2980
   target, along with any target-specific merging.  Because there are
2981
   no common attributes other than Tag_compatibility at present, and
2982
   non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
2983
   is not presently called for targets without their own
2984
   attributes.  */
2985
2986
bool
2987
_bfd_elf_merge_object_attributes (bfd *ibfd, struct bfd_link_info *info)
2988
0
{
2989
0
  bfd *obfd = info->output_bfd;
2990
0
  obj_attribute *in_attr;
2991
0
  obj_attribute *out_attr;
2992
0
  int vendor;
2993
2994
  /* Set the object attribute version for the output object to the recommended
2995
     value by the backend.  */
2996
0
  elf_obj_attr_version (obfd)
2997
0
    = get_elf_backend_data (obfd)->default_obj_attr_version;
2998
2999
  /* The only common attribute is currently Tag_compatibility,
3000
     accepted in both processor and "gnu" sections.  */
3001
0
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
3002
0
    {
3003
      /* Handle Tag_compatibility.  The tags are only compatible if the flags
3004
   are identical and, if the flags are '1', the strings are identical.
3005
   If the flags are non-zero, then we can only use the string "gnu".  */
3006
0
      in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
3007
0
      out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];
3008
3009
0
      if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
3010
0
  {
3011
0
    _bfd_error_handler
3012
      /* xgettext:c-format */
3013
0
      (_("error: %pB: object has vendor-specific contents that "
3014
0
         "must be processed by the '%s' toolchain"),
3015
0
       ibfd, in_attr->s);
3016
0
    return false;
3017
0
  }
3018
3019
0
      if (in_attr->i != out_attr->i
3020
0
    || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
3021
0
  {
3022
    /* xgettext:c-format */
3023
0
    _bfd_error_handler (_("error: %pB: object tag '%d, %s' is "
3024
0
        "incompatible with tag '%d, %s'"),
3025
0
            ibfd,
3026
0
            in_attr->i, in_attr->s ? in_attr->s : "",
3027
0
            out_attr->i, out_attr->s ? out_attr->s : "");
3028
0
    return false;
3029
0
  }
3030
0
    }
3031
3032
0
  return true;
3033
0
}
3034
3035
/* Merge an unknown processor-specific attribute TAG, within the range
3036
   of known attributes, from IBFD into OBFD; return TRUE if the link
3037
   is OK, FALSE if it must fail.  */
3038
3039
bool
3040
_bfd_elf_merge_unknown_attribute_low (bfd *ibfd, bfd *obfd, int tag)
3041
0
{
3042
0
  obj_attribute *in_attr;
3043
0
  obj_attribute *out_attr;
3044
0
  bfd *err_bfd = NULL;
3045
0
  bool result = true;
3046
3047
0
  in_attr = elf_known_obj_attributes_proc (ibfd);
3048
0
  out_attr = elf_known_obj_attributes_proc (obfd);
3049
3050
0
  if (out_attr[tag].i != 0 || out_attr[tag].s != NULL)
3051
0
    err_bfd = obfd;
3052
0
  else if (in_attr[tag].i != 0 || in_attr[tag].s != NULL)
3053
0
    err_bfd = ibfd;
3054
3055
0
  if (err_bfd != NULL)
3056
0
    result
3057
0
      = get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, tag);
3058
3059
  /* Only pass on attributes that match in both inputs.  */
3060
0
  if (in_attr[tag].i != out_attr[tag].i
3061
0
      || (in_attr[tag].s == NULL) != (out_attr[tag].s == NULL)
3062
0
      || (in_attr[tag].s != NULL && out_attr[tag].s != NULL
3063
0
    && strcmp (in_attr[tag].s, out_attr[tag].s) != 0))
3064
0
    {
3065
0
      out_attr[tag].i = 0;
3066
0
      out_attr[tag].s = NULL;
3067
0
    }
3068
3069
0
  return result;
3070
0
}
3071
3072
/* Merge the lists of unknown processor-specific attributes, outside
3073
   the known range, from IBFD into OBFD; return TRUE if the link is
3074
   OK, FALSE if it must fail.  */
3075
3076
bool
3077
_bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd)
3078
0
{
3079
0
  obj_attribute_list *in_list;
3080
0
  obj_attribute_list *out_list;
3081
0
  obj_attribute_list **out_listp;
3082
0
  bool result = true;
3083
3084
0
  in_list = elf_other_obj_attributes_proc (ibfd);
3085
0
  out_listp = &elf_other_obj_attributes_proc (obfd);
3086
0
  out_list = *out_listp;
3087
3088
0
  for (; in_list || out_list; )
3089
0
    {
3090
0
      bfd *err_bfd = NULL;
3091
0
      unsigned int err_tag = 0;
3092
3093
      /* The tags for each list are in numerical order.  */
3094
      /* If the tags are equal, then merge.  */
3095
0
      if (out_list && (!in_list || in_list->tag > out_list->tag))
3096
0
  {
3097
    /* This attribute only exists in obfd.  We can't merge, and we don't
3098
       know what the tag means, so delete it.  */
3099
0
    err_bfd = obfd;
3100
0
    err_tag = out_list->tag;
3101
0
    *out_listp = out_list->next;
3102
0
    out_list = *out_listp;
3103
0
  }
3104
0
      else if (in_list && (!out_list || in_list->tag < out_list->tag))
3105
0
  {
3106
    /* This attribute only exists in ibfd. We can't merge, and we don't
3107
       know what the tag means, so ignore it.  */
3108
0
    err_bfd = ibfd;
3109
0
    err_tag = in_list->tag;
3110
0
    in_list = in_list->next;
3111
0
  }
3112
0
      else /* The tags are equal.  */
3113
0
  {
3114
    /* As present, all attributes in the list are unknown, and
3115
       therefore can't be merged meaningfully.  */
3116
0
    err_bfd = obfd;
3117
0
    err_tag = out_list->tag;
3118
3119
    /*  Only pass on attributes that match in both inputs.  */
3120
0
    if (in_list->attr.i != out_list->attr.i
3121
0
        || (in_list->attr.s == NULL) != (out_list->attr.s == NULL)
3122
0
        || (in_list->attr.s && out_list->attr.s
3123
0
      && strcmp (in_list->attr.s, out_list->attr.s) != 0))
3124
0
      {
3125
        /* No match.  Delete the attribute.  */
3126
0
        *out_listp = out_list->next;
3127
0
        out_list = *out_listp;
3128
0
      }
3129
0
    else
3130
0
      {
3131
        /* Matched.  Keep the attribute and move to the next.  */
3132
0
        out_list = out_list->next;
3133
0
        in_list = in_list->next;
3134
0
      }
3135
0
  }
3136
3137
0
      if (err_bfd)
3138
0
  result = result
3139
0
    && get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd,
3140
0
                       err_tag);
3141
0
    }
3142
3143
0
  return result;
3144
0
}
3145
3146
/* Create a new object attribute with key TAG and value VAL.
3147
   Return a pointer to it.  */
3148
3149
obj_attr_v2_t *
3150
bfd_elf_obj_attr_v2_init (obj_attr_tag_t tag,
3151
        union obj_attr_value_v2 val)
3152
38.4k
{
3153
38.4k
  obj_attr_v2_t *attr = XCNEW (obj_attr_v2_t);
3154
38.4k
  attr->tag = tag;
3155
38.4k
  attr->val = val;
3156
38.4k
  attr->status = obj_attr_v2_ok;
3157
38.4k
  return attr;
3158
38.4k
}
3159
3160
/* Free memory allocated by the object attribute ATTR.  */
3161
3162
void
3163
_bfd_elf_obj_attr_v2_free (obj_attr_v2_t *attr, obj_attr_encoding_v2_t encoding)
3164
38.4k
{
3165
38.4k
  if (encoding == OA_ENC_NTBS)
3166
    /* Note: this field never holds a string literal.  */
3167
15.2k
    free ((char *) attr->val.string);
3168
38.4k
  free (attr);
3169
38.4k
}
3170
3171
/* Copy an object attribute OTHER, and return a pointer to the copy.  */
3172
3173
obj_attr_v2_t *
3174
_bfd_elf_obj_attr_v2_copy (const obj_attr_v2_t *other,
3175
         obj_attr_encoding_v2_t encoding)
3176
0
{
3177
0
  union obj_attr_value_v2 val;
3178
0
  if (encoding == OA_ENC_NTBS)
3179
0
    val.string
3180
0
      = (other->val.string != NULL
3181
0
   ? xstrdup (other->val.string)
3182
0
   : NULL);
3183
0
  else if (encoding == OA_ENC_ULEB128)
3184
0
    val.uint = other->val.uint;
3185
0
  else
3186
0
    abort ();
3187
3188
0
  obj_attr_v2_t *copy = bfd_elf_obj_attr_v2_init (other->tag, val);
3189
0
  copy->status = other->status;
3190
0
  return copy;
3191
0
}
3192
3193
/* Compare two object attributes based on their TAG value only (partial
3194
   ordering), and return an integer indicating the result of the comparison,
3195
   as follows:
3196
   - 0, if A1 and A2 are equal.
3197
   - a negative value if A1 is less than A2.
3198
   - a positive value if A1 is greater than A2.  */
3199
3200
int
3201
_bfd_elf_obj_attr_v2_cmp (const obj_attr_v2_t *a1, const obj_attr_v2_t *a2)
3202
0
{
3203
0
  if (a1->tag < a2->tag)
3204
0
    return -1;
3205
0
  if (a1->tag > a2->tag)
3206
0
    return 1;
3207
0
  return 0;
3208
0
}
3209
3210
/* Return an object attribute in SUBSEC matching TAG or NULL if one is not
3211
   found.  SORTED specifies whether the given list is ordered by tag number.
3212
   This allows an early return if we find a higher numbered tag.  */
3213
3214
obj_attr_v2_t *
3215
bfd_obj_attr_v2_find_by_tag (const obj_attr_subsection_v2_t *subsec,
3216
            obj_attr_tag_t tag,
3217
            bool sorted)
3218
0
{
3219
0
  for (obj_attr_v2_t *attr = subsec->first;
3220
0
       attr != NULL;
3221
0
       attr = attr->next)
3222
0
    {
3223
0
      if (attr->tag == tag)
3224
0
  return attr;
3225
0
      if (sorted && attr->tag > tag)
3226
0
  break;
3227
0
    }
3228
0
  return NULL;
3229
0
}
3230
3231
/* Sort the object attributes inside a subsection.
3232
   Note: since a subsection is a list of attributes, the sorting algorithm is
3233
   implemented with a merge sort.
3234
   See more details in libiberty/doubly-linked-list.h  */
3235
3236
38.4k
LINKED_LIST_MUTATIVE_OPS_DECL (obj_attr_subsection_v2_t,
obj_attr_v2_t_append
Line
Count
Source
3236
LINKED_LIST_MUTATIVE_OPS_DECL (obj_attr_subsection_v2_t,
Unexecuted instantiation: obj_attr_v2_t_prepend
Unexecuted instantiation: obj_attr_v2_t_insert_before
Unexecuted instantiation: obj_attr_v2_t_pop_front
Unexecuted instantiation: obj_attr_v2_t_pop_back
Unexecuted instantiation: obj_attr_v2_t_remove
Unexecuted instantiation: obj_attr_v2_t_swap
3237
38.4k
             obj_attr_v2_t, /* extern */)
3238
38.4k
LINKED_LIST_MERGE_SORT_DECL (obj_attr_subsection_v2_t,
Unexecuted instantiation: obj_attr_v2_t_merge_sort_
Unexecuted instantiation: obj_attr_v2_t_merge_sort
Unexecuted instantiation: elf-attrs.c:obj_attr_v2_t_merge_sort_compute_turtle_
Unexecuted instantiation: elf-attrs.c:obj_attr_v2_t_merge_sort_merge_
Unexecuted instantiation: elf-attrs.c:obj_attr_v2_t_merge_sort_out_append_
3239
0
           obj_attr_v2_t, /* extern */)
3240
0
3241
0
/* Public API wrapper for LINKED_LIST_APPEND (obj_attr_v2_t).  */
3242
0
3243
0
void bfd_obj_attr_subsection_v2_append (obj_attr_subsection_v2_t *subsec,
3244
0
          obj_attr_v2_t *attr)
3245
0
{
3246
0
  LINKED_LIST_APPEND (obj_attr_v2_t) (subsec, attr);
3247
0
}
3248
3249
/* Create a new object attribute subsection with the following properties:
3250
   - NAME: the name of the subsection.  Note: this parameter never holds a
3251
     string literal, so the value has to be freeable.
3252
   - SCOPE: the scope of the subsection (public or private).
3253
   - OPTIONAL: whether this subsection is optional (true) or required (false).
3254
   - ENCODING: the expected encoding for the attributes values (ULEB128 or NTBS).
3255
   Return a pointer to it.  */
3256
3257
obj_attr_subsection_v2_t *
3258
bfd_elf_obj_attr_subsection_v2_init (const char *name,
3259
              obj_attr_subsection_scope_v2_t scope,
3260
              bool optional,
3261
              obj_attr_encoding_v2_t encoding)
3262
287
{
3263
287
  obj_attr_subsection_v2_t *subsection = XCNEW (obj_attr_subsection_v2_t);
3264
287
  subsection->name = name;
3265
287
  subsection->scope = scope;
3266
287
  subsection->optional = optional;
3267
287
  subsection->encoding = encoding;
3268
287
  subsection->status = obj_attr_subsection_v2_ok;
3269
287
  return subsection;
3270
287
}
3271
3272
/* Free memory allocated by the object attribute subsection SUBSEC.  */
3273
3274
void
3275
_bfd_elf_obj_attr_subsection_v2_free (obj_attr_subsection_v2_t *subsec)
3276
287
{
3277
287
  obj_attr_v2_t *attr = subsec->first;
3278
38.7k
  while (attr != NULL)
3279
38.4k
    {
3280
38.4k
      obj_attr_v2_t *a = attr;
3281
38.4k
      attr = attr->next;
3282
38.4k
      _bfd_elf_obj_attr_v2_free (a, subsec->encoding);
3283
38.4k
    }
3284
  /* Note: this field never holds a string literal.  */
3285
287
  free ((char *) subsec->name);
3286
287
  free (subsec);
3287
287
}
3288
3289
/* Deep copy an object attribute subsection OTHER, and return a pointer to the
3290
   copy.  */
3291
3292
static obj_attr_subsection_v2_t *
3293
oav2_obj_attr_subsection_v2_copy (const obj_attr_subsection_v2_t *other)
3294
0
{
3295
0
  obj_attr_subsection_v2_t *new_subsec
3296
0
    = bfd_elf_obj_attr_subsection_v2_init (xstrdup (other->name), other->scope,
3297
0
              other->optional, other->encoding);
3298
0
  new_subsec->status = other->status;
3299
3300
0
  for (obj_attr_v2_t *attr = other->first;
3301
0
       attr != NULL;
3302
0
       attr = attr->next)
3303
0
    {
3304
0
      obj_attr_v2_t *new_attr = _bfd_elf_obj_attr_v2_copy (attr, other->encoding);
3305
0
      LINKED_LIST_APPEND (obj_attr_v2_t) (new_subsec, new_attr);
3306
0
    }
3307
0
  return new_subsec;
3308
0
}
3309
3310
/* Compare two object attribute subsections based on all their properties.
3311
   This operator can be used to obtain a total order in a collection.
3312
   Return an integer indicating the result of the comparison, as follows:
3313
   - 0, if S1 and S2 are equal.
3314
   - a negative value if S1 is less than S2.
3315
   - a positive value if S1 is greater than S2.
3316
3317
   NB: the scope is computed from the name, so is not used for the
3318
   comparison.  */
3319
3320
int
3321
_bfd_elf_obj_attr_subsection_v2_cmp (const obj_attr_subsection_v2_t *s1,
3322
             const obj_attr_subsection_v2_t *s2)
3323
0
{
3324
0
  int res = strcmp (s1->name, s2->name);
3325
0
  if (res != 0)
3326
0
    return res;
3327
3328
  /* Note: The comparison of the encoding and optionality of subsections
3329
     is entirely arbitrary.  The numeric values could be completely flipped
3330
     around without any effect.  Likewise, assigning higher priority to
3331
     optionality than to encoding is artificial.  The desired properties for
3332
     this comparison operator are reflexivity, transitivity, antisymmetry,
3333
     and totality, in order to achieve a total ordering when sorting a
3334
     collection of subsections.
3335
     If the nature of this ordering were to change in the future, it would
3336
     have no functional impact (but e.g. testsuite expectations might still
3337
     need adjusting) on the final merged result in the output file.  Only the
3338
     order of the serialized subsections would differ, which does not affect
3339
     the interpretation of the object attributes.
3340
     Similarly, the ordering of subsections and attributes in an input file
3341
     does not affect the merge process in ld.  The merge process never assumes
3342
     any particular ordering from the input files, it always sorts the
3343
     subsections and attributes before merging.  This means that using an
3344
     older version of gas with a newer ld is safe, and vice versa as long as
3345
     no new features are used that the older ld doesn't know of.
3346
     In conclusion, the (arbitrary) criteria used to sort subsections during
3347
     the merge process are entirely internal to ld and have no effect on the
3348
     merge result.  */
3349
3350
0
  if (!s1->optional && s2->optional)
3351
0
    return -1;
3352
0
  else if (s1->optional && !s2->optional)
3353
0
    return 1;
3354
3355
0
  if (s1->encoding < s2->encoding)
3356
0
    return -1;
3357
0
  else if (s1->encoding > s2->encoding)
3358
0
    return 1;
3359
3360
0
  return 0;
3361
0
}
3362
3363
/* Return a subsection in the list FIRST matching NAME, or NULL if one is not
3364
   found.  SORTED specifies whether the given list is ordered by name.
3365
   This allows an early return if we find a alphabetically-higher name.  */
3366
3367
obj_attr_subsection_v2_t *
3368
bfd_obj_attr_subsection_v2_find_by_name (obj_attr_subsection_v2_t *first,
3369
           const char *name,
3370
           bool sorted)
3371
0
{
3372
0
  for (obj_attr_subsection_v2_t *s = first;
3373
0
       s != NULL;
3374
0
       s = s->next)
3375
0
    {
3376
0
      int cmp = strcmp (s->name, name);
3377
0
      if (cmp == 0)
3378
0
  return s;
3379
0
      else if (sorted && cmp > 0)
3380
0
  break;
3381
0
    }
3382
0
  return NULL;
3383
0
}
3384
3385
/* Sort the subsections in a vendor section.
3386
   Note: since a section is a list of subsections, the sorting algorithm is
3387
   implemented with a merge sort.
3388
   See more details in libiberty/doubly-linked-list.h  */
3389
3390
1.42k
LINKED_LIST_MUTATIVE_OPS_DECL (obj_attr_subsection_list_t,
obj_attr_subsection_v2_t_append
Line
Count
Source
3390
LINKED_LIST_MUTATIVE_OPS_DECL (obj_attr_subsection_list_t,
Unexecuted instantiation: obj_attr_subsection_v2_t_prepend
Unexecuted instantiation: obj_attr_subsection_v2_t_insert_before
obj_attr_subsection_v2_t_pop_front
Line
Count
Source
3390
LINKED_LIST_MUTATIVE_OPS_DECL (obj_attr_subsection_list_t,
Unexecuted instantiation: obj_attr_subsection_v2_t_pop_back
obj_attr_subsection_v2_t_remove
Line
Count
Source
3390
LINKED_LIST_MUTATIVE_OPS_DECL (obj_attr_subsection_list_t,
Unexecuted instantiation: obj_attr_subsection_v2_t_swap
3391
1.42k
             obj_attr_subsection_v2_t, /* extern */)
3392
1.42k
LINKED_LIST_MERGE_SORT_DECL (obj_attr_subsection_list_t,
Unexecuted instantiation: obj_attr_subsection_v2_t_merge_sort_
Unexecuted instantiation: obj_attr_subsection_v2_t_merge_sort
Unexecuted instantiation: elf-attrs.c:obj_attr_subsection_v2_t_merge_sort_compute_turtle_
Unexecuted instantiation: elf-attrs.c:obj_attr_subsection_v2_t_merge_sort_merge_
Unexecuted instantiation: elf-attrs.c:obj_attr_subsection_v2_t_merge_sort_out_append_
3393
0
           obj_attr_subsection_v2_t, /* extern */)
3394
0
3395
0
/* Public API wrapper for LINKED_LIST_APPEND (obj_attr_subsection_v2_t).  */
3396
0
3397
0
void
3398
0
bfd_obj_attr_subsection_v2_list_append (obj_attr_subsection_list_t *l,
3399
0
          obj_attr_subsection_v2_t *subsec)
3400
0
{
3401
0
  LINKED_LIST_APPEND (obj_attr_subsection_v2_t) (l, subsec);
3402
0
}
3403
3404
/* Public API wrapper for LINKED_LIST_REMOVE (obj_attr_subsection_v2_t).  */
3405
3406
obj_attr_subsection_v2_t *
3407
bfd_obj_attr_subsection_v2_list_remove (obj_attr_subsection_list_t *l,
3408
          obj_attr_subsection_v2_t *subsec)
3409
0
{
3410
0
  return LINKED_LIST_REMOVE (obj_attr_subsection_v2_t) (l, subsec);
3411
0
}
3412
3413
/* Serialize the object attributes in ABFD into the vendor section of
3414
   OUTPUT_BFD.  */
3415
3416
bool _bfd_elf_write_section_object_attributes
3417
  (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
3418
0
{
3419
0
  asection *sec = elf_obj_object_attributes (abfd);
3420
3421
0
  if (sec == NULL)
3422
0
    return true;
3423
3424
0
  bfd_byte *contents = (bfd_byte *) bfd_malloc (sec->size);
3425
0
  if (contents == NULL)
3426
0
    return false; /* Bail out and fail.  */
3427
3428
0
  bfd_elf_set_obj_attr_contents (abfd, contents, sec->size);
3429
0
  bfd_set_section_contents (abfd, sec, contents, 0, sec->size);
3430
0
  free (contents);
3431
  return true;
3432
0
}