2009-01-12 Andrew Stubbs bfd/ * elf-attrs.c (vendor_set_obj_attr_contents): Support tag ordering. * elf-bfd.h (elf_backend_data): Add obj_attrs_order. * elf32-arm.c (elf32_arm_obj_attrs_order): New function. (elf_backend_obj_attrs_order): New define. * elfxx-target.h (elf_backend_obj_attrs_order): New define. (elfNN_bed): Add elf_backend_obj_attrs_order. gas/testsuite/ * gas/arm/attr-order.d: New file. * gas/arm/attr-order.s: New file. --- bfd/elf-attrs.c | 7 ++++++- bfd/elf-bfd.h | 6 ++++++ bfd/elf32-arm.c | 19 +++++++++++++++++++ bfd/elfxx-target.h | 4 ++++ gas/testsuite/gas/arm/attr-order.d | 15 +++++++++++++++ gas/testsuite/gas/arm/attr-order.s | 9 +++++++++ 6 files changed, 59 insertions(+), 1 deletion(-) Index: bfd/elf-attrs.c =================================================================== --- bfd/elf-attrs.c.orig +++ bfd/elf-attrs.c @@ -189,7 +189,12 @@ vendor_set_obj_attr_contents (bfd *abfd, attr = elf_known_obj_attributes (abfd)[vendor]; for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) - p = write_obj_attribute (p, i, &attr[i]); + { + int tag = i; + if (get_elf_backend_data (abfd)->obj_attrs_order) + tag = get_elf_backend_data (abfd)->obj_attrs_order (i); + p = write_obj_attribute (p, tag, &attr[tag]); + } for (list = elf_other_obj_attributes (abfd)[vendor]; list; Index: bfd/elf-bfd.h =================================================================== --- bfd/elf-bfd.h.orig +++ bfd/elf-bfd.h @@ -1166,6 +1166,12 @@ struct elf_backend_data /* The section type to use for an attributes section. */ unsigned int obj_attrs_section_type; + /* This function determines the order in which any attributes are written. + It must be defined for input in the range 4..NUM_KNOWN_OBJ_ATTRIBUTES-1 + (this range is used in order to make unity easy). The returned value is + the actual tag number to place in the input position. */ + int (*obj_attrs_order) (int); + /* This is TRUE if the linker should act like collect and gather global constructors and destructors by name. This is TRUE for MIPS ELF because the Irix 5 tools can not handle the .init Index: bfd/elf32-arm.c =================================================================== --- bfd/elf32-arm.c.orig +++ bfd/elf32-arm.c @@ -8145,6 +8145,24 @@ elf32_arm_obj_attrs_arg_type (int tag) return (tag & 1) != 0 ? 2 : 1; } +/* The ABI defines that Tag_conformance should be emitted first, and that + Tag_nodefaults should be second (if either is defined). This sets those + two positions, and bumps up the position of all the remaining tags to + compensate. */ +static int +elf32_arm_obj_attrs_order (int num) +{ + if (num == 4) + return Tag_conformance; + if (num == 5) + return Tag_nodefaults; + if ((num - 2) < Tag_nodefaults) + return num - 2; + if ((num - 1) < Tag_conformance) + return num - 1; + return num; +} + /* Read the architecture from the Tag_also_compatible_with attribute, if any. Returns -1 if no architecture could be read. */ @@ -12290,6 +12308,7 @@ const struct elf_size_info elf32_arm_siz #define elf_backend_obj_attrs_arg_type elf32_arm_obj_attrs_arg_type #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 #include "elf32-target.h" Index: bfd/elfxx-target.h =================================================================== --- bfd/elfxx-target.h.orig +++ bfd/elfxx-target.h @@ -461,6 +461,9 @@ #ifndef elf_backend_obj_attrs_section_type #define elf_backend_obj_attrs_section_type SHT_GNU_ATTRIBUTES #endif +#ifndef elf_backend_obj_attrs_order +#define elf_backend_obj_attrs_order NULL +#endif #ifndef elf_backend_post_process_headers #define elf_backend_post_process_headers NULL #endif @@ -720,6 +723,7 @@ static struct elf_backend_data elfNN_bed elf_backend_obj_attrs_section, elf_backend_obj_attrs_arg_type, elf_backend_obj_attrs_section_type, + elf_backend_obj_attrs_order, elf_backend_collect, elf_backend_type_change_ok, elf_backend_may_use_rel_p, Index: gas/testsuite/gas/arm/attr-order.d =================================================================== --- /dev/null +++ gas/testsuite/gas/arm/attr-order.d @@ -0,0 +1,15 @@ +# name: EABI attribute ordering +# source: attr-order.s +# as: +# readelf: -A + +Attribute Section: aeabi +File Attributes + Tag_conformance: "2.07" + Tag_nodefaults: True + Tag_CPU_name: "ARM7TDMI" + Tag_CPU_arch: v4T + Tag_unknown_63: "val" + Tag_also_compatible_with: v6-M + Tag_T2EE_use: Allowed + Tag_Virtualization_use: Allowed Index: gas/testsuite/gas/arm/attr-order.s =================================================================== --- /dev/null +++ gas/testsuite/gas/arm/attr-order.s @@ -0,0 +1,9 @@ +@ This test ensures that the following attributes +@ are emitted in the proper order. + .cpu arm7tdmi + .eabi_attribute 63, "val" + .eabi_attribute Tag_nodefaults, 0 + .eabi_attribute Tag_also_compatible_with, "\006\013" + .eabi_attribute Tag_T2EE_use, 1 + .eabi_attribute Tag_conformance, "2.07" + .eabi_attribute Tag_Virtualization_use, 1