| 43 |
static bfd_boolean |
static bfd_boolean |
| 44 |
is_default_attr (obj_attribute *attr) |
is_default_attr (obj_attribute *attr) |
| 45 |
{ |
{ |
| 46 |
if ((attr->type & 1) && attr->i != 0) |
if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0) |
| 47 |
return FALSE; |
return FALSE; |
| 48 |
if ((attr->type & 2) && attr->s && *attr->s) |
if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s) |
| 49 |
|
return FALSE; |
| 50 |
|
if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type)) |
| 51 |
return FALSE; |
return FALSE; |
| 52 |
|
|
| 53 |
return TRUE; |
return TRUE; |
| 63 |
return 0; |
return 0; |
| 64 |
|
|
| 65 |
size = uleb128_size (tag); |
size = uleb128_size (tag); |
| 66 |
if (attr->type & 1) |
if (ATTR_TYPE_HAS_INT_VAL (attr->type)) |
| 67 |
size += uleb128_size (attr->i); |
size += uleb128_size (attr->i); |
| 68 |
if (attr->type & 2) |
if (ATTR_TYPE_HAS_STR_VAL (attr->type)) |
| 69 |
size += strlen ((char *)attr->s) + 1; |
size += strlen ((char *)attr->s) + 1; |
| 70 |
return size; |
return size; |
| 71 |
} |
} |
| 151 |
return p; |
return p; |
| 152 |
|
|
| 153 |
p = write_uleb128 (p, tag); |
p = write_uleb128 (p, tag); |
| 154 |
if (attr->type & 1) |
if (ATTR_TYPE_HAS_INT_VAL (attr->type)) |
| 155 |
p = write_uleb128 (p, attr->i); |
p = write_uleb128 (p, attr->i); |
| 156 |
if (attr->type & 2) |
if (ATTR_TYPE_HAS_STR_VAL (attr->type)) |
| 157 |
{ |
{ |
| 158 |
int len; |
int len; |
| 159 |
|
|
| 189 |
|
|
| 190 |
attr = elf_known_obj_attributes (abfd)[vendor]; |
attr = elf_known_obj_attributes (abfd)[vendor]; |
| 191 |
for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) |
for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) |
| 192 |
p = write_obj_attribute (p, i, &attr[i]); |
{ |
| 193 |
|
int tag = i; |
| 194 |
|
if (get_elf_backend_data (abfd)->obj_attrs_order) |
| 195 |
|
tag = get_elf_backend_data (abfd)->obj_attrs_order (i); |
| 196 |
|
p = write_obj_attribute (p, tag, &attr[tag]); |
| 197 |
|
} |
| 198 |
|
|
| 199 |
for (list = elf_other_obj_attributes (abfd)[vendor]; |
for (list = elf_other_obj_attributes (abfd)[vendor]; |
| 200 |
list; |
list; |
| 238 |
|
|
| 239 |
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) |
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) |
| 240 |
{ |
{ |
| 241 |
/* Knwon tags are preallocated. */ |
/* Known tags are preallocated. */ |
| 242 |
attr = &elf_known_obj_attributes (abfd)[vendor][tag]; |
attr = &elf_known_obj_attributes (abfd)[vendor][tag]; |
| 243 |
} |
} |
| 244 |
else |
else |
| 272 |
|
|
| 273 |
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) |
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) |
| 274 |
{ |
{ |
| 275 |
/* Knwon tags are preallocated. */ |
/* Known tags are preallocated. */ |
| 276 |
return elf_known_obj_attributes (abfd)[vendor][tag].i; |
return elf_known_obj_attributes (abfd)[vendor][tag].i; |
| 277 |
} |
} |
| 278 |
else |
else |
| 297 |
obj_attribute *attr; |
obj_attribute *attr; |
| 298 |
|
|
| 299 |
attr = elf_new_obj_attr (abfd, vendor, tag); |
attr = elf_new_obj_attr (abfd, vendor, tag); |
| 300 |
attr->type = 1; |
attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); |
| 301 |
attr->i = i; |
attr->i = i; |
| 302 |
} |
} |
| 303 |
|
|
| 320 |
obj_attribute *attr; |
obj_attribute *attr; |
| 321 |
|
|
| 322 |
attr = elf_new_obj_attr (abfd, vendor, tag); |
attr = elf_new_obj_attr (abfd, vendor, tag); |
| 323 |
attr->type = 2; |
attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); |
| 324 |
attr->s = _bfd_elf_attr_strdup (abfd, s); |
attr->s = _bfd_elf_attr_strdup (abfd, s); |
| 325 |
} |
} |
| 326 |
|
|
| 327 |
/* Add a Tag_compatibility object attribute. */ |
/* Add a int+string object attribute. */ |
| 328 |
void |
void |
| 329 |
bfd_elf_add_obj_attr_compat (bfd *abfd, int vendor, unsigned int i, |
bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag, |
| 330 |
const char *s) |
unsigned int i, const char *s) |
| 331 |
{ |
{ |
| 332 |
obj_attribute_list *list; |
obj_attribute *attr; |
|
obj_attribute_list *p; |
|
|
obj_attribute_list **lastp; |
|
| 333 |
|
|
| 334 |
list = (obj_attribute_list *) |
attr = elf_new_obj_attr (abfd, vendor, tag); |
| 335 |
bfd_alloc (abfd, sizeof (obj_attribute_list)); |
attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); |
| 336 |
memset (list, 0, sizeof (obj_attribute_list)); |
attr->i = i; |
| 337 |
list->tag = Tag_compatibility; |
attr->s = _bfd_elf_attr_strdup (abfd, s); |
|
list->attr.type = 3; |
|
|
list->attr.i = i; |
|
|
list->attr.s = _bfd_elf_attr_strdup (abfd, s); |
|
|
|
|
|
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; |
|
| 338 |
} |
} |
| 339 |
|
|
| 340 |
/* Copy the object attributes from IBFD to OBFD. */ |
/* Copy the object attributes from IBFD to OBFD. */ |
| 366 |
list = list->next) |
list = list->next) |
| 367 |
{ |
{ |
| 368 |
in_attr = &list->attr; |
in_attr = &list->attr; |
| 369 |
switch (in_attr->type) |
switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL)) |
| 370 |
{ |
{ |
| 371 |
case 1: |
case ATTR_TYPE_FLAG_INT_VAL: |
| 372 |
bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i); |
bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i); |
| 373 |
break; |
break; |
| 374 |
case 2: |
case ATTR_TYPE_FLAG_STR_VAL: |
| 375 |
bfd_elf_add_obj_attr_string (obfd, vendor, list->tag, |
bfd_elf_add_obj_attr_string (obfd, vendor, list->tag, |
| 376 |
in_attr->s); |
in_attr->s); |
| 377 |
break; |
break; |
| 378 |
case 3: |
case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL: |
| 379 |
bfd_elf_add_obj_attr_compat (obfd, vendor, in_attr->i, |
bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag, |
| 380 |
in_attr->s); |
in_attr->i, in_attr->s); |
| 381 |
break; |
break; |
| 382 |
default: |
default: |
| 383 |
abort (); |
abort (); |
| 494 |
tag = read_unsigned_leb128 (abfd, p, &n); |
tag = read_unsigned_leb128 (abfd, p, &n); |
| 495 |
p += n; |
p += n; |
| 496 |
type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); |
type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); |
| 497 |
switch (type) |
switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL)) |
| 498 |
{ |
{ |
| 499 |
case 3: |
case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL: |
| 500 |
val = read_unsigned_leb128 (abfd, p, &n); |
val = read_unsigned_leb128 (abfd, p, &n); |
| 501 |
p += n; |
p += n; |
| 502 |
bfd_elf_add_obj_attr_compat (abfd, vendor, val, |
bfd_elf_add_obj_attr_int_string (abfd, vendor, tag, |
| 503 |
(char *)p); |
val, (char *)p); |
| 504 |
p += strlen ((char *)p) + 1; |
p += strlen ((char *)p) + 1; |
| 505 |
break; |
break; |
| 506 |
case 2: |
case ATTR_TYPE_FLAG_STR_VAL: |
| 507 |
bfd_elf_add_obj_attr_string (abfd, vendor, tag, |
bfd_elf_add_obj_attr_string (abfd, vendor, tag, |
| 508 |
(char *)p); |
(char *)p); |
| 509 |
p += strlen ((char *)p) + 1; |
p += strlen ((char *)p) + 1; |
| 510 |
break; |
break; |
| 511 |
case 1: |
case ATTR_TYPE_FLAG_INT_VAL: |
| 512 |
val = read_unsigned_leb128 (abfd, p, &n); |
val = read_unsigned_leb128 (abfd, p, &n); |
| 513 |
p += n; |
p += n; |
| 514 |
bfd_elf_add_obj_attr_int (abfd, vendor, tag, val); |
bfd_elf_add_obj_attr_int (abfd, vendor, tag, val); |
| 549 |
{ |
{ |
| 550 |
obj_attribute *in_attr; |
obj_attribute *in_attr; |
| 551 |
obj_attribute *out_attr; |
obj_attribute *out_attr; |
|
obj_attribute_list *in_list; |
|
|
obj_attribute_list *out_list; |
|
| 552 |
int vendor; |
int vendor; |
| 553 |
|
|
| 554 |
/* The only common attribute is currently Tag_compatibility, |
/* The only common attribute is currently Tag_compatibility, |
| 555 |
accepted in both processor and "gnu" sections. */ |
accepted in both processor and "gnu" sections. */ |
| 556 |
for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) |
for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) |
| 557 |
{ |
{ |
| 558 |
in_list = elf_other_obj_attributes (ibfd)[vendor]; |
/* Handle Tag_compatibility. The tags are only compatible if the flags |
| 559 |
out_list = elf_other_obj_attributes (ibfd)[vendor]; |
are identical and, if the flags are '1', the strings are identical. |
| 560 |
while (in_list && in_list->tag == Tag_compatibility) |
If the flags are non-zero, then we can only use the string "gnu". */ |
| 561 |
|
in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility]; |
| 562 |
|
out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility]; |
| 563 |
|
|
| 564 |
|
if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0) |
| 565 |
{ |
{ |
| 566 |
in_attr = &in_list->attr; |
_bfd_error_handler |
| 567 |
if (in_attr->i == 0) |
(_("error: %B: Must be processed by '%s' toolchain"), |
|
continue; |
|
|
if (in_attr->i == 1 && strcmp (in_attr->s, "gnu") != 0) |
|
|
{ |
|
|
_bfd_error_handler |
|
|
(_("ERROR: %B: Must be processed by '%s' toolchain"), |
|
| 568 |
ibfd, in_attr->s); |
ibfd, in_attr->s); |
| 569 |
return FALSE; |
return FALSE; |
| 570 |
} |
} |
|
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; |
|
|
} |
|
| 571 |
|
|
| 572 |
/* Check the output doesn't have extra tags with this identifier. */ |
if (in_attr->i != out_attr->i |
| 573 |
if (out_list && out_list->tag == Tag_compatibility |
|| (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0)) |
| 574 |
&& strcmp (in_attr->s, out_list->attr.s) == 0) |
{ |
| 575 |
{ |
_bfd_error_handler (_("error: %B: Object tag '%d, %s' is " |
| 576 |
_bfd_error_handler |
"incompatible with tag '%d, %s'"), |
| 577 |
(_("ERROR: %B: Incompatible object tag '%s':%d"), |
ibfd, |
| 578 |
ibfd, in_attr->s, out_list->attr.i); |
in_attr->i, in_attr->s ? in_attr->s : "", |
| 579 |
return FALSE; |
out_attr->i, out_attr->s ? out_attr->s : ""); |
| 580 |
} |
return FALSE; |
| 581 |
} |
} |
| 582 |
} |
} |
| 583 |
|
|