X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-arm.c;h=09c5aa44df85d819b02b90c5d03ab31ac2008a60;hb=32d0add0a654c1204ab71dc8a55d9374538c4b33;hp=996889d8b72452eb842f9962930b6aa05fc61e32;hpb=f1885d1e59a7e6e0627429cd3068740d96f8a184;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 996889d8b7..09c5aa44df 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -11700,6 +11700,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) static const int order_021[3] = {0, 2, 1}; int i; bfd_boolean result = TRUE; + const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section; /* Skip the linker stubs file. This preserves previous behavior of accepting unknown attributes in the first input file - but @@ -11707,6 +11708,12 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) if (ibfd->flags & BFD_LINKER_CREATED) return TRUE; + /* Skip any input that hasn't attribute section. + This enables to link object files without attribute section with + any others. */ + if (bfd_get_section_by_name (ibfd, sec_name) == NULL) + return TRUE; + if (!elf_known_obj_attributes_proc (obfd)[0].i) { /* This is the first object. Copy the attributes. */ @@ -11746,10 +11753,14 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) /* This needs to happen before Tag_ABI_FP_number_model is merged. */ if (in_attr[Tag_ABI_VFP_args].i != out_attr[Tag_ABI_VFP_args].i) { - /* Ignore mismatches if the object doesn't use floating point. */ - if (out_attr[Tag_ABI_FP_number_model].i == 0) + /* Ignore mismatches if the object doesn't use floating point or is + floating point ABI independent. */ + if (out_attr[Tag_ABI_FP_number_model].i == AEABI_FP_number_model_none + || (in_attr[Tag_ABI_FP_number_model].i != AEABI_FP_number_model_none + && out_attr[Tag_ABI_VFP_args].i == AEABI_VFP_args_compatible)) out_attr[Tag_ABI_VFP_args].i = in_attr[Tag_ABI_VFP_args].i; - else if (in_attr[Tag_ABI_FP_number_model].i != 0) + else if (in_attr[Tag_ABI_FP_number_model].i != AEABI_FP_number_model_none + && in_attr[Tag_ABI_VFP_args].i != AEABI_VFP_args_compatible) { _bfd_error_handler (_("error: %B uses VFP register arguments, %B does not"), @@ -11948,7 +11959,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) when it's 0. It might mean absence of FP hardware if Tag_FP_arch is zero, otherwise it is effectively SP + DP. */ -#define VFP_VERSION_COUNT 8 +#define VFP_VERSION_COUNT 9 static const struct { int ver; @@ -11962,7 +11973,8 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) {3, 16}, {4, 32}, {4, 16}, - {8, 32} + {8, 32}, + {8, 16} }; int ver; int regs; @@ -13331,7 +13343,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info, h->needs_copy = 1; } - return _bfd_elf_adjust_dynamic_copy (h, s); + return _bfd_elf_adjust_dynamic_copy (info, h, s); } /* Allocate space in .plt, .got and associated reloc sections for @@ -14711,7 +14723,7 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT && ((i_ehdrp->e_type == ET_DYN) || (i_ehdrp->e_type == ET_EXEC))) { int abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ABI_VFP_args); - if (abi) + if (abi == AEABI_VFP_args_vfp) i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_HARD; else i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_SOFT; @@ -15956,6 +15968,26 @@ const struct elf_size_info elf32_arm_size_info = bfd_elf32_swap_reloca_out }; +static bfd_vma +read_code32 (const bfd *abfd, const bfd_byte *addr) +{ + /* V7 BE8 code is always little endian. */ + if ((elf_elfheader (abfd)->e_flags & EF_ARM_BE8) != 0) + return bfd_getl32 (addr); + + return bfd_get_32 (abfd, addr); +} + +static bfd_vma +read_code16 (const bfd *abfd, const bfd_byte *addr) +{ + /* V7 BE8 code is always little endian. */ + if ((elf_elfheader (abfd)->e_flags & EF_ARM_BE8) != 0) + return bfd_getl16 (addr); + + return bfd_get_16 (abfd, addr); +} + /* Return size of plt0 entry starting at ADDR or (bfd_vma) -1 if size can not be determined. */ @@ -15965,7 +15997,7 @@ elf32_arm_plt0_size (const bfd *abfd, const bfd_byte *addr) bfd_vma first_word; bfd_vma plt0_size; - first_word = H_GET_32 (abfd, addr); + first_word = read_code32 (abfd, addr); if (first_word == elf32_arm_plt0_entry[0]) plt0_size = 4 * ARRAY_SIZE (elf32_arm_plt0_entry); @@ -15990,17 +16022,17 @@ elf32_arm_plt_size (const bfd *abfd, const bfd_byte *start, bfd_vma offset) const bfd_byte *addr = start + offset; /* PLT entry size if fixed on Thumb-only platforms. */ - if (H_GET_32(abfd, start) == elf32_thumb2_plt0_entry[0]) + if (read_code32 (abfd, start) == elf32_thumb2_plt0_entry[0]) return 4 * ARRAY_SIZE (elf32_thumb2_plt_entry); /* Respect Thumb stub if necessary. */ - if (H_GET_16(abfd, addr) == elf32_arm_plt_thumb_stub[0]) + if (read_code16 (abfd, addr) == elf32_arm_plt_thumb_stub[0]) { plt_size += 2 * ARRAY_SIZE(elf32_arm_plt_thumb_stub); } /* Strip immediate from first add. */ - first_insn = H_GET_32(abfd, addr + plt_size) & 0xffffff00; + first_insn = read_code32 (abfd, addr + plt_size) & 0xffffff00; #ifdef FOUR_WORD_PLT if (first_insn == elf32_arm_plt_entry[0])