elf-attrs.c revision 214634
1139815Simp/* ELF attributes support (based on ARM EABI attributes).
2206361Sjoel   Copyright 2005, 2006, 2007
375332Sbp   Free Software Foundation, Inc.
475332Sbp
575332Sbp   This file is part of BFD, the Binary File Descriptor library.
675332Sbp
775332Sbp   This program is free software; you can redistribute it and/or modify
875332Sbp   it under the terms of the GNU General Public License as published by
975332Sbp   the Free Software Foundation; either version 2 of the License, or
1075332Sbp   (at your option) any later version.
1175332Sbp
1275332Sbp   This program is distributed in the hope that it will be useful,
1375332Sbp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1475332Sbp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1575332Sbp   GNU General Public License for more details.
1675332Sbp
1775332Sbp   You should have received a copy of the GNU General Public License
1875332Sbp   along with this program; if not, write to the Free Software
1975332Sbp   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2075332Sbp
2175332Sbp#include "sysdep.h"
2275332Sbp#include "bfd.h"
2375332Sbp#include "libiberty.h"
2475332Sbp#include "libbfd.h"
2575332Sbp#include "elf-bfd.h"
26116189Sobrien
27116189Sobrien/* Return the number of bytes needed by I in uleb128 format.  */
28116189Sobrienstatic int
29116189Sobrienuleb128_size (unsigned int i)
3075332Sbp{
3175332Sbp  int size;
3275332Sbp  size = 1;
3375332Sbp  while (i >= 0x80)
3475332Sbp    {
35120492Sfjoe      i >>= 7;
36185652Sjhb      size++;
37120492Sfjoe    }
3875332Sbp  return size;
3975332Sbp}
4075332Sbp
4175332Sbp/* Return TRUE if the attribute has the default value (0/"").  */
4275332Sbpstatic bfd_boolean
4375332Sbpis_default_attr (obj_attribute *attr)
4475332Sbp{
45151897Srwatson  if ((attr->type & 1) && attr->i != 0)
46249132Smav    return FALSE;
4775332Sbp  if ((attr->type & 2) && attr->s && *attr->s)
48120492Sfjoe    return FALSE;
4975332Sbp
50185652Sjhb  return TRUE;
51185652Sjhb}
5275332Sbp
5375332Sbp/* Return the size of a single attribute.  */
5475332Sbpstatic bfd_vma
5575332Sbpobj_attr_size (int tag, obj_attribute *attr)
5675332Sbp{
5775332Sbp  bfd_vma size;
5875332Sbp
5975332Sbp  if (is_default_attr (attr))
6075332Sbp    return 0;
6175332Sbp
6275332Sbp  size = uleb128_size (tag);
6375332Sbp  if (attr->type & 1)
6475332Sbp    size += uleb128_size (attr->i);
6575332Sbp  if (attr->type & 2)
6675332Sbp    size += strlen ((char *)attr->s) + 1;
6775332Sbp  return size;
6875332Sbp}
6975332Sbp
7075332Sbp/* Return the vendor name for a given object attributes section.  */
7175332Sbpstatic const char *
7275332Sbpvendor_obj_attr_name (bfd *abfd, int vendor)
7375332Sbp{
7475332Sbp  return (vendor == OBJ_ATTR_PROC
7575332Sbp	  ? get_elf_backend_data (abfd)->obj_attrs_vendor
7675332Sbp	  : "gnu");
7775332Sbp}
7875332Sbp
7975332Sbp/* Return the size of the object attributes section for VENDOR
8075332Sbp   (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
8175332Sbp   for that vendor to record and the vendor is OBJ_ATTR_GNU.  */
8275332Sbpstatic bfd_vma
8375332Sbpvendor_obj_attr_size (bfd *abfd, int vendor)
8475332Sbp{
8575332Sbp  bfd_vma size;
86185652Sjhb  obj_attribute *attr;
87245149Skevlo  obj_attribute_list *list;
88245149Skevlo  int i;
89245149Skevlo  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
9075332Sbp
91245149Skevlo  if (!vendor_name)
92185652Sjhb    return 0;
93185652Sjhb
94185652Sjhb  attr = elf_known_obj_attributes (abfd)[vendor];
9575332Sbp  size = 0;
96185652Sjhb  for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
97185652Sjhb    size += obj_attr_size (i, &attr[i]);
9875332Sbp
9975332Sbp  for (list = elf_other_obj_attributes (abfd)[vendor];
10075332Sbp       list;
10175332Sbp       list = list->next)
10275332Sbp    size += obj_attr_size (list->tag, &list->attr);
10375332Sbp
10475332Sbp  /* <size> <vendor_name> NUL 0x1 <size> */
10575332Sbp  return ((size || vendor == OBJ_ATTR_PROC)
10675332Sbp	  ? size + 10 + strlen (vendor_name)
10775332Sbp	  : 0);
10875332Sbp}
109185652Sjhb
11075332Sbp/* Return the size of the object attributes section.  */
11175332Sbpbfd_vma
11275332Sbpbfd_elf_obj_attr_size (bfd *abfd)
11375332Sbp{
11475332Sbp  bfd_vma size;
11575332Sbp
11675332Sbp  size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC);
11775332Sbp  size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU);
11875332Sbp
11975332Sbp  /* 'A' <sections for each vendor> */
12075332Sbp  return (size ? size + 1 : 0);
12175332Sbp}
12275332Sbp
12375332Sbp/* Write VAL in uleb128 format to P, returning a pointer to the
12475332Sbp   following byte.  */
12575332Sbpstatic bfd_byte *
12675332Sbpwrite_uleb128 (bfd_byte *p, unsigned int val)
12775332Sbp{
12875332Sbp  bfd_byte c;
12975332Sbp  do
13075332Sbp    {
13175332Sbp      c = val & 0x7f;
13275332Sbp      val >>= 7;
13375332Sbp      if (val)
13475332Sbp	c |= 0x80;
13575332Sbp      *(p++) = c;
13675332Sbp    }
13775332Sbp  while (val);
13875332Sbp  return p;
13975332Sbp}
14075332Sbp
14175332Sbp/* Write attribute ATTR to butter P, and return a pointer to the following
14275332Sbp   byte.  */
14375332Sbpstatic bfd_byte *
14475332Sbpwrite_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
14575332Sbp{
14675332Sbp  /* Suppress default entries.  */
14775332Sbp  if (is_default_attr (attr))
14875332Sbp    return p;
14975332Sbp
15075332Sbp  p = write_uleb128 (p, tag);
15175332Sbp  if (attr->type & 1)
15275332Sbp    p = write_uleb128 (p, attr->i);
15375332Sbp  if (attr->type & 2)
15475332Sbp    {
15575332Sbp      int len;
15675332Sbp
15775332Sbp      len = strlen (attr->s) + 1;
15875332Sbp      memcpy (p, attr->s, len);
15975332Sbp      p += len;
16075332Sbp    }
16175332Sbp
16275332Sbp  return p;
16375332Sbp}
16475332Sbp
16575332Sbp/* Write the contents of the object attributes section (length SIZE)
16675332Sbp   for VENDOR to CONTENTS.  */
16775332Sbpstatic void
16875332Sbpvendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
16975332Sbp			      int vendor)
17075332Sbp{
17175332Sbp  bfd_byte *p;
17275332Sbp  obj_attribute *attr;
17375332Sbp  obj_attribute_list *list;
17475332Sbp  int i;
17575332Sbp  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
17675332Sbp  size_t vendor_length = strlen (vendor_name) + 1;
17775332Sbp
17875332Sbp  p = contents;
17975332Sbp  bfd_put_32 (abfd, size, p);
18075332Sbp  p += 4;
18175332Sbp  memcpy (p, vendor_name, vendor_length);
18275332Sbp  p += vendor_length;
18375332Sbp  *(p++) = Tag_File;
18475332Sbp  bfd_put_32 (abfd, size - 4 - vendor_length, p);
18575332Sbp  p += 4;
18675332Sbp
18775332Sbp  attr = elf_known_obj_attributes (abfd)[vendor];
18875332Sbp  for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
18975332Sbp    p = write_obj_attribute (p, i, &attr[i]);
19075332Sbp
19175332Sbp  for (list = elf_other_obj_attributes (abfd)[vendor];
19275332Sbp       list;
19375332Sbp       list = list->next)
19475332Sbp    p = write_obj_attribute (p, list->tag, &list->attr);
19575332Sbp}
19675332Sbp
19775332Sbp/* Write the contents of the object attributes section to CONTENTS.  */
198111119Simpvoid
19975332Sbpbfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
20075332Sbp{
20175332Sbp  bfd_byte *p;
20275332Sbp  int vendor;
20375332Sbp  bfd_vma my_size;
20475332Sbp
20575332Sbp  p = contents;
20675332Sbp  *(p++) = 'A';
20775332Sbp  my_size = 1;
20875332Sbp  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
20975332Sbp    {
21075332Sbp      bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor);
21175332Sbp      if (vendor_size)
21275332Sbp	vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor);
21375332Sbp      p += vendor_size;
21475332Sbp      my_size += vendor_size;
21575332Sbp    }
21675332Sbp
21775332Sbp  if (size != my_size)
21875332Sbp    abort ();
21975332Sbp}
22075332Sbp
22175332Sbp/* Allocate/find an object attribute.  */
22275332Sbpstatic obj_attribute *
22375332Sbpelf_new_obj_attr (bfd *abfd, int vendor, int tag)
22475332Sbp{
22575332Sbp  obj_attribute *attr;
22675332Sbp  obj_attribute_list *list;
22775332Sbp  obj_attribute_list *p;
22875332Sbp  obj_attribute_list **lastp;
22975332Sbp
23075332Sbp
23175332Sbp  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
23275332Sbp    {
23375332Sbp      /* Knwon tags are preallocated.  */
23475332Sbp      attr = &elf_known_obj_attributes (abfd)[vendor][tag];
23575332Sbp    }
23675332Sbp  else
23775332Sbp    {
23875332Sbp      /* Create a new tag.  */
23975332Sbp      list = (obj_attribute_list *)
24075332Sbp	bfd_alloc (abfd, sizeof (obj_attribute_list));
24175332Sbp      memset (list, 0, sizeof (obj_attribute_list));
24275332Sbp      list->tag = tag;
24375332Sbp      /* Keep the tag list in order.  */
24475332Sbp      lastp = &elf_other_obj_attributes (abfd)[vendor];
24575332Sbp      for (p = *lastp; p; p = p->next)
24675332Sbp	{
24775332Sbp	  if (tag < p->tag)
24875332Sbp	    break;
24975332Sbp	  lastp = &p->next;
25075332Sbp	}
25175332Sbp      list->next = *lastp;
25275332Sbp      *lastp = list;
25375332Sbp      attr = &list->attr;
25475332Sbp    }
25575332Sbp
25675332Sbp  return attr;
25775332Sbp}
25875332Sbp
25975332Sbp/* Return the value of an integer object attribute.  */
26075332Sbpint
26175332Sbpbfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
26275332Sbp{
26375332Sbp  obj_attribute_list *p;
26475332Sbp
26575332Sbp  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
26675332Sbp    {
26775332Sbp      /* Knwon tags are preallocated.  */
26875332Sbp      return elf_known_obj_attributes (abfd)[vendor][tag].i;
26975332Sbp    }
27075332Sbp  else
27175332Sbp    {
27275332Sbp      for (p = elf_other_obj_attributes (abfd)[vendor];
27375332Sbp	   p;
27475332Sbp	   p = p->next)
27575332Sbp	{
27675332Sbp	  if (tag == p->tag)
27775332Sbp	    return p->attr.i;
27875332Sbp	  if (tag < p->tag)
27975332Sbp	    break;
28075332Sbp	}
28175332Sbp      return 0;
282120492Sfjoe    }
28375332Sbp}
28475332Sbp
285120492Sfjoe/* Add an integer object attribute.  */
286120492Sfjoevoid
287120492Sfjoebfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i)
288120492Sfjoe{
289120492Sfjoe  obj_attribute *attr;
290120492Sfjoe
291120492Sfjoe  attr = elf_new_obj_attr (abfd, vendor, tag);
292120492Sfjoe  attr->type = 1;
293120492Sfjoe  attr->i = i;
294120492Sfjoe}
295120492Sfjoe
296120492Sfjoe/* Duplicate an object attribute string value.  */
297120492Sfjoechar *
298120492Sfjoe_bfd_elf_attr_strdup (bfd *abfd, const char * s)
299120492Sfjoe{
300120492Sfjoe  char * p;
301120492Sfjoe  int len;
302120492Sfjoe
303120492Sfjoe  len = strlen (s) + 1;
304120492Sfjoe  p = (char *) bfd_alloc (abfd, len);
305120492Sfjoe  return memcpy (p, s, len);
306194638Sdelphij}
307194638Sdelphij
308194638Sdelphij/* Add a string object attribute.  */
309194638Sdelphijvoid
310194638Sdelphijbfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s)
311194638Sdelphij{
312194638Sdelphij  obj_attribute *attr;
313194638Sdelphij
314194638Sdelphij  attr = elf_new_obj_attr (abfd, vendor, tag);
315194638Sdelphij  attr->type = 2;
316194638Sdelphij  attr->s = _bfd_elf_attr_strdup (abfd, s);
317194638Sdelphij}
31875332Sbp
31975332Sbp/* Add a Tag_compatibility object attribute.  */
32075332Sbpvoid
32175332Sbpbfd_elf_add_obj_attr_compat (bfd *abfd, int vendor, unsigned int i,
32275332Sbp			     const char *s)
32375332Sbp{
32475332Sbp  obj_attribute_list *list;
32575332Sbp  obj_attribute_list *p;
32675332Sbp  obj_attribute_list **lastp;
32775332Sbp
32875332Sbp  list = (obj_attribute_list *)
32975332Sbp    bfd_alloc (abfd, sizeof (obj_attribute_list));
33075332Sbp  memset (list, 0, sizeof (obj_attribute_list));
331185652Sjhb  list->tag = Tag_compatibility;
33275332Sbp  list->attr.type = 3;
33375332Sbp  list->attr.i = i;
33475332Sbp  list->attr.s = _bfd_elf_attr_strdup (abfd, s);
33575332Sbp
33675332Sbp  lastp = &elf_other_obj_attributes (abfd)[vendor];
33775332Sbp  for (p = *lastp; p; p = p->next)
33875332Sbp    {
33975332Sbp      int cmp;
340185652Sjhb      if (p->tag != Tag_compatibility)
34175332Sbp	break;
34275332Sbp      cmp = strcmp(s, p->attr.s);
34375332Sbp      if (cmp < 0 || (cmp == 0 && i < p->attr.i))
34475332Sbp	break;
34575332Sbp      lastp = &p->next;
34675332Sbp    }
34775332Sbp  list->next = *lastp;
34875332Sbp  *lastp = list;
34975332Sbp}
35075332Sbp
35175332Sbp/* Copy the object attributes from IBFD to OBFD.  */
35275332Sbpvoid
35375332Sbp_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
35475332Sbp{
35575332Sbp  obj_attribute *in_attr;
35675332Sbp  obj_attribute *out_attr;
35775332Sbp  obj_attribute_list *list;
35875332Sbp  int i;
35975332Sbp  int vendor;
36075332Sbp
36175332Sbp  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
36275332Sbp    {
36375332Sbp      in_attr = &elf_known_obj_attributes (ibfd)[vendor][4];
364185652Sjhb      out_attr = &elf_known_obj_attributes (obfd)[vendor][4];
36575332Sbp      for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
36675332Sbp	{
36775332Sbp	  out_attr->type = in_attr->type;
36875332Sbp	  out_attr->i = in_attr->i;
36975332Sbp	  if (in_attr->s && *in_attr->s)
37075332Sbp	    out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
37175332Sbp	  in_attr++;
37275332Sbp	  out_attr++;
37375332Sbp	}
37475332Sbp
375185652Sjhb      for (list = elf_other_obj_attributes (ibfd)[vendor];
37675332Sbp	   list;
37775332Sbp	   list = list->next)
37875332Sbp	{
37975332Sbp	  in_attr = &list->attr;
38075332Sbp	  switch (in_attr->type)
38175332Sbp	    {
382230196Skevlo	    case 1:
383230196Skevlo	      bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
384230196Skevlo	      break;
385230196Skevlo	    case 2:
386230196Skevlo	      bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
387230196Skevlo					   in_attr->s);
388230196Skevlo	      break;
389230196Skevlo	    case 3:
390230196Skevlo	      bfd_elf_add_obj_attr_compat (obfd, vendor, in_attr->i,
391230196Skevlo					   in_attr->s);
392230196Skevlo	      break;
393230196Skevlo	    default:
39475332Sbp	      abort ();
39575332Sbp	    }
39675332Sbp	}
39775332Sbp    }
39875332Sbp}
39975332Sbp
40075332Sbp/* Determine whether a GNU object attribute tag takes an integer, a
40175332Sbp   string or both.  */
40275332Sbpstatic int
40375332Sbpgnu_obj_attrs_arg_type (int tag)
40475332Sbp{
40575332Sbp  /* Except for Tag_compatibility, for GNU attributes we follow the
40675332Sbp     same rule ARM ones > 32 follow: odd-numbered tags take strings
40775332Sbp     and even-numbered tags take integers.  In addition, tag & 2 is
40875332Sbp     nonzero for architecture-independent tags and zero for
40975332Sbp     architecture-dependent ones.  */
41075332Sbp  if (tag == Tag_compatibility)
41175332Sbp    return 3;
41275332Sbp  else
413149415Simura    return (tag & 1) != 0 ? 2 : 1;
414149415Simura}
415149415Simura
416149415Simura/* Determine what arguments an attribute tag takes.  */
417149415Simuraint
418149415Simura_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, int tag)
41975332Sbp{
42075332Sbp  switch (vendor)
421185652Sjhb    {
42275332Sbp    case OBJ_ATTR_PROC:
423185652Sjhb      return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
424185652Sjhb      break;
42575332Sbp    case OBJ_ATTR_GNU:
426185652Sjhb      return gnu_obj_attrs_arg_type (tag);
42775332Sbp      break;
428111119Simp    default:
42975332Sbp      abort ();
43075332Sbp    }
43175332Sbp}
43275332Sbp
43375332Sbp/* Parse an object attributes section.  */
43475332Sbpvoid
43575332Sbp_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
43675332Sbp{
437185652Sjhb  bfd_byte *contents;
438120492Sfjoe  bfd_byte *p;
43975332Sbp  bfd_vma len;
44075332Sbp  const char *std_section;
44175332Sbp
442185652Sjhb  contents = bfd_malloc (hdr->sh_size);
44375332Sbp  if (!contents)
44475332Sbp    return;
44575332Sbp  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
44675332Sbp				 hdr->sh_size))
44775332Sbp    {
44875332Sbp      free (contents);
44975332Sbp      return;
45075332Sbp    }
45175332Sbp  p = contents;
45275332Sbp  std_section = get_elf_backend_data (abfd)->obj_attrs_vendor;
45375332Sbp  if (*(p++) == 'A')
45475332Sbp    {
45575332Sbp      len = hdr->sh_size - 1;
45675332Sbp      while (len > 0)
45775332Sbp	{
45875332Sbp	  int namelen;
45975332Sbp	  bfd_vma section_len;
46075332Sbp	  int vendor;
46175332Sbp
46275332Sbp	  section_len = bfd_get_32 (abfd, p);
46375332Sbp	  p += 4;
46475332Sbp	  if (section_len > len)
465194638Sdelphij	    section_len = len;
466194638Sdelphij	  len -= section_len;
467194638Sdelphij	  namelen = strlen ((char *)p) + 1;
468194638Sdelphij	  section_len -= namelen + 4;
469194638Sdelphij	  if (std_section && strcmp ((char *)p, std_section) == 0)
470194638Sdelphij	    vendor = OBJ_ATTR_PROC;
47175332Sbp	  else if (strcmp ((char *)p, "gnu") == 0)
47275332Sbp	    vendor = OBJ_ATTR_GNU;
47375332Sbp	  else
47475332Sbp	    {
47575332Sbp	      /* Other vendor section.  Ignore it.  */
47675332Sbp	      p += namelen + section_len;
47775332Sbp	      continue;
478185652Sjhb	    }
47975332Sbp
480185652Sjhb	  p += namelen;
481185652Sjhb	  while (section_len > 0)
48275332Sbp	    {
483185652Sjhb	      int tag;
48475332Sbp	      unsigned int n;
48575332Sbp	      unsigned int val;
48675332Sbp	      bfd_vma subsection_len;
487185652Sjhb	      bfd_byte *end;
48875332Sbp
48975332Sbp	      tag = read_unsigned_leb128 (abfd, p, &n);
490185652Sjhb	      p += n;
49175332Sbp	      subsection_len = bfd_get_32 (abfd, p);
49275332Sbp	      p += 4;
493185652Sjhb	      if (subsection_len > section_len)
49475332Sbp		subsection_len = section_len;
49575332Sbp	      section_len -= subsection_len;
49675332Sbp	      subsection_len -= n + 4;
49775332Sbp	      end = p + subsection_len;
49875332Sbp	      switch (tag)
49975332Sbp		{
50075332Sbp		case Tag_File:
50175332Sbp		  while (p < end)
502120492Sfjoe		    {
50375332Sbp		      int type;
50475332Sbp
50575332Sbp		      tag = read_unsigned_leb128 (abfd, p, &n);
50675332Sbp		      p += n;
50775332Sbp		      type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
508104568Smux		      switch (type)
509104568Smux			{
51075332Sbp			case 3:
51175332Sbp			  val = read_unsigned_leb128 (abfd, p, &n);
51275332Sbp			  p += n;
51375332Sbp			  bfd_elf_add_obj_attr_compat (abfd, vendor, val,
51475332Sbp						       (char *)p);
515148342Simura			  p += strlen ((char *)p) + 1;
51675332Sbp			  break;
51775332Sbp			case 2:
51875332Sbp			  bfd_elf_add_obj_attr_string (abfd, vendor, tag,
51975332Sbp						       (char *)p);
52075332Sbp			  p += strlen ((char *)p) + 1;
52175332Sbp			  break;
52275332Sbp			case 1:
52375332Sbp			  val = read_unsigned_leb128 (abfd, p, &n);
52475332Sbp			  p += n;
52575332Sbp			  bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
52675332Sbp			  break;
52775332Sbp			default:
52875332Sbp			  abort ();
52975332Sbp			}
53075332Sbp		    }
531104568Smux		  break;
532104568Smux		case Tag_Section:
53375332Sbp		case Tag_Symbol:
53475332Sbp		  /* Don't have anywhere convenient to attach these.
53575332Sbp		     Fall through for now.  */
53675332Sbp		default:
53775332Sbp		  /* Ignore things we don't kow about.  */
53875332Sbp		  p += subsection_len;
53975332Sbp		  subsection_len = 0;
540148342Simura		  break;
54175332Sbp		}
54275332Sbp	    }
54375332Sbp	}
54475332Sbp    }
54575332Sbp  free (contents);
54675332Sbp}
54775332Sbp
54875332Sbp/* Merge common object attributes from IBFD into OBFD.  Raise an error
54975332Sbp   if there are conflicting attributes.  Any processor-specific
55075332Sbp   attributes have already been merged.  This must be called from the
55175332Sbp   bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
55275332Sbp   target, along with any target-specific merging.  Because there are
55375332Sbp   no common attributes other than Tag_compatibility at present, and
554100080Smarkm   non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
555100080Smarkm   is not presently called for targets without their own
556100080Smarkm   attributes.  */
55775332Sbp
55875332Sbpbfd_boolean
55975332Sbp_bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd)
56075332Sbp{
56175332Sbp  obj_attribute *in_attr;
56275332Sbp  obj_attribute *out_attr;
56375332Sbp  obj_attribute_list *in_list;
564120492Sfjoe  obj_attribute_list *out_list;
565120492Sfjoe  int vendor;
566120492Sfjoe
567120492Sfjoe  /* The only common attribute is currently Tag_compatibility,
568120492Sfjoe     accepted in both processor and "gnu" sections.  */
569120492Sfjoe  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
570120492Sfjoe    {
571120492Sfjoe      in_list = elf_other_obj_attributes (ibfd)[vendor];
572120492Sfjoe      out_list = elf_other_obj_attributes (ibfd)[vendor];
573132710Sphk      while (in_list && in_list->tag == Tag_compatibility)
574132710Sphk	{
575132710Sphk	  in_attr = &in_list->attr;
576120492Sfjoe	  if (in_attr->i == 0)
577120492Sfjoe	    continue;
578	  if (in_attr->i == 1 && strcmp (in_attr->s, "gnu") != 0)
579	    {
580	      _bfd_error_handler
581		(_("ERROR: %B: Must be processed by '%s' toolchain"),
582		 ibfd, in_attr->s);
583	      return FALSE;
584	    }
585	  if (!out_list || out_list->tag != Tag_compatibility
586	      || strcmp (in_attr->s, out_list->attr.s) != 0)
587	    {
588	      /* Add this compatibility tag to the output.  */
589	      bfd_elf_add_proc_attr_compat (obfd, in_attr->i, in_attr->s);
590	      continue;
591	    }
592	  out_attr = &out_list->attr;
593	  /* Check all the input tags with the same identifier.  */
594	  for (;;)
595	    {
596	      if (out_list->tag != Tag_compatibility
597		  || in_attr->i != out_attr->i
598		  || strcmp (in_attr->s, out_attr->s) != 0)
599		{
600		  _bfd_error_handler
601		    (_("ERROR: %B: Incompatible object tag '%s':%d"),
602		     ibfd, in_attr->s, in_attr->i);
603		  return FALSE;
604		}
605	      in_list = in_list->next;
606	      if (in_list->tag != Tag_compatibility
607		  || strcmp (in_attr->s, in_list->attr.s) != 0)
608		break;
609	      in_attr = &in_list->attr;
610	      out_list = out_list->next;
611	      if (out_list)
612		out_attr = &out_list->attr;
613	    }
614
615	  /* Check the output doesn't have extra tags with this identifier.  */
616	  if (out_list && out_list->tag == Tag_compatibility
617	      && strcmp (in_attr->s, out_list->attr.s) == 0)
618	    {
619	      _bfd_error_handler
620		(_("ERROR: %B: Incompatible object tag '%s':%d"),
621		 ibfd, in_attr->s, out_list->attr.i);
622	      return FALSE;
623	    }
624	}
625    }
626
627  return TRUE;
628}
629