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