aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-tic6x.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2010-11-02 14:36:39 +0000
committerJoseph Myers <joseph@codesourcery.com>2010-11-02 14:36:39 +0000
commit877791769e23126090bab077d41f4d6221a23045 (patch)
treed2bb3fc25263f3ff4f0567b690aa6a453b263da2 /bfd/elf32-tic6x.c
parent34734a010beee3b56b382dc93249b6cd27c9a373 (diff)
downloadfsf-binutils-gdb-877791769e23126090bab077d41f4d6221a23045.zip
fsf-binutils-gdb-877791769e23126090bab077d41f4d6221a23045.tar.gz
fsf-binutils-gdb-877791769e23126090bab077d41f4d6221a23045.tar.bz2
bfd:
* elf32-tic6x.c (elf32_tic6x_obj_attrs_arg_type): Except for Tag_ABI_compatibility, treat odd tags as strings and even ones as integers. (elf32_tic6x_obj_attrs_order, elf32_tic6x_tag_to_array_alignment, elf32_tic6x_array_alignment_to_tag): New. (elf32_tic6x_merge_attributes): Handle more attributes. Set type for merged attributes. (elf_backend_obj_attrs_order): Define. binutils: * readelf.c (display_tic6x_attribute): Handle more attributes. gas: * config/tc-tic6x.c (OPTION_MPID, OPTION_MPIC, OPTION_MNO_PIC): New enum values. (md_longopts): Add options mpid, mpic and mno-pic. (tic6x_pid_type, tic6x_pid, tic6x_pic, tic6x_pid_type_table, tic6x_pid_types, tic6x_use_pid): New. (md_parse_option): Handle new options. (md_show_usage): Output help text for new options. (tic6x_set_attributes): Set PID and PIC attributes. * doc/as.texinfo: Document -mpid=, -mpic and -mno-pic. * doc/c-tic6x.texi (TIC6X Options): Likewise. gas/testsuite: * gas/tic6x/attr-array-directive-1.d, gas/tic6x/attr-array-directive-1.s, gas/tic6x/attr-array-directive-2.d, gas/tic6x/attr-array-directive-2.s, gas/tic6x/attr-array-directive-3.d, gas/tic6x/attr-array-directive-3.s, gas/tic6x/attr-array-directive-4.d, gas/tic6x/attr-array-directive-4.s, gas/tic6x/attr-conformance-directive-1.d, gas/tic6x/attr-conformance-directive-1.s, gas/tic6x/attr-conformance-directive-2.d, gas/tic6x/attr-conformance-directive-2.s, gas/tic6x/attr-pic-directive-1.d, gas/tic6x/attr-pic-directive-1.s, gas/tic6x/attr-pic-directive-2.d, gas/tic6x/attr-pic-directive-2.s, gas/tic6x/attr-pic-opts-mno-pic.d, gas/tic6x/attr-pic-opts-mpic.d, gas/tic6x/attr-pid-directive-1.d, gas/tic6x/attr-pid-directive-1.s, gas/tic6x/attr-pid-directive-2.d, gas/tic6x/attr-pid-directive-2.s, gas/tic6x/attr-pid-opts-mpid-far.d, gas/tic6x/attr-pid-opts-mpid-near.d, gas/tic6x/attr-pid-opts-mpid-no.d, gas/tic6x/attr-stack-directive-1.d, gas/tic6x/attr-stack-directive-1.s, gas/tic6x/attr-stack-directive-2.d, gas/tic6x/attr-stack-directive-2.s, gas/tic6x/attr-wchar-directive-1.d, gas/tic6x/attr-wchar-directive-1.s, gas/tic6x/attr-wchar-directive-2.d, gas/tic6x/attr-wchar-directive-2.s: New tests. include/elf: * tic6x-attrs.h (Tag_ABI_wchar_t, Tag_ABI_stack_align_needed, Tag_ABI_stack_align_preserved, Tag_ABI_PID, Tag_ABI_PIC, Tag_ABI_array_object_alignment, Tag_ABI_array_object_align_expected, Tag_ABI_conformance): Define. ld/testsuite: * ld-tic6x/attr-array-16-16.d, ld-tic6x/attr-array-16-4.d, ld-tic6x/attr-array-16-416.d, ld-tic6x/attr-array-16-48.d, ld-tic6x/attr-array-16-8.d, ld-tic6x/attr-array-16-816.d, ld-tic6x/attr-array-16.s, ld-tic6x/attr-array-4-16.d, ld-tic6x/attr-array-4-4.d, ld-tic6x/attr-array-4-416.d, ld-tic6x/attr-array-4-48.d, ld-tic6x/attr-array-4-8.d, ld-tic6x/attr-array-4-816.d, ld-tic6x/attr-array-4.s, ld-tic6x/attr-array-416-16.d, ld-tic6x/attr-array-416-4.d, ld-tic6x/attr-array-416-416.d, ld-tic6x/attr-array-416-48.d, ld-tic6x/attr-array-416-8.d, ld-tic6x/attr-array-416-816.d, ld-tic6x/attr-array-416.s, ld-tic6x/attr-array-48-16.d, ld-tic6x/attr-array-48-4.d, ld-tic6x/attr-array-48-416.d, ld-tic6x/attr-array-48-48.d, ld-tic6x/attr-array-48-8.d, ld-tic6x/attr-array-48-816.d, ld-tic6x/attr-array-48.s, ld-tic6x/attr-array-8-16.d, ld-tic6x/attr-array-8-4.d, ld-tic6x/attr-array-8-416.d, ld-tic6x/attr-array-8-48.d, ld-tic6x/attr-array-8-8.d, ld-tic6x/attr-array-8-816.d, ld-tic6x/attr-array-8.s, ld-tic6x/attr-array-816-16.d, ld-tic6x/attr-array-816-4.d, ld-tic6x/attr-array-816-416.d, ld-tic6x/attr-array-816-48.d, ld-tic6x/attr-array-816-8.d, ld-tic6x/attr-array-816-816.d, ld-tic6x/attr-array-816.s, ld-tic6x/attr-conformance-10-10.d, ld-tic6x/attr-conformance-10-11.d, ld-tic6x/attr-conformance-10-none.d, ld-tic6x/attr-conformance-10.s, ld-tic6x/attr-conformance-11-10.d, ld-tic6x/attr-conformance-11-11.d, ld-tic6x/attr-conformance-11-none.d, ld-tic6x/attr-conformance-11.s, ld-tic6x/attr-conformance-none-10.d, ld-tic6x/attr-conformance-none-11.d, ld-tic6x/attr-conformance-none-none.d, ld-tic6x/attr-conformance-none.s, ld-tic6x/attr-pic-0.s, ld-tic6x/attr-pic-00.d, ld-tic6x/attr-pic-01.d, ld-tic6x/attr-pic-1.s, ld-tic6x/attr-pic-10.d, ld-tic6x/attr-pic-11.d, ld-tic6x/attr-pid-0.s, ld-tic6x/attr-pid-00.d, ld-tic6x/attr-pid-01.d, ld-tic6x/attr-pid-02.d, ld-tic6x/attr-pid-1.s, ld-tic6x/attr-pid-10.d, ld-tic6x/attr-pid-11.d, ld-tic6x/attr-pid-12.d, ld-tic6x/attr-pid-2.s, ld-tic6x/attr-pid-20.d, ld-tic6x/attr-pid-21.d, ld-tic6x/attr-pid-22.d, ld-tic6x/attr-stack-16-16.d, ld-tic6x/attr-stack-16-8.d, ld-tic6x/attr-stack-16-816.d, ld-tic6x/attr-stack-16.s, ld-tic6x/attr-stack-8-16.d, ld-tic6x/attr-stack-8-8.d, ld-tic6x/attr-stack-8-816.d, ld-tic6x/attr-stack-8.s, ld-tic6x/attr-stack-816-16.d, ld-tic6x/attr-stack-816-8.d, ld-tic6x/attr-stack-816-816.d, ld-tic6x/attr-stack-816.s, ld-tic6x/attr-wchar-0.s, ld-tic6x/attr-wchar-00.d, ld-tic6x/attr-wchar-01.d, ld-tic6x/attr-wchar-02.d, ld-tic6x/attr-wchar-1.s, ld-tic6x/attr-wchar-10.d, ld-tic6x/attr-wchar-11.d, ld-tic6x/attr-wchar-12.d, ld-tic6x/attr-wchar-2.s, ld-tic6x/attr-wchar-20.d, ld-tic6x/attr-wchar-21.d, ld-tic6x/attr-wchar-22.d: New tests.
Diffstat (limited to 'bfd/elf32-tic6x.c')
-rw-r--r--bfd/elf32-tic6x.c232
1 files changed, 225 insertions, 7 deletions
diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c
index 3e8564a..4e91d74 100644
--- a/bfd/elf32-tic6x.c
+++ b/bfd/elf32-tic6x.c
@@ -1663,11 +1663,22 @@ elf32_tic6x_obj_attrs_arg_type (int tag)
{
if (tag == Tag_ABI_compatibility)
return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
+ else if (tag & 1)
+ return ATTR_TYPE_FLAG_STR_VAL;
else
- /* Correct for known attributes, arbitrary for others. */
return ATTR_TYPE_FLAG_INT_VAL;
}
+static int
+elf32_tic6x_obj_attrs_order (int num)
+{
+ if (num == LEAST_KNOWN_OBJ_ATTRIBUTE)
+ return Tag_ABI_conformance;
+ if ((num - 1) < Tag_ABI_conformance)
+ return num - 1;
+ return num;
+}
+
/* Merge the Tag_ISA attribute values ARCH1 and ARCH2
and return the merged value. At present, all merges succeed, so no
return value for errors is defined. */
@@ -1691,14 +1702,64 @@ elf32_tic6x_merge_arch_attributes (int arch1, int arch2)
return max_arch;
}
+/* Convert a Tag_ABI_array_object_alignment or
+ Tag_ABI_array_object_align_expected tag value TAG to a
+ corresponding alignment value; return the alignment, or -1 for an
+ unknown tag value. */
+
+static int
+elf32_tic6x_tag_to_array_alignment (int tag)
+{
+ switch (tag)
+ {
+ case 0:
+ return 8;
+
+ case 1:
+ return 4;
+
+ case 2:
+ return 16;
+
+ default:
+ return -1;
+ }
+}
+
+/* Convert a Tag_ABI_array_object_alignment or
+ Tag_ABI_array_object_align_expected alignment ALIGN to a
+ corresponding tag value; return the tag value. */
+
+static int
+elf32_tic6x_array_alignment_to_tag (int align)
+{
+ switch (align)
+ {
+ case 8:
+ return 0;
+
+ case 4:
+ return 1;
+
+ case 16:
+ return 2;
+
+ default:
+ abort ();
+ }
+}
+
/* Merge attributes from IBFD and OBFD, returning TRUE if the merge
succeeded, FALSE otherwise. */
static bfd_boolean
elf32_tic6x_merge_attributes (bfd *ibfd, bfd *obfd)
{
+ bfd_boolean result = TRUE;
obj_attribute *in_attr;
obj_attribute *out_attr;
+ int i;
+ int array_align_in, array_align_out, array_expect_in, array_expect_out;
if (!elf_known_obj_attributes_proc (obfd)[0].i)
{
@@ -1719,21 +1780,177 @@ elf32_tic6x_merge_attributes (bfd *ibfd, bfd *obfd)
/* No specification yet for handling of unknown attributes, so just
ignore them and handle known ones. */
- out_attr[Tag_ISA].i
- = elf32_tic6x_merge_arch_attributes (in_attr[Tag_ISA].i,
- out_attr[Tag_ISA].i);
- if (out_attr[Tag_ABI_DSBT].i != in_attr[Tag_ABI_DSBT].i)
+ if (out_attr[Tag_ABI_stack_align_preserved].i
+ < in_attr[Tag_ABI_stack_align_needed].i)
+ {
+ _bfd_error_handler
+ (_("error: %B requires more stack alignment than %B preserves"),
+ ibfd, obfd);
+ result = FALSE;
+ }
+ if (in_attr[Tag_ABI_stack_align_preserved].i
+ < out_attr[Tag_ABI_stack_align_needed].i)
+ {
+ _bfd_error_handler
+ (_("error: %B requires more stack alignment than %B preserves"),
+ obfd, ibfd);
+ result = FALSE;
+ }
+
+ array_align_in = elf32_tic6x_tag_to_array_alignment
+ (in_attr[Tag_ABI_array_object_alignment].i);
+ if (array_align_in == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_alignment value in %B"),
+ ibfd);
+ result = FALSE;
+ }
+ array_align_out = elf32_tic6x_tag_to_array_alignment
+ (out_attr[Tag_ABI_array_object_alignment].i);
+ if (array_align_out == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_alignment value in %B"),
+ obfd);
+ result = FALSE;
+ }
+ array_expect_in = elf32_tic6x_tag_to_array_alignment
+ (in_attr[Tag_ABI_array_object_align_expected].i);
+ if (array_expect_in == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_align_expected value in %B"),
+ ibfd);
+ result = FALSE;
+ }
+ array_expect_out = elf32_tic6x_tag_to_array_alignment
+ (out_attr[Tag_ABI_array_object_align_expected].i);
+ if (array_expect_out == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_align_expected value in %B"),
+ obfd);
+ result = FALSE;
+ }
+
+ if (array_align_out < array_expect_in)
+ {
+ _bfd_error_handler
+ (_("error: %B requires more array alignment than %B preserves"),
+ ibfd, obfd);
+ result = FALSE;
+ }
+ if (array_align_in < array_expect_out)
{
_bfd_error_handler
- (_("warning: %B and %B differ in whether code is compiled for DSBT"),
+ (_("error: %B requires more array alignment than %B preserves"),
obfd, ibfd);
+ result = FALSE;
}
+
+ for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
+ {
+ switch (i)
+ {
+ case Tag_ISA:
+ out_attr[i].i = elf32_tic6x_merge_arch_attributes (in_attr[i].i,
+ out_attr[i].i);
+ break;
+
+ case Tag_ABI_wchar_t:
+ if (out_attr[i].i == 0)
+ out_attr[i].i = in_attr[i].i;
+ if (out_attr[i].i != 0
+ && in_attr[i].i != 0
+ && out_attr[i].i != in_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("warning: %B and %B differ in wchar_t size"), obfd, ibfd);
+ }
+ break;
+
+ case Tag_ABI_stack_align_needed:
+ if (out_attr[i].i < in_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_ABI_stack_align_preserved:
+ if (out_attr[i].i > in_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_ABI_DSBT:
+ if (out_attr[i].i != in_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("warning: %B and %B differ in whether code is "
+ "compiled for DSBT"),
+ obfd, ibfd);
+ }
+ break;
+
+ case Tag_ABI_PID:
+ if (out_attr[i].i != in_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("warning: %B and %B differ in position-dependence of "
+ "data addressing"),
+ obfd, ibfd);
+ }
+ break;
+
+ case Tag_ABI_PIC:
+ if (out_attr[i].i != in_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("warning: %B and %B differ in position-dependence of "
+ "code addressing"),
+ obfd, ibfd);
+ }
+ break;
+
+ case Tag_ABI_array_object_alignment:
+ if (array_align_out != -1
+ && array_align_in != -1
+ && array_align_out > array_align_in)
+ out_attr[i].i
+ = elf32_tic6x_array_alignment_to_tag (array_align_in);
+ break;
+
+ case Tag_ABI_array_object_align_expected:
+ if (array_expect_out != -1
+ && array_expect_in != -1
+ && array_expect_out < array_expect_in)
+ out_attr[i].i
+ = elf32_tic6x_array_alignment_to_tag (array_expect_in);
+ break;
+
+ case Tag_ABI_conformance:
+ /* Merging for this attribute is not specified. As on ARM,
+ treat a missing attribute as no claim to conform and only
+ merge identical values. */
+ if (out_attr[i].s == NULL
+ || in_attr[i].s == NULL
+ || strcmp (out_attr[i].s,
+ in_attr[i].s) != 0)
+ out_attr[i].s = NULL;
+ break;
+
+ default:
+ break;
+ }
+
+ if (in_attr[i].type && !out_attr[i].type)
+ out_attr[i].type = in_attr[i].type;
+ }
+
/* Merge Tag_ABI_compatibility attributes and any common GNU ones. */
if (!_bfd_elf_merge_object_attributes (ibfd, obfd))
return FALSE;
- return TRUE;
+ return result;
}
static bfd_boolean
@@ -1767,6 +1984,7 @@ elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
#define elf_backend_may_use_rel_p 1
#define elf_backend_may_use_rela_p 1
#define elf_backend_obj_attrs_arg_type elf32_tic6x_obj_attrs_arg_type
+#define elf_backend_obj_attrs_order elf32_tic6x_obj_attrs_order
#define elf_backend_obj_attrs_section ".c6xabi.attributes"
#define elf_backend_obj_attrs_section_type SHT_C6000_ATTRIBUTES
#define elf_backend_obj_attrs_vendor "c6xabi"