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