* 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.
This commit is contained in:
parent
608bcef267
commit
e8b36cd1e5
@ -1,3 +1,20 @@
|
||||
2010-11-04 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* 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 <hongjiu.lu@intel.com>
|
||||
|
||||
* bfd.c (BFD_FLAGS_FOR_BFD_USE_MASK): New.
|
||||
|
111
bfd/elf-attrs.c
111
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
131
bfd/elf32-arm.c
131
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"
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user