From e8b36cd1e57055ea2eb1e2ba2692f1ec520b34db Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 4 Nov 2010 11:35:01 +0000 Subject: [PATCH] * elf-attrs.c (_bfd_elf_merge_unknown_attribute_low, _bfd_elf_merge_unknown_attribute_list): New. * elf-bfd.h (struct elf_backend_data): Add obj_attrs_handle_unknown. (_bfd_elf_merge_unknown_attribute_low, _bfd_elf_merge_unknown_attribute_list): Declare. * elf32-arm.c (elf32_arm_obj_attrs_handle_unknown): New. Split out from elf32_arm_merge_eabi_attributes. (elf32_arm_merge_eabi_attributes): Use _bfd_elf_merge_unknown_attribute_low and _bfd_elf_merge_unknown_attribute_list. (elf_backend_obj_attrs_handle_unknown): Define. * elfxx-target.h (elf_backend_obj_attrs_handle_unknown): Define. (elfNN_bed): Update initializer. --- bfd/ChangeLog | 17 +++++++ bfd/elf-attrs.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ bfd/elf-bfd.h | 6 +++ bfd/elf32-arm.c | 131 ++++++++++------------------------------------------- bfd/elfxx-target.h | 4 ++ 5 files changed, 163 insertions(+), 106 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 24d096b..2a14bc6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,20 @@ +2010-11-04 Joseph Myers + + * elf-attrs.c (_bfd_elf_merge_unknown_attribute_low, + _bfd_elf_merge_unknown_attribute_list): New. + * elf-bfd.h (struct elf_backend_data): Add + obj_attrs_handle_unknown. + (_bfd_elf_merge_unknown_attribute_low, + _bfd_elf_merge_unknown_attribute_list): Declare. + * elf32-arm.c (elf32_arm_obj_attrs_handle_unknown): New. Split + out from elf32_arm_merge_eabi_attributes. + (elf32_arm_merge_eabi_attributes): Use + _bfd_elf_merge_unknown_attribute_low and + _bfd_elf_merge_unknown_attribute_list. + (elf_backend_obj_attrs_handle_unknown): Define. + * elfxx-target.h (elf_backend_obj_attrs_handle_unknown): Define. + (elfNN_bed): Update initializer. + 2010-11-02 H.J. Lu * bfd.c (BFD_FLAGS_FOR_BFD_USE_MASK): New. diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c index b9d3bf2..e1893d3 100644 --- a/bfd/elf-attrs.c +++ b/bfd/elf-attrs.c @@ -586,3 +586,114 @@ _bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd) return TRUE; } + +/* Merge an unknown processor-specific attribute TAG, within the range + of known attributes, from IBFD into OBFD; return TRUE if the link + is OK, FALSE if it must fail. */ + +bfd_boolean +_bfd_elf_merge_unknown_attribute_low (bfd *ibfd, bfd *obfd, int tag) +{ + obj_attribute *in_attr; + obj_attribute *out_attr; + bfd *err_bfd = NULL; + bfd_boolean result = TRUE; + + in_attr = elf_known_obj_attributes_proc (ibfd); + out_attr = elf_known_obj_attributes_proc (obfd); + + if (out_attr[tag].i != 0 || out_attr[tag].s != NULL) + err_bfd = obfd; + else if (in_attr[tag].i != 0 || in_attr[tag].s != NULL) + err_bfd = ibfd; + + if (err_bfd != NULL) + result + = get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, tag); + + /* Only pass on attributes that match in both inputs. */ + if (in_attr[tag].i != out_attr[tag].i + || in_attr[tag].s != out_attr[tag].s + || (in_attr[tag].s != NULL && out_attr[tag].s != NULL + && strcmp (in_attr[tag].s, out_attr[tag].s) != 0)) + { + out_attr[tag].i = 0; + out_attr[tag].s = NULL; + } + + return result; +} + +/* Merge the lists of unknown processor-specific attributes, outside + the known range, from IBFD into OBFD; return TRUE if the link is + OK, FALSE if it must fail. */ + +bfd_boolean +_bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd) +{ + obj_attribute_list *in_list; + obj_attribute_list *out_list; + obj_attribute_list **out_listp; + bfd_boolean result = TRUE; + + in_list = elf_other_obj_attributes_proc (ibfd); + out_listp = &elf_other_obj_attributes_proc (obfd); + out_list = *out_listp; + + for (; in_list || out_list; ) + { + bfd *err_bfd = NULL; + int err_tag = 0; + + /* The tags for each list are in numerical order. */ + /* If the tags are equal, then merge. */ + if (out_list && (!in_list || in_list->tag > out_list->tag)) + { + /* This attribute only exists in obfd. We can't merge, and we don't + know what the tag means, so delete it. */ + err_bfd = obfd; + err_tag = out_list->tag; + *out_listp = out_list->next; + out_list = *out_listp; + } + else if (in_list && (!out_list || in_list->tag < out_list->tag)) + { + /* This attribute only exists in ibfd. We can't merge, and we don't + know what the tag means, so ignore it. */ + err_bfd = ibfd; + err_tag = in_list->tag; + in_list = in_list->next; + } + else /* The tags are equal. */ + { + /* As present, all attributes in the list are unknown, and + therefore can't be merged meaningfully. */ + err_bfd = obfd; + err_tag = out_list->tag; + + /* Only pass on attributes that match in both inputs. */ + if (in_list->attr.i != out_list->attr.i + || in_list->attr.s != out_list->attr.s + || (in_list->attr.s && out_list->attr.s + && strcmp (in_list->attr.s, out_list->attr.s) != 0)) + { + /* No match. Delete the attribute. */ + *out_listp = out_list->next; + out_list = *out_listp; + } + else + { + /* Matched. Keep the attribute and move to the next. */ + out_list = out_list->next; + in_list = in_list->next; + } + } + + if (err_bfd) + result = result + && get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, + err_tag); + } + + return result; +} diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index e306f8d..2e607f8 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1256,6 +1256,10 @@ struct elf_backend_data actual tag number to place in the input position. */ int (*obj_attrs_order) (int); + /* Handle merging unknown attributes; either warn and return TRUE, + or give an error and return FALSE. */ + bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int); + /* This is non-zero if static TLS segments require a special alignment. */ unsigned static_tls_alignment; @@ -2235,6 +2239,8 @@ extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *); extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int); extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *); extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *); +extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int); +extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *); extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec); /* The linker may needs to keep track of the number of relocs that it diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 24a50a3..577060b 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -9653,6 +9653,27 @@ elf32_arm_obj_attrs_order (int num) return num; } +/* Attribute numbers >=64 (mod 128) can be safely ignored. */ +static bfd_boolean +elf32_arm_obj_attrs_handle_unknown (bfd *abfd, int tag) +{ + if ((tag & 127) < 64) + { + _bfd_error_handler + (_("%B: Unknown mandatory EABI object attribute %d"), + abfd, tag); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + else + { + _bfd_error_handler + (_("Warning: %B: Unknown EABI object attribute %d"), + abfd, tag); + return TRUE; + } +} + /* Read the architecture from the Tag_also_compatible_with attribute, if any. Returns -1 if no architecture could be read. */ @@ -10382,45 +10403,8 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) break; default: - { - bfd *err_bfd = NULL; - - /* The "known_obj_attributes" table does contain some undefined - attributes. Ensure that there are unused. */ - if (out_attr[i].i != 0 || out_attr[i].s != NULL) - err_bfd = obfd; - else if (in_attr[i].i != 0 || in_attr[i].s != NULL) - err_bfd = ibfd; - - if (err_bfd != NULL) - { - /* Attribute numbers >=64 (mod 128) can be safely ignored. */ - if ((i & 127) < 64) - { - _bfd_error_handler - (_("%B: Unknown mandatory EABI object attribute %d"), - err_bfd, i); - bfd_set_error (bfd_error_bad_value); - result = FALSE; - } - else - { - _bfd_error_handler - (_("Warning: %B: Unknown EABI object attribute %d"), - err_bfd, i); - } - } - - /* Only pass on attributes that match in both inputs. */ - if (in_attr[i].i != out_attr[i].i - || in_attr[i].s != out_attr[i].s - || (in_attr[i].s != NULL && out_attr[i].s != NULL - && strcmp (in_attr[i].s, out_attr[i].s) != 0)) - { - out_attr[i].i = 0; - out_attr[i].s = NULL; - } - } + result + = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i); } /* If out_attr was copied from in_attr then it won't have a type yet. */ @@ -10437,74 +10421,8 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) out_listp = &elf_other_obj_attributes_proc (obfd); out_list = *out_listp; - for (; in_list || out_list; ) - { - bfd *err_bfd = NULL; - int err_tag = 0; + result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd); - /* The tags for each list are in numerical order. */ - /* If the tags are equal, then merge. */ - if (out_list && (!in_list || in_list->tag > out_list->tag)) - { - /* This attribute only exists in obfd. We can't merge, and we don't - know what the tag means, so delete it. */ - err_bfd = obfd; - err_tag = out_list->tag; - *out_listp = out_list->next; - out_list = *out_listp; - } - else if (in_list && (!out_list || in_list->tag < out_list->tag)) - { - /* This attribute only exists in ibfd. We can't merge, and we don't - know what the tag means, so ignore it. */ - err_bfd = ibfd; - err_tag = in_list->tag; - in_list = in_list->next; - } - else /* The tags are equal. */ - { - /* As present, all attributes in the list are unknown, and - therefore can't be merged meaningfully. */ - err_bfd = obfd; - err_tag = out_list->tag; - - /* Only pass on attributes that match in both inputs. */ - if (in_list->attr.i != out_list->attr.i - || in_list->attr.s != out_list->attr.s - || (in_list->attr.s && out_list->attr.s - && strcmp (in_list->attr.s, out_list->attr.s) != 0)) - { - /* No match. Delete the attribute. */ - *out_listp = out_list->next; - out_list = *out_listp; - } - else - { - /* Matched. Keep the attribute and move to the next. */ - out_list = out_list->next; - in_list = in_list->next; - } - } - - if (err_bfd) - { - /* Attribute numbers >=64 (mod 128) can be safely ignored. */ - if ((err_tag & 127) < 64) - { - _bfd_error_handler - (_("%B: Unknown mandatory EABI object attribute %d"), - err_bfd, err_tag); - bfd_set_error (bfd_error_bad_value); - result = FALSE; - } - else - { - _bfd_error_handler - (_("Warning: %B: Unknown EABI object attribute %d"), - err_bfd, err_tag); - } - } - } return result; } @@ -13977,6 +13895,7 @@ const struct elf_size_info elf32_arm_size_info = #undef elf_backend_obj_attrs_section_type #define elf_backend_obj_attrs_section_type SHT_ARM_ATTRIBUTES #define elf_backend_obj_attrs_order elf32_arm_obj_attrs_order +#define elf_backend_obj_attrs_handle_unknown elf32_arm_obj_attrs_handle_unknown #include "elf32-target.h" diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 6695afc..fab1b04 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -477,6 +477,9 @@ #ifndef elf_backend_obj_attrs_order #define elf_backend_obj_attrs_order NULL #endif +#ifndef elf_backend_obj_attrs_handle_unknown +#define elf_backend_obj_attrs_handle_unknown NULL +#endif #ifndef elf_backend_static_tls_alignment #define elf_backend_static_tls_alignment 1 #endif @@ -741,6 +744,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_obj_attrs_arg_type, elf_backend_obj_attrs_section_type, elf_backend_obj_attrs_order, + elf_backend_obj_attrs_handle_unknown, elf_backend_static_tls_alignment, elf_backend_collect, elf_backend_type_change_ok, -- 2.7.4