2009-01-15 Andrew Stubbs <ams@codesourcery.com>

Julian Brown   <julian@codesourcery.com>

	bfd/
	* elf-bfd.h (NUM_KNOWN_OBJ_ATTRIBUTES): Set to 71 to include all known
	ARM attributes in ABI 2.07.
	* elf32-arm.c (get_secondary_compatible_arch): New function.
	(set_secondary_compatible_arch): New function.
	(tag_cpu_arch_combine): New function.
	(elf32_arm_copy_one_eabi_other_attribute): Delete function.
	(elf32_arm_copy_eabi_other_attribute_list): Delete function.
	(elf32_arm_merge_eabi_attributes): Rename order_312 to order_021 to
	make it fit with order_01243.
	Add support for Tag_also_compatible_with,
	Tag_CPU_unaligned_access, Tag_T2EE_use, Tag_Virtualization_use,
	Tag_MPextension_use, Tag_nodefaults and Tag_conformance.
	Improve/tidy up support for Tag_CPU_raw_name, Tag_CPU_name,
	Tag_CPU_arch, Tag_ABI_HardFP_use, Tag_VFP_HP_extension,
	Tag_ABI_FP_denormal, Tag_ABI_PCS_GOT_use, Tag_ABI_align8_needed,
	Tag_VFP_arch and Tag_ABI_FP_16bit_format.
	Rework the way unknown attributes are handled.
	Defer errors until all attributes have been processed.

	gas/
	* config/tc-arm.c (cpu_arch): Change ARM_ARCH_V6M to 11.

	include/elf/
	* arm.h (TAG_CPU_ARCH_V6_M, TAG_CPU_ARCH_V6S_M): New defines.
	(MAX_TAG_CPU_ARCH, TAG_CPU_ARCH_V4T_PLUS_V6_M): New defines.
	(Tag_NEON_arch): Rename to Tag_Advanced_SIMD_arch to match ARM ABI
	version 2.07.
	(Tag_undefined39, Tag_nodefaults): New enum values.
	(Tag_also_compatible_with, Tag_T2EE_use): Likewise.
	(Tag_conformance, Tag_Virtualization_use): Likewise.
	(Tag_undefined69, Tag_MPextension_use): Likewise.
This commit is contained in:
Andrew Stubbs 2009-01-15 18:00:49 +00:00
parent 572d275cf7
commit 91e22acdfa
7 changed files with 555 additions and 153 deletions

View File

@ -1,3 +1,25 @@
2009-01-15 Andrew Stubbs <ams@codesourcery.com>
Julian Brown <julian@codesourcery.com>
* elf-bfd.h (NUM_KNOWN_OBJ_ATTRIBUTES): Set to 71 to include all known
ARM attributes in ABI 2.07.
* elf32-arm.c (get_secondary_compatible_arch): New function.
(set_secondary_compatible_arch): New function.
(tag_cpu_arch_combine): New function.
(elf32_arm_copy_one_eabi_other_attribute): Delete function.
(elf32_arm_copy_eabi_other_attribute_list): Delete function.
(elf32_arm_merge_eabi_attributes): Rename order_312 to order_021 to
make it fit with order_01243.
Add support for Tag_also_compatible_with,
Tag_CPU_unaligned_access, Tag_T2EE_use, Tag_Virtualization_use,
Tag_MPextension_use, Tag_nodefaults and Tag_conformance.
Improve/tidy up support for Tag_CPU_raw_name, Tag_CPU_name,
Tag_CPU_arch, Tag_ABI_HardFP_use, Tag_VFP_HP_extension,
Tag_ABI_FP_denormal, Tag_ABI_PCS_GOT_use, Tag_ABI_align8_needed,
Tag_VFP_arch and Tag_ABI_FP_16bit_format.
Rework the way unknown attributes are handled.
Defer errors until all attributes have been processed.
2009-01-15 Andrew Stubbs <ams@codesourcery.com>
* elf-attrs.c (bfd_elf_add_obj_attr_compat): Rename to

View File

@ -1369,7 +1369,7 @@ struct elf_find_verdep_info
};
/* The maximum number of known object attributes for any target. */
#define NUM_KNOWN_OBJ_ATTRIBUTES 33
#define NUM_KNOWN_OBJ_ATTRIBUTES 71
/* The value of an object attribute. type & 1 indicates whether there
is an integer value; type & 2 indicates whether there is a string

View File

@ -8147,31 +8147,207 @@ elf32_arm_obj_attrs_arg_type (int tag)
return (tag & 1) != 0 ? 2 : 1;
}
static void
elf32_arm_copy_one_eabi_other_attribute (bfd *ibfd, bfd *obfd, obj_attribute_list *in_list)
{
switch (in_list->tag)
{
case Tag_VFP_HP_extension:
case Tag_ABI_FP_16bit_format:
bfd_elf_add_obj_attr_int (obfd, OBJ_ATTR_PROC, in_list->tag, in_list->attr.i);
break;
/* Read the architecture from the Tag_also_compatible_with attribute, if any.
Returns -1 if no architecture could be read. */
default:
if ((in_list->tag & 127) < 64)
{
_bfd_error_handler
(_("Warning: %B: Unknown EABI object attribute %d"), ibfd, in_list->tag);
break;
}
}
static int
get_secondary_compatible_arch (bfd *abfd)
{
obj_attribute *attr =
&elf_known_obj_attributes_proc (abfd)[Tag_also_compatible_with];
/* Note: the tag and its argument below are uleb128 values, though
currently-defined values fit in one byte for each. */
if (attr->s
&& attr->s[0] == Tag_CPU_arch
&& (attr->s[1] & 128) != 128
&& attr->s[2] == 0)
return attr->s[1];
/* This tag is "safely ignorable", so don't complain if it looks funny. */
return -1;
}
static void
elf32_arm_copy_eabi_other_attribute_list (bfd *ibfd, bfd *obfd, obj_attribute_list *in_list)
/* Set, or unset, the architecture of the Tag_also_compatible_with attribute.
The tag is removed if ARCH is -1. */
static void
set_secondary_compatible_arch (bfd *abfd, int arch)
{
for (; in_list; in_list = in_list->next )
elf32_arm_copy_one_eabi_other_attribute (ibfd, obfd, in_list);
obj_attribute *attr =
&elf_known_obj_attributes_proc (abfd)[Tag_also_compatible_with];
if (arch == -1)
{
attr->s = NULL;
return;
}
/* Note: the tag and its argument below are uleb128 values, though
currently-defined values fit in one byte for each. */
if (!attr->s)
attr->s = bfd_alloc (abfd, 3);
attr->s[0] = Tag_CPU_arch;
attr->s[1] = arch;
attr->s[2] = '\0';
}
/* Combine two values for Tag_CPU_arch, taking secondary compatibility tags
into account. */
static int
tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
int newtag, int secondary_compat)
{
#define T(X) TAG_CPU_ARCH_##X
int tagl, tagh, result;
const int v6t2[] =
{
T(V6T2), /* PRE_V4. */
T(V6T2), /* V4. */
T(V6T2), /* V4T. */
T(V6T2), /* V5T. */
T(V6T2), /* V5TE. */
T(V6T2), /* V5TEJ. */
T(V6T2), /* V6. */
T(V7), /* V6KZ. */
T(V6T2) /* V6T2. */
};
const int v6k[] =
{
T(V6K), /* PRE_V4. */
T(V6K), /* V4. */
T(V6K), /* V4T. */
T(V6K), /* V5T. */
T(V6K), /* V5TE. */
T(V6K), /* V5TEJ. */
T(V6K), /* V6. */
T(V6KZ), /* V6KZ. */
T(V7), /* V6T2. */
T(V6K) /* V6K. */
};
const int v7[] =
{
T(V7), /* PRE_V4. */
T(V7), /* V4. */
T(V7), /* V4T. */
T(V7), /* V5T. */
T(V7), /* V5TE. */
T(V7), /* V5TEJ. */
T(V7), /* V6. */
T(V7), /* V6KZ. */
T(V7), /* V6T2. */
T(V7), /* V6K. */
T(V7) /* V7. */
};
const int v6_m[] =
{
-1, /* PRE_V4. */
-1, /* V4. */
T(V6K), /* V4T. */
T(V6K), /* V5T. */
T(V6K), /* V5TE. */
T(V6K), /* V5TEJ. */
T(V6K), /* V6. */
T(V6KZ), /* V6KZ. */
T(V7), /* V6T2. */
T(V6K), /* V6K. */
T(V7), /* V7. */
T(V6_M) /* V6_M. */
};
const int v6s_m[] =
{
-1, /* PRE_V4. */
-1, /* V4. */
T(V6K), /* V4T. */
T(V6K), /* V5T. */
T(V6K), /* V5TE. */
T(V6K), /* V5TEJ. */
T(V6K), /* V6. */
T(V6KZ), /* V6KZ. */
T(V7), /* V6T2. */
T(V6K), /* V6K. */
T(V7), /* V7. */
T(V6S_M), /* V6_M. */
T(V6S_M) /* V6S_M. */
};
const int v4t_plus_v6_m[] =
{
-1, /* PRE_V4. */
-1, /* V4. */
T(V4T), /* V4T. */
T(V5T), /* V5T. */
T(V5TE), /* V5TE. */
T(V5TEJ), /* V5TEJ. */
T(V6), /* V6. */
T(V6KZ), /* V6KZ. */
T(V6T2), /* V6T2. */
T(V6K), /* V6K. */
T(V7), /* V7. */
T(V6_M), /* V6_M. */
T(V6S_M), /* V6S_M. */
T(V4T_PLUS_V6_M) /* V4T plus V6_M. */
};
const int *comb[] =
{
v6t2,
v6k,
v7,
v6_m,
v6s_m,
/* Pseudo-architecture. */
v4t_plus_v6_m
};
/* Check we've not got a higher architecture than we know about. */
if (oldtag >= MAX_TAG_CPU_ARCH || newtag >= MAX_TAG_CPU_ARCH)
{
_bfd_error_handler (_("ERROR: %B: Unknown CPU architecture"), ibfd);
return -1;
}
/* Override old tag if we have a Tag_also_compatible_with on the output. */
if ((oldtag == T(V6_M) && *secondary_compat_out == T(V4T))
|| (oldtag == T(V4T) && *secondary_compat_out == T(V6_M)))
oldtag = T(V4T_PLUS_V6_M);
/* And override the new tag if we have a Tag_also_compatible_with on the
input. */
if ((newtag == T(V6_M) && secondary_compat == T(V4T))
|| (newtag == T(V4T) && secondary_compat == T(V6_M)))
newtag = T(V4T_PLUS_V6_M);
tagl = (oldtag < newtag) ? oldtag : newtag;
result = tagh = (oldtag > newtag) ? oldtag : newtag;
/* Architectures before V6KZ add features monotonically. */
if (tagh <= TAG_CPU_ARCH_V6KZ)
return result;
result = comb[tagh - T(V6T2)][tagl];
/* Use Tag_CPU_arch == V4T and Tag_also_compatible_with (Tag_CPU_arch V6_M)
as the canonical version. */
if (result == T(V4T_PLUS_V6_M))
{
result = T(V4T);
*secondary_compat_out = T(V6_M);
}
else
*secondary_compat_out = -1;
if (result == -1)
{
_bfd_error_handler (_("ERROR: %B: Conflicting CPU architectures %d/%d"),
ibfd, oldtag, newtag);
return -1;
}
return result;
#undef T
}
/* Merge EABI object attributes from IBFD into OBFD. Raise an error if there
@ -8184,12 +8360,14 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
obj_attribute *out_attr;
obj_attribute_list *in_list;
obj_attribute_list *out_list;
obj_attribute_list **out_listp;
/* Some tags have 0 = don't care, 1 = strong requirement,
2 = weak requirement. */
static const int order_312[3] = {3, 1, 2};
static const int order_021[3] = {0, 2, 1};
/* For use with Tag_VFP_arch. */
static const int order_01243[5] = {0, 1, 2, 4, 3};
int i;
bfd_boolean result = TRUE;
if (!elf_known_obj_attributes_proc (obfd)[0].i)
{
@ -8216,7 +8394,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
_bfd_error_handler
(_("ERROR: %B uses VFP register arguments, %B does not"),
ibfd, obfd);
return FALSE;
result = FALSE;
}
}
@ -8227,12 +8405,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
{
case Tag_CPU_raw_name:
case Tag_CPU_name:
/* Use whichever has the greatest architecture requirements. We
won't necessarily have both the above tags, so make sure input
name is non-NULL. */
if (in_attr[Tag_CPU_arch].i > out_attr[Tag_CPU_arch].i
&& in_attr[i].s)
out_attr[i].s = _bfd_elf_attr_strdup (obfd, in_attr[i].s);
/* These are merged after Tag_CPU_arch. */
break;
case Tag_ABI_optimization_goals:
@ -8241,38 +8414,148 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
break;
case Tag_CPU_arch:
{
int secondary_compat = -1, secondary_compat_out = -1;
unsigned int saved_out_attr = out_attr[i].i;
static const char *name_table[] = {
/* These aren't real CPU names, but we can't guess
that from the architecture version alone. */
"Pre v4",
"ARM v4",
"ARM v4T",
"ARM v5T",
"ARM v5TE",
"ARM v5TEJ",
"ARM v6",
"ARM v6KZ",
"ARM v6T2",
"ARM v6K",
"ARM v7",
"ARM v6-M",
"ARM v6S-M"
};
/* Merge Tag_CPU_arch and Tag_also_compatible_with. */
secondary_compat = get_secondary_compatible_arch (ibfd);
secondary_compat_out = get_secondary_compatible_arch (obfd);
out_attr[i].i = tag_cpu_arch_combine (ibfd, out_attr[i].i,
&secondary_compat_out,
in_attr[i].i,
secondary_compat);
set_secondary_compatible_arch (obfd, secondary_compat_out);
/* Merge Tag_CPU_name and Tag_CPU_raw_name. */
if (out_attr[i].i == saved_out_attr)
; /* Leave the names alone. */
else if (out_attr[i].i == in_attr[i].i)
{
/* The output architecture has been changed to match the
input architecture. Use the input names. */
out_attr[Tag_CPU_name].s = in_attr[Tag_CPU_name].s
? _bfd_elf_attr_strdup (obfd, in_attr[Tag_CPU_name].s)
: NULL;
out_attr[Tag_CPU_raw_name].s = in_attr[Tag_CPU_raw_name].s
? _bfd_elf_attr_strdup (obfd, in_attr[Tag_CPU_raw_name].s)
: NULL;
}
else
{
out_attr[Tag_CPU_name].s = NULL;
out_attr[Tag_CPU_raw_name].s = NULL;
}
/* If we still don't have a value for Tag_CPU_name,
make one up now. Tag_CPU_raw_name remains blank. */
if (out_attr[Tag_CPU_name].s == NULL
&& out_attr[i].i < ARRAY_SIZE (name_table))
out_attr[Tag_CPU_name].s =
_bfd_elf_attr_strdup (obfd, name_table[out_attr[i].i]);
}
break;
case Tag_ARM_ISA_use:
case Tag_THUMB_ISA_use:
case Tag_WMMX_arch:
case Tag_NEON_arch:
/* ??? Do NEON and WMMX conflict? */
case Tag_Advanced_SIMD_arch:
/* ??? Do Advanced_SIMD (NEON) and WMMX conflict? */
case Tag_ABI_FP_rounding:
case Tag_ABI_FP_denormal:
case Tag_ABI_FP_exceptions:
case Tag_ABI_FP_user_exceptions:
case Tag_ABI_FP_number_model:
case Tag_ABI_align8_preserved:
case Tag_ABI_HardFP_use:
case Tag_VFP_HP_extension:
case Tag_CPU_unaligned_access:
case Tag_T2EE_use:
case Tag_Virtualization_use:
case Tag_MPextension_use:
/* Use the largest value specified. */
if (in_attr[i].i > out_attr[i].i)
out_attr[i].i = in_attr[i].i;
break;
case Tag_CPU_arch_profile:
/* Warn if conflicting architecture profiles used. */
if (out_attr[i].i && in_attr[i].i && in_attr[i].i != out_attr[i].i)
{
_bfd_error_handler
(_("ERROR: %B: Conflicting architecture profiles %c/%c"),
ibfd, in_attr[i].i, out_attr[i].i);
return FALSE;
}
if (in_attr[i].i)
case Tag_ABI_align8_preserved:
case Tag_ABI_PCS_RO_data:
/* Use the smallest value specified. */
if (in_attr[i].i < out_attr[i].i)
out_attr[i].i = in_attr[i].i;
break;
case Tag_ABI_align8_needed:
if ((in_attr[i].i > 0 || out_attr[i].i > 0)
&& (in_attr[Tag_ABI_align8_preserved].i == 0
|| out_attr[Tag_ABI_align8_preserved].i == 0))
{
/* This error message should be enabled once all non-conformant
binaries in the toolchain have had the attributes set
properly.
_bfd_error_handler
(_("ERROR: %B: 8-byte data alignment conflicts with %B"),
obfd, ibfd);
result = FALSE; */
}
/* Fall through. */
case Tag_ABI_FP_denormal:
case Tag_ABI_PCS_GOT_use:
/* Use the "greatest" from the sequence 0, 2, 1, or the largest
value if greater than 2 (for future-proofing). */
if ((in_attr[i].i > 2 && in_attr[i].i > out_attr[i].i)
|| (in_attr[i].i <= 2 && out_attr[i].i <= 2
&& order_021[in_attr[i].i] > order_021[out_attr[i].i]))
out_attr[i].i = in_attr[i].i;
break;
case Tag_CPU_arch_profile:
if (out_attr[i].i != in_attr[i].i)
{
/* 0 will merge with anything.
'A' and 'S' merge to 'A'.
'R' and 'S' merge to 'R'.
'M' and 'A|R|S' is an error. */
if (out_attr[i].i == 0
|| (out_attr[i].i == 'S'
&& (in_attr[i].i == 'A' || in_attr[i].i == 'R')))
out_attr[i].i = in_attr[i].i;
else if (in_attr[i].i == 0
|| (in_attr[i].i == 'S'
&& (out_attr[i].i == 'A' || out_attr[i].i == 'R')))
; /* Do nothing. */
else
{
_bfd_error_handler
(_("ERROR: %B: Conflicting architecture profiles %c/%c"),
ibfd,
in_attr[i].i ? in_attr[i].i : '0',
out_attr[i].i ? out_attr[i].i : '0');
result = FALSE;
}
}
break;
case Tag_VFP_arch:
if (in_attr[i].i > 4 || out_attr[i].i > 4
|| order_01243[in_attr[i].i] > order_01243[out_attr[i].i])
/* Use the "greatest" from the sequence 0, 1, 2, 4, 3, or the
largest value if greater than 4 (for future-proofing). */
if ((in_attr[i].i > 4 && in_attr[i].i > out_attr[i].i)
|| (in_attr[i].i <= 4 && out_attr[i].i <= 4
&& order_01243[in_attr[i].i] > order_01243[out_attr[i].i]))
out_attr[i].i = in_attr[i].i;
break;
case Tag_PCS_config:
@ -8293,7 +8576,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
{
_bfd_error_handler
(_("ERROR: %B: Conflicting use of R9"), ibfd);
return FALSE;
result = FALSE;
}
if (out_attr[i].i == AEABI_R9_unused)
out_attr[i].i = in_attr[i].i;
@ -8306,22 +8589,12 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
_bfd_error_handler
(_("ERROR: %B: SB relative addressing conflicts with use of R9"),
ibfd);
return FALSE;
result = FALSE;
}
/* Use the smallest value specified. */
if (in_attr[i].i < out_attr[i].i)
out_attr[i].i = in_attr[i].i;
break;
case Tag_ABI_PCS_RO_data:
/* Use the smallest value specified. */
if (in_attr[i].i < out_attr[i].i)
out_attr[i].i = in_attr[i].i;
break;
case Tag_ABI_PCS_GOT_use:
if (in_attr[i].i > 2 || out_attr[i].i > 2
|| order_312[in_attr[i].i] < order_312[out_attr[i].i])
out_attr[i].i = in_attr[i].i;
break;
case Tag_ABI_PCS_wchar_t:
if (out_attr[i].i && in_attr[i].i && out_attr[i].i != in_attr[i].i
&& !elf_arm_tdata (obfd)->no_wchar_size_warning)
@ -8333,12 +8606,6 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
else if (in_attr[i].i && !out_attr[i].i)
out_attr[i].i = in_attr[i].i;
break;
case Tag_ABI_align8_needed:
/* ??? Check against Tag_ABI_align8_preserved. */
if (in_attr[i].i > 2 || out_attr[i].i > 2
|| order_312[in_attr[i].i] < order_312[out_attr[i].i])
out_attr[i].i = in_attr[i].i;
break;
case Tag_ABI_enum_size:
if (in_attr[i].i != AEABI_enum_unused)
{
@ -8353,12 +8620,19 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
&& out_attr[i].i != in_attr[i].i
&& !elf_arm_tdata (obfd)->no_enum_size_warning)
{
const char *aeabi_enum_names[] =
static const char *aeabi_enum_names[] =
{ "", "variable-size", "32-bit", "" };
const char *in_name =
in_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
? aeabi_enum_names[in_attr[i].i]
: "<unknown>";
const char *out_name =
out_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
? aeabi_enum_names[out_attr[i].i]
: "<unknown>";
_bfd_error_handler
(_("warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"),
ibfd, aeabi_enum_names[in_attr[i].i],
aeabi_enum_names[out_attr[i].i]);
ibfd, in_name, out_name);
}
}
break;
@ -8371,34 +8645,98 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
_bfd_error_handler
(_("ERROR: %B uses iWMMXt register arguments, %B does not"),
ibfd, obfd);
return FALSE;
result = FALSE;
}
break;
case Tag_compatibility:
/* Merged in target-independent code. */
break;
case Tag_ABI_HardFP_use:
/* 1 (SP) and 2 (DP) conflict, so combine to 3 (SP & DP). */
if ((in_attr[i].i == 1 && out_attr[i].i == 2)
|| (in_attr[i].i == 2 && out_attr[i].i == 1))
out_attr[i].i = 3;
else if (in_attr[i].i > out_attr[i].i)
out_attr[i].i = in_attr[i].i;
break;
case Tag_ABI_FP_16bit_format:
if (in_attr[i].i != 0 && out_attr[i].i != 0)
{
if (in_attr[i].i != out_attr[i].i)
{
_bfd_error_handler
(_("ERROR: fp16 format mismatch between %B and %B"),
ibfd, obfd);
result = FALSE;
}
}
if (in_attr[i].i != 0)
out_attr[i].i = in_attr[i].i;
break;
default: /* All known attributes should be explicitly covered. */
abort ();
case Tag_nodefaults:
/* This tag is set if it exists, but the value is unused.
Unfortunately, we don't record whether each attribute is zero
initialized, or read from the file, so the information has been
lost. In any case, we don't write attributes with zero values.
Do nothing. */
break;
case Tag_also_compatible_with:
/* Already done in Tag_CPU_arch. */
break;
case Tag_conformance:
/* Keep the attribute if it matches. Throw it away otherwise.
No attribute means no claim to conform. */
if (!in_attr[i].s || !out_attr[i].s
|| strcmp (in_attr[i].s, out_attr[i].s) != 0)
out_attr[i].s = NULL;
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;
}
}
}
/* If out_attr was copied from in_attr then it won't have a type yet. */
if (in_attr[i].type && !out_attr[i].type)
switch (in_attr[i].type)
{
case 1:
if (out_attr[i].i)
out_attr[i].type = 1;
break;
case 2:
if (out_attr[i].s)
out_attr[i].type = 2;
break;
default:
abort ();
}
out_attr[i].type = in_attr[i].type;
}
/* Merge Tag_compatibility attributes and any common GNU ones. */
@ -8406,67 +8744,78 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
/* Check for any attributes not known on ARM. */
in_list = elf_other_obj_attributes_proc (ibfd);
out_list = elf_other_obj_attributes_proc (obfd);
out_listp = &elf_other_obj_attributes_proc (obfd);
out_list = *out_listp;
for (; in_list != NULL; )
for (; in_list || out_list; )
{
if (out_list == NULL)
{
elf32_arm_copy_eabi_other_attribute_list (ibfd, obfd, in_list);
return TRUE;
}
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 (in_list->tag == out_list->tag)
{
switch (in_list->tag)
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))
{
case Tag_VFP_HP_extension:
if (out_list->attr.i == 0)
out_list->attr.i = in_list->attr.i;
break;
case Tag_ABI_FP_16bit_format:
if (in_list->attr.i != 0 && out_list->attr.i != 0)
{
if (in_list->attr.i != out_list->attr.i)
{
_bfd_error_handler
(_("ERROR: fp16 format mismatch between %B and %B"),
ibfd, obfd);
return FALSE;
}
}
if (in_list->attr.i != 0)
out_list->attr.i = in_list->attr.i;
break;
default:
if ((in_list->tag & 127) < 64)
{
_bfd_error_handler
(_("Warning: %B: Unknown EABI object attribute %d"), ibfd, in_list->tag);
break;
}
/* 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;
}
}
else if (in_list->tag < out_list->tag)
if (err_bfd)
{
/* This attribute is in ibfd, but not obfd. Copy to obfd and advance to
next input attribute. */
elf32_arm_copy_one_eabi_other_attribute (ibfd, obfd, in_list);
/* 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);
}
}
if (in_list->tag <= out_list->tag)
{
in_list = in_list->next;
if (in_list == NULL)
continue;
}
while (out_list && out_list->tag < in_list->tag)
out_list = out_list->next;
}
return TRUE;
return result;
}

View File

@ -1,3 +1,8 @@
2009-01-15 Andrew Stubbs <ams@codesourcery.com>
Julian Brown <julian@codesourcery.com>
* config/tc-arm.c (cpu_arch): Change ARM_ARCH_V6M to 11.
2009-01-15 Andrew Stubbs <ams@codesourcery.com>
* read.c (s_vendor_attribute): bfd_elf_add_obj_attr_compat ->

View File

@ -20719,7 +20719,7 @@ static const cpu_arch_ver_table cpu_arch_ver[] =
{6, ARM_ARCH_V6},
{7, ARM_ARCH_V6Z},
{9, ARM_ARCH_V6K},
{9, ARM_ARCH_V6M},
{11, ARM_ARCH_V6M},
{8, ARM_ARCH_V6T2},
{10, ARM_ARCH_V7A},
{10, ARM_ARCH_V7R},

View File

@ -1,3 +1,15 @@
2009-01-15 Andrew Stubbs <ams@codesourcery.com>
Julian Brown <julian@codesourcery.com>
* arm.h (TAG_CPU_ARCH_V6_M, TAG_CPU_ARCH_V6S_M): New defines.
(MAX_TAG_CPU_ARCH, TAG_CPU_ARCH_V4T_PLUS_V6_M): New defines.
(Tag_NEON_arch): Rename to Tag_Advanced_SIMD_arch to match ARM ABI
version 2.07.
(Tag_undefined39, Tag_nodefaults): New enum values.
(Tag_also_compatible_with, Tag_T2EE_use): Likewise.
(Tag_conformance, Tag_Virtualization_use): Likewise.
(Tag_undefined69, Tag_MPextension_use): Likewise.
2009-01-15 Douglas B Rupp <rupp@gnat.com>
* ia64.h (SHT_IA_64_VMS_DISPLAY_NAME_INFO, EF_IA_64_ARCHVER_1):

View File

@ -85,17 +85,23 @@
#define PF_ARM_ABS 0x40000000 /* Segment must be loaded at its base address. */
/* Values for the Tag_CPU_arch EABI attribute. */
#define TAG_CPU_ARCH_PRE_V4 0
#define TAG_CPU_ARCH_V4 1
#define TAG_CPU_ARCH_V4T 2
#define TAG_CPU_ARCH_V5T 3
#define TAG_CPU_ARCH_V5TE 4
#define TAG_CPU_ARCH_V5TEJ 5
#define TAG_CPU_ARCH_V6 6
#define TAG_CPU_ARCH_V6KZ 7
#define TAG_CPU_ARCH_V6T2 8
#define TAG_CPU_ARCH_V6K 9
#define TAG_CPU_ARCH_V7 10
#define TAG_CPU_ARCH_PRE_V4 0
#define TAG_CPU_ARCH_V4 1
#define TAG_CPU_ARCH_V4T 2
#define TAG_CPU_ARCH_V5T 3
#define TAG_CPU_ARCH_V5TE 4
#define TAG_CPU_ARCH_V5TEJ 5
#define TAG_CPU_ARCH_V6 6
#define TAG_CPU_ARCH_V6KZ 7
#define TAG_CPU_ARCH_V6T2 8
#define TAG_CPU_ARCH_V6K 9
#define TAG_CPU_ARCH_V7 10
#define TAG_CPU_ARCH_V6_M 11
#define TAG_CPU_ARCH_V6S_M 12
#define MAX_TAG_CPU_ARCH 12
/* Pseudo-architecture to allow objects to be compatible with the subset of
armv4t and armv6-m. This value should never be stored in object files. */
#define TAG_CPU_ARCH_V4T_PLUS_V6_M (MAX_TAG_CPU_ARCH + 1)
/* Relocation types. */
@ -251,7 +257,7 @@ enum
Tag_THUMB_ISA_use,
Tag_VFP_arch,
Tag_WMMX_arch,
Tag_NEON_arch,
Tag_Advanced_SIMD_arch,
Tag_PCS_config,
Tag_ABI_PCS_R9_use,
Tag_ABI_PCS_RW_data,
@ -271,13 +277,21 @@ enum
Tag_ABI_WMMX_args,
Tag_ABI_optimization_goals,
Tag_ABI_FP_optimization_goals,
/* 32 is generic. */
/* 32 is generic (Tag_compatibility). */
Tag_undefined33 = 33,
Tag_CPU_unaligned_access,
Tag_undefined35,
Tag_undefined35,
Tag_VFP_HP_extension,
Tag_undefined37,
Tag_ABI_FP_16bit_format = 38,
Tag_ABI_FP_16bit_format,
Tag_undefined39,
Tag_nodefaults = 64,
Tag_also_compatible_with,
Tag_T2EE_use,
Tag_conformance,
Tag_Virtualization_use,
Tag_undefined69,
Tag_MPextension_use
};
#endif