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