Subversion Repositories Kolibri OS

Rev

Rev 5197 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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