From 34c8bcbae2e6ea0752c1ebe6e1282cc74a821957 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Sat, 30 Jun 2007 00:03:40 +0000 Subject: bfd: * elf32-ppc.c (ppc_elf_merge_obj_attributes): New. (ppc_elf_merge_private_bfd_data): Call it. binutils: * readelf.c (display_power_gnu_attribute, process_power_specific): New. (process_arch_specific): Call process_power_specific. include/elf: * ppc.h (Tag_GNU_Power_ABI_FP): Define. ld/testsuite: * ld-powerpc/attr-gnu-4-0.s, ld-powerpc/attr-gnu-4-00.d, ld-powerpc/attr-gnu-4-01.d, ld-powerpc/attr-gnu-4-02.d, ld-powerpc/attr-gnu-4-1.s, ld-powerpc/attr-gnu-4-10.d, ld-powerpc/attr-gnu-4-11.d, ld-powerpc/attr-gnu-4-12.d, ld-powerpc/attr-gnu-4-13.d, ld-powerpc/attr-gnu-4-2.s, ld-powerpc/attr-gnu-4-20.d, ld-powerpc/attr-gnu-4-21.d, ld-powerpc/attr-gnu-4-22.d, ld-powerpc/attr-gnu-4-3.s, ld-powerpc/attr-gnu-4-31.d: New. * ld-powerpc/powerpc.exp: Run these new tests. --- bfd/elf32-ppc.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'bfd/elf32-ppc.c') diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index b84f0af..d67ad86 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -3594,6 +3594,62 @@ ppc_elf_check_relocs (bfd *abfd, return TRUE; } + +/* Merge object attributes from IBFD into OBFD. Raise an error if + there are conflicting attributes. */ +static bfd_boolean +ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) +{ + obj_attribute *in_attr; + obj_attribute *out_attr; + + if (!elf_known_obj_attributes_proc (obfd)[0].i) + { + /* This is the first object. Copy the attributes. */ + _bfd_elf_copy_obj_attributes (ibfd, obfd); + + /* Use the Tag_null value to indicate the attributes have been + initialized. */ + elf_known_obj_attributes_proc (obfd)[0].i = 1; + + return TRUE; + } + + /* Check for conflicting Tag_GNU_Power_ABI_FP attributes and merge + non-conflicting ones. */ + in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU]; + out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU]; + if (in_attr[Tag_GNU_Power_ABI_FP].i != out_attr[Tag_GNU_Power_ABI_FP].i) + { + out_attr[Tag_GNU_Power_ABI_FP].type = 1; + if (out_attr[Tag_GNU_Power_ABI_FP].i == 0) + out_attr[Tag_GNU_Power_ABI_FP].i = in_attr[Tag_GNU_Power_ABI_FP].i; + else if (in_attr[Tag_GNU_Power_ABI_FP].i == 0) + ; + else if (out_attr[Tag_GNU_Power_ABI_FP].i == 1 + && in_attr[Tag_GNU_Power_ABI_FP].i == 2) + _bfd_error_handler + (_("Warning: %B uses hard float, %B uses soft float"), obfd, ibfd); + else if (out_attr[Tag_GNU_Power_ABI_FP].i == 2 + && in_attr[Tag_GNU_Power_ABI_FP].i == 1) + _bfd_error_handler + (_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd); + else if (in_attr[Tag_GNU_Power_ABI_FP].i > 2) + _bfd_error_handler + (_("Warning: %B uses unknown floating point ABI %d"), ibfd, + in_attr[Tag_GNU_Power_ABI_FP].i); + else + _bfd_error_handler + (_("Warning: %B uses unknown floating point ABI %d"), obfd, + out_attr[Tag_GNU_Power_ABI_FP].i); + } + + /* Merge Tag_compatibility attributes and any common GNU ones. */ + _bfd_elf_merge_object_attributes (ibfd, obfd); + + return TRUE; +} + /* Merge backend specific data from an object file to the output object file when linking. */ @@ -3612,6 +3668,9 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) if (! _bfd_generic_verify_endian_match (ibfd, obfd)) return FALSE; + if (!ppc_elf_merge_obj_attributes (ibfd, obfd)) + return FALSE; + new_flags = elf_elfheader (ibfd)->e_flags; old_flags = elf_elfheader (obfd)->e_flags; if (!elf_flags_init (obfd)) -- cgit v1.1