From 39b41c9ca83ec4e504d90bd6e2137e67a27585e2 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Mon, 12 Dec 2005 17:03:40 +0000 Subject: [PATCH] 2005-12-12 Paul Brook bfd/ * bfd-in2.h: Regenerate. * elf32-arm.c (elf32_arm_reloc_map): Add BFD_RELOC_ARM_PCREL_CALL and BFD_RELOC_ARM_PCREL_JUMP. (check_use_blx): New function. (bfd_elf32_arm_process_before_allocation): Don't allocate glue if using BLX. (elf32_arm_final_link_relocate): Perform bl<->blx conversion for R_ARM_CALL and R_ARM_THM. (elf32_arm_get_eabi_attr_int): New function. (elf32_arm_size_dynamic_sections): Call check_use_blx. * libbfd.h: Regenerate. * reloc.c: Add BFD_RELOC_ARM_PCREL_CALL and BFD_RELOC_ARM_PCREL_JUMP. gas/ * config/tc-arm.c (do_branch): Generate EABI branch relocations. (do_bl): New function. (do_blx): Generate BFD_RELOC_ARM_PCREL_CALL relocation. (do_t_blx): Generate BFD_RELOC_THUMB_PCREL_BRANCH23. (insns): Use do_bl. (md_pcrel_from_section): Add BFD_RELOC_ARM_PCREL_CALL and BFD_RELOC_ARM_PCREL_JUMP. (md_apply_fix): Merge BFD_RELOC_ARM_PCREL_BRANCH and BFD_RELOC_ARM_PCREL_BLX cases. Handle BFD_RELOC_ARM_PCREL_CALL and BFD_RELOC_ARM_PCREL_JUMP. (tc_gen_reloc): Handle BFD_RELOC_ARM_PCREL_CALL and BFD_RELOC_ARM_PCREL_JUMP. gas/testsuite/ * gas/arm/pic.d: Allow R_ARM_CALL relocations. include/elf/ * arm.h (elf32_arm_get_eabi_attr_int): Add prototype. ld/testsuite/ * ld-arm/arm-call.d: New test. * ld-arm/arm-call1.s: New file. * ld-arm/arm-call1.s: New file. * ld-arm/arm-elf.exp: Add arm-call and mixed-app-v5. * ld-arm/arm.ld: Add .glue_7 and .ARM.attribues. * ld-arm/mixed-app-v5.d: New file. * ld-arm/mixed-app.r: Tweak expected output. --- bfd/ChangeLog | 15 ++++++ bfd/bfd-in2.h | 6 +++ bfd/elf32-arm.c | 97 +++++++++++++++++++++++++++++--------- bfd/libbfd.h | 2 + bfd/reloc.c | 8 ++++ gas/ChangeLog | 17 +++++++ gas/config/tc-arm.c | 90 ++++++++++++++++++++++------------- gas/testsuite/gas/arm/pic.d | 2 +- include/elf/ChangeLog | 4 ++ include/elf/arm.h | 1 + ld/testsuite/ChangeLog | 10 ++++ ld/testsuite/ld-arm/arm-call.d | 58 +++++++++++++++++++++++ ld/testsuite/ld-arm/arm-call1.s | 30 ++++++++++++ ld/testsuite/ld-arm/arm-call2.s | 24 ++++++++++ ld/testsuite/ld-arm/arm-elf.exp | 8 ++++ ld/testsuite/ld-arm/arm.ld | 2 + ld/testsuite/ld-arm/mixed-app-v5.d | 56 ++++++++++++++++++++++ ld/testsuite/ld-arm/mixed-app.r | 2 +- 18 files changed, 377 insertions(+), 55 deletions(-) create mode 100644 ld/testsuite/ld-arm/arm-call.d create mode 100644 ld/testsuite/ld-arm/arm-call1.s create mode 100644 ld/testsuite/ld-arm/arm-call2.s create mode 100644 ld/testsuite/ld-arm/mixed-app-v5.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 528ab5f..cf86df4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2005-12-12 Paul Brook + + * bfd-in2.h: Regenerate. + * elf32-arm.c (elf32_arm_reloc_map): Add BFD_RELOC_ARM_PCREL_CALL and + BFD_RELOC_ARM_PCREL_JUMP. + (check_use_blx): New function. + (bfd_elf32_arm_process_before_allocation): Don't allocate glue if + using BLX. + (elf32_arm_final_link_relocate): Perform bl<->blx conversion for + R_ARM_CALL and R_ARM_THM. + (elf32_arm_get_eabi_attr_int): New function. + (elf32_arm_size_dynamic_sections): Call check_use_blx. + * libbfd.h: Regenerate. + * reloc.c: Add BFD_RELOC_ARM_PCREL_CALL and BFD_RELOC_ARM_PCREL_JUMP. + 2005-12-12 Nathan Sidwell * Makefile.am (ALL_MACHINES, ALL_MACHINES_CFILES, diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 39c15bd..ed78323 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2827,6 +2827,12 @@ not stored in the instruction. The 2nd lowest bit comes from a 1 bit field in the instruction. */ BFD_RELOC_THUMB_PCREL_BLX, +/* ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction. */ + BFD_RELOC_ARM_PCREL_CALL, + +/* ARM 26-bit pc-relative branch for B or conditional BL instruction. */ + BFD_RELOC_ARM_PCREL_JUMP, + /* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. The lowest bit must be zero and is not stored in the instruction. Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 6f220e9..d9648af 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -1297,6 +1297,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = { {BFD_RELOC_NONE, R_ARM_NONE}, {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24}, + {BFD_RELOC_ARM_PCREL_CALL, R_ARM_CALL}, + {BFD_RELOC_ARM_PCREL_JUMP, R_ARM_JUMP24}, {BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25}, {BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22}, {BFD_RELOC_32, R_ARM_ABS32}, @@ -2285,6 +2287,12 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info) return TRUE; } +static void check_use_blx(struct elf32_arm_link_hash_table *globals) +{ + if (elf32_arm_get_eabi_attr_int (globals->obfd, Tag_CPU_arch) > 2) + globals->use_blx = 1; +} + bfd_boolean bfd_elf32_arm_process_before_allocation (bfd *abfd, struct bfd_link_info *link_info, @@ -2306,6 +2314,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd, /* Here we have a bfd that is to be included on the link. We have a hook to do reloc rummaging, before section sizes are nailed down. */ globals = elf32_arm_hash_table (link_info); + check_use_blx (globals); BFD_ASSERT (globals != NULL); BFD_ASSERT (globals->bfd_of_glue_owner != NULL); @@ -2403,7 +2412,8 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd, /* This one is a call from arm code. We need to look up the target of the call. If it is a thumb target, we insert glue. */ - if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC) + if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC + && !(r_type == R_ARM_CALL && globals->use_blx)) record_arm_to_thumb_glue (link_info, h); break; @@ -2411,7 +2421,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd, /* This one is a call from thumb code. We look up the target of the call. If it is not a thumb target, we insert glue. */ - if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC) + if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC && !globals->use_blx) record_thumb_to_arm_glue (link_info, h); break; @@ -3045,7 +3055,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, input_bfd, h ? h->root.root.string : "(local)"); } - else + else if (r_type != R_ARM_CALL || !globals->use_blx) { /* Check for Arm calling Thumb function. */ if (sym_flags == STT_ARM_TFUNC) @@ -3101,14 +3111,30 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, return bfd_reloc_overflow; } - /* If necessary set the H bit in the BLX instruction. */ - if (r_type == R_ARM_XPC25 && ((value & 2) == 2)) - value = (signed_addend & howto->dst_mask) - | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask)) - | (1 << 24); - else - value = (signed_addend & howto->dst_mask) - | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask)); + addend = (value & 2); + + value = (signed_addend & howto->dst_mask) + | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask)); + + /* Set the H bit in the BLX instruction. */ + if (sym_flags == STT_ARM_TFUNC) + { + if (addend) + value |= (1 << 24); + else + value &= ~(bfd_vma)(1 << 24); + } + if (r_type == R_ARM_CALL) + { + /* Select the correct instruction (BL or BLX). */ + if (sym_flags == STT_ARM_TFUNC) + value |= (1 << 28); + else + { + value &= ~(bfd_vma)(1 << 28); + value |= (1 << 24); + } + } break; case R_ARM_ABS32: @@ -3204,7 +3230,6 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, bfd_signed_vma reloc_signed_min = ~ reloc_signed_max; bfd_vma check; bfd_signed_vma signed_check; - bfd_boolean thumb_plt_call = FALSE; /* Need to refetch the addend and squish the two 11 bit pieces together. */ @@ -3238,13 +3263,23 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, && (h == NULL || splt == NULL || h->plt.offset == (bfd_vma) -1)) { - if (elf32_thumb_to_arm_stub + if (globals->use_blx) + { + /* Convert BL to BLX. */ + lower_insn = (lower_insn & ~0x1000) | 0x0800; + } + else if (elf32_thumb_to_arm_stub (info, sym_name, input_bfd, output_bfd, input_section, hit_data, sym_sec, rel->r_offset, signed_addend, value)) return bfd_reloc_ok; else return bfd_reloc_dangerous; } + else if (sym_flags == STT_ARM_TFUNC && globals->use_blx) + { + /* Make sure this is a BL. */ + lower_insn |= 0x1800; + } } /* Handle calls via the PLT. */ @@ -3257,11 +3292,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, { /* If the Thumb BLX instruction is available, convert the BL to a BLX instruction to call the ARM-mode PLT entry. */ - if ((lower_insn & (0x3 << 11)) == 0x3 << 11) - { - lower_insn = (lower_insn & ~(0x3 << 11)) | 0x1 << 11; - thumb_plt_call = TRUE; - } + lower_insn = (lower_insn & ~0x1000) | 0x0800; } else /* Target the Thumb stub before the ARM PLT entry. */ @@ -3288,9 +3319,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, if (signed_check > reloc_signed_max || signed_check < reloc_signed_min) overflow = TRUE; - if ((r_type == R_ARM_THM_XPC22 - && ((lower_insn & 0x1800) == 0x0800)) - || thumb_plt_call) + if ((lower_insn & 0x1800) == 0x0800) /* For a BLX instruction, make sure that the relocation is rounded up to a word boundary. This follows the semantics of the instruction which specifies that bit 1 of the target address will come from bit @@ -4474,6 +4503,31 @@ elf32_arm_new_eabi_attr (bfd *abfd, int tag) return attr; } +int +elf32_arm_get_eabi_attr_int (bfd *abfd, int tag) +{ + aeabi_attribute_list *p; + + if (tag < NUM_KNOWN_ATTRIBUTES) + { + /* Knwon tags are preallocated. */ + return elf32_arm_tdata (abfd)->known_eabi_attributes[tag].i; + } + else + { + for (p = elf32_arm_tdata (abfd)->other_eabi_attributes; + p; + p = p->next) + { + if (tag == p->tag) + return p->attr.i; + if (tag < p->tag) + break; + } + return 0; + } +} + void elf32_arm_add_eabi_attr_int (bfd *abfd, int tag, unsigned int i) { @@ -6381,6 +6435,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, htab = elf32_arm_hash_table (info); dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); + check_use_blx (htab); if (elf_hash_table (info)->dynamic_sections_created) { diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 8b01aaa..b3d9403 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1170,6 +1170,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_PCREL_BRANCH", "BFD_RELOC_ARM_PCREL_BLX", "BFD_RELOC_THUMB_PCREL_BLX", + "BFD_RELOC_ARM_PCREL_CALL", + "BFD_RELOC_ARM_PCREL_JUMP", "BFD_RELOC_THUMB_PCREL_BRANCH7", "BFD_RELOC_THUMB_PCREL_BRANCH9", "BFD_RELOC_THUMB_PCREL_BRANCH12", diff --git a/bfd/reloc.c b/bfd/reloc.c index d5277c0..3e43d6c 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2610,6 +2610,14 @@ ENUMDOC Thumb 22 bit pc-relative branch. The lowest bit must be zero and is not stored in the instruction. The 2nd lowest bit comes from a 1 bit field in the instruction. +ENUM + BFD_RELOC_ARM_PCREL_CALL +ENUMDOC + ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction. +ENUM + BFD_RELOC_ARM_PCREL_JUMP +ENUMDOC + ARM 26-bit pc-relative branch for B or conditional BL instruction. ENUM BFD_RELOC_THUMB_PCREL_BRANCH7 diff --git a/gas/ChangeLog b/gas/ChangeLog index 00d5415..6f310ea 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,20 @@ +2005-12-12 Paul Brook + + * config/tc-arm.c (do_branch): Generate EABI branch relocations. + (do_bl): New function. + (do_blx): Generate BFD_RELOC_ARM_PCREL_CALL relocation. + (do_t_blx): Generate BFD_RELOC_THUMB_PCREL_BRANCH23. + (insns): Use do_bl. + (md_pcrel_from_section): Add BFD_RELOC_ARM_PCREL_CALL and + BFD_RELOC_ARM_PCREL_JUMP. + (md_apply_fix): Merge BFD_RELOC_ARM_PCREL_BRANCH and + BFD_RELOC_ARM_PCREL_BLX cases. Handle BFD_RELOC_ARM_PCREL_CALL and + BFD_RELOC_ARM_PCREL_JUMP. + (tc_gen_reloc): Handle BFD_RELOC_ARM_PCREL_CALL and + BFD_RELOC_ARM_PCREL_JUMP. + gas/testsuite/ + * gas/arm/pic.d: Allow R_ARM_CALL relocations. + 2005-12-12 Nathan Sidwell * configure.in: Replace ms1 arch with mt arch. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 9f8e0e9..a2baa32 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -4610,7 +4610,28 @@ encode_branch (int default_reloc) static void do_branch (void) { - encode_branch (BFD_RELOC_ARM_PCREL_BRANCH); +#ifdef OBJ_ELF + if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4) + encode_branch (BFD_RELOC_ARM_PCREL_JUMP); + else +#endif + encode_branch (BFD_RELOC_ARM_PCREL_BRANCH); +} + +static void +do_bl (void) +{ +#ifdef OBJ_ELF + if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4) + { + if (inst.cond == COND_ALWAYS) + encode_branch (BFD_RELOC_ARM_PCREL_CALL); + else + encode_branch (BFD_RELOC_ARM_PCREL_JUMP); + } + else +#endif + encode_branch (BFD_RELOC_ARM_PCREL_BRANCH); } /* ARM V5 branch-link-exchange instruction (argument parse) @@ -4639,7 +4660,12 @@ do_blx (void) conditionally, and the opcode must be adjusted. */ constraint (inst.cond != COND_ALWAYS, BAD_COND); inst.instruction = 0xfa000000; - encode_branch (BFD_RELOC_ARM_PCREL_BLX); +#ifdef OBJ_ELF + if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4) + encode_branch (BFD_RELOC_ARM_PCREL_CALL); + else +#endif + encode_branch (BFD_RELOC_ARM_PCREL_BLX); } } @@ -6434,7 +6460,12 @@ do_t_blx (void) { /* No register. This must be BLX(1). */ inst.instruction = 0xf000e800; - inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX; +#ifdef OBJ_ELF + if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4) + inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23; + else +#endif + inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX; inst.reloc.pc_rel = 1; } } @@ -8689,7 +8720,7 @@ static const struct asm_opcode insns[] = TCE(swi, f000000, df00, 1, (EXPi), swi, t_swi), tCE(b, a000000, b, 1, (EXPr), branch, t_branch), - TCE(bl, b000000, f000f800, 1, (EXPr), branch, t_branch23), + TCE(bl, b000000, f000f800, 1, (EXPr), bl, t_branch23), /* Pseudo ops. */ tCE(adr, 28f0000, adr, 2, (RR, EXP), adr, t_adr), @@ -10849,6 +10880,8 @@ md_pcrel_from_section (fixS * fixP, segT seg) /* ARM mode branches are offset by +8. However, the Windows CE loader expects the relocation not to take this into account. */ case BFD_RELOC_ARM_PCREL_BRANCH: + case BFD_RELOC_ARM_PCREL_CALL: + case BFD_RELOC_ARM_PCREL_JUMP: case BFD_RELOC_ARM_PCREL_BLX: case BFD_RELOC_ARM_PLT32: #ifdef TE_WINCE @@ -11457,15 +11490,30 @@ md_apply_fix (fixS * fixP, md_number_to_chars (buf, newval, INSN_SIZE); break; - case BFD_RELOC_ARM_PCREL_BRANCH: #ifdef OBJ_ELF + case BFD_RELOC_ARM_PCREL_CALL: + newval = md_chars_to_number (buf, INSN_SIZE); + if ((newval & 0xf0000000) == 0xf0000000) + temp = 1; + else + temp = 3; + goto arm_branch_common; + + case BFD_RELOC_ARM_PCREL_JUMP: case BFD_RELOC_ARM_PLT32: #endif + case BFD_RELOC_ARM_PCREL_BRANCH: + temp = 3; + goto arm_branch_common; + case BFD_RELOC_ARM_PCREL_BLX: + temp = 1; + arm_branch_common: /* We are going to store value (shifted right by two) in the - instruction, in a 24 bit, signed field. Bits 0 and 1 must be - clear, and bits 26 through 32 either all clear or all set. */ - if (value & 0x00000003) + instruction, in a 24 bit, signed field. Bits 26 through 32 either + all clear or all set and bit 0 must be clear. For B/BL bit 1 must + also be be clear. */ + if (value & temp) as_bad_where (fixP->fx_file, fixP->fx_line, _("misaligned branch destination")); if ((value & (offsetT)0xfe000000) != (offsetT)0 @@ -11481,30 +11529,6 @@ md_apply_fix (fixS * fixP, } break; - case BFD_RELOC_ARM_PCREL_BLX: - /* BLX allows bit 1 to be set in the branch destination, since - it targets a Thumb instruction which is only required to be - aligned modulo 2. Other constraints are as for B/BL. */ - if (value & 0x00000001) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("misaligned BLX destination")); - if ((value & (offsetT)0xfe000000) != (offsetT)0 - && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("branch out of range")); - - if (fixP->fx_done || !seg->use_rela_p) - { - offsetT hbit; - hbit = (value >> 1) & 1; - value = (value >> 2) & 0x00ffffff; - - newval = md_chars_to_number (buf, INSN_SIZE); - newval |= value | hbit << 24; - md_number_to_chars (buf, newval, INSN_SIZE); - } - break; - case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CZB */ /* CZB can only branch forward. */ if (value & ~0x7e) @@ -11969,6 +11993,8 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, case BFD_RELOC_ARM_TARGET2: case BFD_RELOC_ARM_TLS_LE32: case BFD_RELOC_ARM_TLS_LDO32: + case BFD_RELOC_ARM_PCREL_CALL: + case BFD_RELOC_ARM_PCREL_JUMP: code = fixp->fx_r_type; break; diff --git a/gas/testsuite/gas/arm/pic.d b/gas/testsuite/gas/arm/pic.d index 133614c..8eed71d 100644 --- a/gas/testsuite/gas/arm/pic.d +++ b/gas/testsuite/gas/arm/pic.d @@ -9,7 +9,7 @@ Disassembly of section .text: 00+0 <[^>]*> eb...... bl 00+. <[^>]*> - 0: R_ARM_PC24 foo.* + 0: R_ARM_(PC24|CALL) foo.* 00+4 <[^>]*> eb...... bl 0[0123456789abcdef]+ <[^>]*> 4: R_ARM_PLT32 foo \.\.\. diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index af4947c..a62cb1f 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,7 @@ +2005-12-12 Paul Brook + + * arm.h (elf32_arm_get_eabi_attr_int): Add prototype. + 2005-11-11 Nick Clifton PR 1150 diff --git a/include/elf/arm.h b/include/elf/arm.h index 2d76ab6..9ad0420 100644 --- a/include/elf/arm.h +++ b/include/elf/arm.h @@ -228,6 +228,7 @@ END_RELOC_NUMBERS (R_ARM_max) void elf32_arm_add_eabi_attr_int (bfd *, int, unsigned int); void elf32_arm_add_eabi_attr_string (bfd *, int, const char *); void elf32_arm_add_eabi_attr_compat (bfd *, unsigned int, const char *); +int elf32_arm_get_eabi_attr_int (bfd *, int); void elf32_arm_set_eabi_attr_contents (bfd *, bfd_byte *, bfd_vma); bfd_vma elf32_arm_eabi_attr_size (bfd *); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 3187cfe..a85aa42 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2005-12-12 Paul Brook + + * ld-arm/arm-call.d: New test. + * ld-arm/arm-call1.s: New file. + * ld-arm/arm-call1.s: New file. + * ld-arm/arm-elf.exp: Add arm-call and mixed-app-v5. + * ld-arm/arm.ld: Add .glue_7 and .ARM.attribues. + * ld-arm/mixed-app-v5.d: New file. + * ld-arm/mixed-app.r: Tweak expected output. + 2005-11-18 Alan Modra * ld-powerpc/symtocbase.d: Adjust for alignment change. diff --git a/ld/testsuite/ld-arm/arm-call.d b/ld/testsuite/ld-arm/arm-call.d new file mode 100644 index 0000000..fd4cd13 --- /dev/null +++ b/ld/testsuite/ld-arm/arm-call.d @@ -0,0 +1,58 @@ + +.*: file format.* + +Disassembly of section .text: + +00008000 <_start>: + 8000: eb00000d bl 803c + 8004: fa00000d blx 8040 + 8008: fb00000c blx 8042 + 800c: fb00000d blx 804a + 8010: fa00000a blx 8040 + 8014: fb000009 blx 8042 + 8018: ea00000f b 805c <__t1_from_arm> + 801c: ea000011 b 8068 <__t2_from_arm> + 8020: 1b00000d blne 805c <__t1_from_arm> + 8024: 1b00000f blne 8068 <__t2_from_arm> + 8028: 1b000003 blne 803c + 802c: eb000002 bl 803c + 8030: faffffff blx 8034 + +00008034 : + 8034: 4770 bx lr + +00008036 : + 8036: 4770 bx lr + +00008038 : + 8038: 4770 bx lr + 803a: 46c0 nop \(mov r8, r8\) + +0000803c : + 803c: e12fff1e bx lr + +00008040 : + 8040: 4770 bx lr + +00008042 : + 8042: f7ff fff8 bl 8036 + 8046: f7ff fff7 bl 8038 + +0000804a : + 804a: f000 f801 bl 8050 + 804e: 46c0 nop \(mov r8, r8\) + +00008050 : + 8050: f7ff fff1 bl 8036 + 8054: f7ff efd4 blx 8000 <_start> + 8058: f7ff efd2 blx 8000 <_start> + +0000805c <__t1_from_arm>: + 805c: e59fc000 ldr ip, \[pc, #0\] ; 8064 <__t1_from_arm\+0x8> + 8060: e12fff1c bx ip + 8064: 00008041 andeq r8, r0, r1, asr #32 + +00008068 <__t2_from_arm>: + 8068: e59fc000 ldr ip, \[pc, #0\] ; 8070 <__t2_from_arm\+0x8> + 806c: e12fff1c bx ip + 8070: 00008043 andeq r8, r0, r3, asr #32 diff --git a/ld/testsuite/ld-arm/arm-call1.s b/ld/testsuite/ld-arm/arm-call1.s new file mode 100644 index 0000000..e6ea1f2 --- /dev/null +++ b/ld/testsuite/ld-arm/arm-call1.s @@ -0,0 +1,30 @@ +# Test R_ARM_CALL and R_ARM_JUMP24 relocations and interworking + .text + .arch armv5t + .global _start +_start: + bl arm + bl t1 + bl t2 + bl t5 + blx t1 + blx t2 + b t1 + b t2 + blne t1 + blne t2 + blne arm + blx arm + blx thumblocal + .thumb +thumblocal: + bx lr + .global t3 + .thumb_func +t3: + bx lr + .global t4 + .thumb_func +t4: + bx lr + nop diff --git a/ld/testsuite/ld-arm/arm-call2.s b/ld/testsuite/ld-arm/arm-call2.s new file mode 100644 index 0000000..30ae349 --- /dev/null +++ b/ld/testsuite/ld-arm/arm-call2.s @@ -0,0 +1,24 @@ + .text + .arch armv5t + .global arm + .global t1 + .global t2 + .global t5 +arm: + bx lr + .thumb + .thumb_func +t1: + bx lr + .thumb_func +t2: + bl t3 + bl t4 + .thumb_func +t5: + bl local_thumb + nop +local_thumb: + blx t3 + bl _start + blx _start diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 7404adf..384b289 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -57,6 +57,11 @@ set armelftests { {{objdump -fdw mixed-app.d} {objdump -Rw mixed-app.r} {readelf -Ds mixed-app.sym}} "mixed-app"} + {"Mixed ARM/Thumb arch5 dynamic application" "tmpdir/mixed-lib.so -T arm-dyn.ld --use-blx" "" + {mixed-app.s} + {{objdump -fdw mixed-app-v5.d} {objdump -Rw mixed-app.r} + {readelf -Ds mixed-app.sym}} + "mixed-app-v5"} {"target1-abs" "-static --target1-abs -T arm.ld" "" {arm-target1.s} {{objdump -s arm-target1-abs.d}} "arm-target1-abs"} @@ -75,6 +80,9 @@ set armelftests { {"arm-rel31" "-static -T arm.ld" "" {arm-rel31.s} {{objdump -s arm-rel31.d}} "arm-rel31"} + {"arm-call" "-static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s} + {{objdump -d arm-call.d}} + "arm-call"} {"TLS shared library" "-shared -T arm-lib.ld" "" {tls-lib.s} {{objdump -fdw tls-lib.d} {objdump -Rw tls-lib.r}} "tls-lib.so"} diff --git a/ld/testsuite/ld-arm/arm.ld b/ld/testsuite/ld-arm/arm.ld index 23d914b..4ef7d82 100644 --- a/ld/testsuite/ld-arm/arm.ld +++ b/ld/testsuite/ld-arm/arm.ld @@ -10,7 +10,9 @@ SECTIONS *(.before) *(.text) *(.after) + *(.glue_7) } =0 . = 0x9000; .got : { *(.got) *(.got.plt)} + .ARM.attribues 0 : { *(.ARM.atttributes) } } diff --git a/ld/testsuite/ld-arm/mixed-app-v5.d b/ld/testsuite/ld-arm/mixed-app-v5.d new file mode 100644 index 0000000..9e8d4dd --- /dev/null +++ b/ld/testsuite/ld-arm/mixed-app-v5.d @@ -0,0 +1,56 @@ + +tmpdir/mixed-app-v5: file format elf32-(little|big)arm +architecture: arm, flags 0x00000112: +EXEC_P, HAS_SYMS, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 str lr, \[sp, #-4\]! + .*: e59fe004 ldr lr, \[pc, #4\] ; .* <_start-0x20> + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! + .*: e28fc6.* add ip, pc, #.* ; 0x.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! +Disassembly of section .text: + +.* <_start>: + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: eb000004 bl .* + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* : + .*: e1a0c00d mov ip, sp + .*: e92dd800 stmdb sp!, {fp, ip, lr, pc} + .*: ebfffff. bl .* + .*: e89d6800 ldmia sp, {fp, sp, lr} + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* : + .*: e12fff1e bx lr + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + .*: e1a00000 nop \(mov r0,r0\) + +.* : + .*: b500 push {lr} + .*: f7ff efc. blx .* <_start-0x..> + .*: bd00 pop {pc} + .*: 4770 bx lr + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) + .*: 46c0 nop \(mov r8, r8\) diff --git a/ld/testsuite/ld-arm/mixed-app.r b/ld/testsuite/ld-arm/mixed-app.r index 601c5f9..648e92f 100644 --- a/ld/testsuite/ld-arm/mixed-app.r +++ b/ld/testsuite/ld-arm/mixed-app.r @@ -1,5 +1,5 @@ -tmpdir/mixed-app: file format elf32-(little|big)arm +tmpdir/mixed-app.*: file format elf32-(little|big)arm DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE -- 2.7.4