static bfd_boolean
is_default_attr (obj_attribute *attr)
{
- if ((attr->type & 1) && attr->i != 0)
+ if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0)
return FALSE;
- if ((attr->type & 2) && attr->s && *attr->s)
+ if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s)
+ return FALSE;
+ if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type))
return FALSE;
return TRUE;
return 0;
size = uleb128_size (tag);
- if (attr->type & 1)
+ if (ATTR_TYPE_HAS_INT_VAL (attr->type))
size += uleb128_size (attr->i);
- if (attr->type & 2)
+ if (ATTR_TYPE_HAS_STR_VAL (attr->type))
size += strlen ((char *)attr->s) + 1;
return size;
}
return p;
p = write_uleb128 (p, tag);
- if (attr->type & 1)
+ if (ATTR_TYPE_HAS_INT_VAL (attr->type))
p = write_uleb128 (p, attr->i);
- if (attr->type & 2)
+ if (ATTR_TYPE_HAS_STR_VAL (attr->type))
{
int len;
attr = elf_known_obj_attributes (abfd)[vendor];
for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
- p = write_obj_attribute (p, i, &attr[i]);
+ {
+ int tag = i;
+ if (get_elf_backend_data (abfd)->obj_attrs_order)
+ tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
+ p = write_obj_attribute (p, tag, &attr[tag]);
+ }
for (list = elf_other_obj_attributes (abfd)[vendor];
list;
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
{
- /* Knwon tags are preallocated. */
+ /* Known tags are preallocated. */
attr = &elf_known_obj_attributes (abfd)[vendor][tag];
}
else
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
{
- /* Knwon tags are preallocated. */
+ /* Known tags are preallocated. */
return elf_known_obj_attributes (abfd)[vendor][tag].i;
}
else
obj_attribute *attr;
attr = elf_new_obj_attr (abfd, vendor, tag);
- attr->type = 1;
+ attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
attr->i = i;
}
obj_attribute *attr;
attr = elf_new_obj_attr (abfd, vendor, tag);
- attr->type = 2;
+ attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
attr->s = _bfd_elf_attr_strdup (abfd, s);
}
-/* Add a Tag_compatibility object attribute. */
+/* Add a int+string object attribute. */
void
-bfd_elf_add_obj_attr_compat (bfd *abfd, int vendor, unsigned int i,
- const char *s)
+bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag,
+ unsigned int i, const char *s)
{
- obj_attribute_list *list;
- obj_attribute_list *p;
- obj_attribute_list **lastp;
-
- list = (obj_attribute_list *)
- bfd_alloc (abfd, sizeof (obj_attribute_list));
- memset (list, 0, sizeof (obj_attribute_list));
- list->tag = Tag_compatibility;
- list->attr.type = 3;
- list->attr.i = i;
- list->attr.s = _bfd_elf_attr_strdup (abfd, s);
+ obj_attribute *attr;
- lastp = &elf_other_obj_attributes (abfd)[vendor];
- for (p = *lastp; p; p = p->next)
- {
- int cmp;
- if (p->tag != Tag_compatibility)
- break;
- cmp = strcmp(s, p->attr.s);
- if (cmp < 0 || (cmp == 0 && i < p->attr.i))
- break;
- lastp = &p->next;
- }
- list->next = *lastp;
- *lastp = list;
+ attr = elf_new_obj_attr (abfd, vendor, tag);
+ attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+ attr->i = i;
+ attr->s = _bfd_elf_attr_strdup (abfd, s);
}
/* Copy the object attributes from IBFD to OBFD. */
list = list->next)
{
in_attr = &list->attr;
- switch (in_attr->type)
+ switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
{
- case 1:
+ case ATTR_TYPE_FLAG_INT_VAL:
bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
break;
- case 2:
+ case ATTR_TYPE_FLAG_STR_VAL:
bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
in_attr->s);
break;
- case 3:
- bfd_elf_add_obj_attr_compat (obfd, vendor, in_attr->i,
- in_attr->s);
+ case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
+ bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
+ in_attr->i, in_attr->s);
break;
default:
abort ();
tag = read_unsigned_leb128 (abfd, p, &n);
p += n;
type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
- switch (type)
+ switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
{
- case 3:
+ case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
val = read_unsigned_leb128 (abfd, p, &n);
p += n;
- bfd_elf_add_obj_attr_compat (abfd, vendor, val,
- (char *)p);
+ bfd_elf_add_obj_attr_int_string (abfd, vendor, tag,
+ val, (char *)p);
p += strlen ((char *)p) + 1;
break;
- case 2:
+ case ATTR_TYPE_FLAG_STR_VAL:
bfd_elf_add_obj_attr_string (abfd, vendor, tag,
(char *)p);
p += strlen ((char *)p) + 1;
break;
- case 1:
+ case ATTR_TYPE_FLAG_INT_VAL:
val = read_unsigned_leb128 (abfd, p, &n);
p += n;
bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
{
obj_attribute *in_attr;
obj_attribute *out_attr;
- obj_attribute_list *in_list;
- obj_attribute_list *out_list;
int vendor;
/* The only common attribute is currently Tag_compatibility,
accepted in both processor and "gnu" sections. */
for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
{
- in_list = elf_other_obj_attributes (ibfd)[vendor];
- out_list = elf_other_obj_attributes (ibfd)[vendor];
- while (in_list && in_list->tag == Tag_compatibility)
+ /* Handle Tag_compatibility. The tags are only compatible if the flags
+ are identical and, if the flags are '1', the strings are identical.
+ If the flags are non-zero, then we can only use the string "gnu". */
+ in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
+ out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];
+
+ if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
{
- in_attr = &in_list->attr;
- if (in_attr->i == 0)
- continue;
- if (in_attr->i == 1 && strcmp (in_attr->s, "gnu") != 0)
- {
- _bfd_error_handler
+ _bfd_error_handler
(_("ERROR: %B: Must be processed by '%s' toolchain"),
ibfd, in_attr->s);
- return FALSE;
- }
- if (!out_list || out_list->tag != Tag_compatibility
- || strcmp (in_attr->s, out_list->attr.s) != 0)
- {
- /* Add this compatibility tag to the output. */
- bfd_elf_add_proc_attr_compat (obfd, in_attr->i, in_attr->s);
- continue;
- }
- out_attr = &out_list->attr;
- /* Check all the input tags with the same identifier. */
- for (;;)
- {
- if (out_list->tag != Tag_compatibility
- || in_attr->i != out_attr->i
- || strcmp (in_attr->s, out_attr->s) != 0)
- {
- _bfd_error_handler
- (_("ERROR: %B: Incompatible object tag '%s':%d"),
- ibfd, in_attr->s, in_attr->i);
- return FALSE;
- }
- in_list = in_list->next;
- if (in_list->tag != Tag_compatibility
- || strcmp (in_attr->s, in_list->attr.s) != 0)
- break;
- in_attr = &in_list->attr;
- out_list = out_list->next;
- if (out_list)
- out_attr = &out_list->attr;
- }
+ return FALSE;
+ }
- /* Check the output doesn't have extra tags with this identifier. */
- if (out_list && out_list->tag == Tag_compatibility
- && strcmp (in_attr->s, out_list->attr.s) == 0)
- {
- _bfd_error_handler
- (_("ERROR: %B: Incompatible object tag '%s':%d"),
- ibfd, in_attr->s, out_list->attr.i);
- return FALSE;
- }
+ if (in_attr->i != out_attr->i
+ || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
+ {
+ _bfd_error_handler (_("ERROR: %B: Object tag '%d, %s' is "
+ "incompatible with tag '%d, %s'"),
+ ibfd,
+ in_attr->i, in_attr->s ? in_attr->s : "",
+ out_attr->i, out_attr->s ? out_attr->s : "");
+ return FALSE;
}
}