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