From: Julian Brown Date: Fri, 28 Jan 2005 17:24:41 +0000 (+0000) Subject: * bfd/bin-in.h (bfd_elf32_arm_set_target_relocs): Update prototype. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=319850b45155323419e8862ee9e1b20d12b3a62d;p=binutils-gdb.git * bfd/bin-in.h (bfd_elf32_arm_set_target_relocs): Update prototype. * bfd/bin-in2.h (bfd_elf32_arm_set_target_relocs): Update prototype. * bfd/elf32-arm.c (elf32_arm_link_hash_table): Add fix_v4bx flag. (bfd_elf32_arm_set_target_relocs): Add formal parameter fix_v4bx for passing flag value from ld. Set flag value in global hash table entry. (elf32_arm_final_link_relocate): Add code to implement R_ARM_V4BX relocation. * ld/emultempl/armelf.em (fix_v4bx): New variable. (arm_elf_create_output_section_statements): Communicate fix_v4bx flag value to bfd. (PARSE_AND_LIST_PROLOGUE): Add option token OPTION_FIX_V4BX. (PARSE_AND_LIST_LONGOPTS): Add option --fix-v4bx. (PARSE_AND_LIST_OPTIONS): Add option --fix-v4bx. (PARSE_AND_LIST_ARGS_CASES): Add option OPTION_FIX_V4BX. * ld/NEWS: Mention --fix-v4bx. * ld/ld.texinfo: Document --fix-v4bx. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a8f8a335eed..3b9a9b6bf99 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2005-01-28 Julian Brown + + * bin-in.h (bfd_elf32_arm_set_target_relocs): Update prototype. + * bin-in2.h (bfd_elf32_arm_set_target_relocs): Update prototype. + * elf32-arm.c (elf32_arm_link_hash_table): Add fix_v4bx flag. + (bfd_elf32_arm_set_target_relocs): Add formal parameter fix_v4bx for + passing flag value from ld. Set flag value in global hash table entry. + (elf32_arm_final_link_relocate): Add code to implement R_ARM_V4BX + relocation. + 2005-01-27 Andrew Cagney * configure: Regenerate to track ../gettext.m4 change. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index ff84516eebc..1ca14500826 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -817,7 +817,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation (bfd *, struct bfd_link_info *, int); void bfd_elf32_arm_set_target_relocs - (struct bfd_link_info *, int, char *); + (struct bfd_link_info *, int, char *, int); extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking (bfd *, struct bfd_link_info *); diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 6c783a0893c..da2d8cc2c10 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -824,7 +824,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation (bfd *, struct bfd_link_info *, int); void bfd_elf32_arm_set_target_relocs - (struct bfd_link_info *, int, char *); + (struct bfd_link_info *, int, char *, int); extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking (bfd *, struct bfd_link_info *); diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 09b47d3cdc8..14f46f4342d 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -1165,6 +1165,9 @@ struct elf32_arm_link_hash_table /* The relocation to use for R_ARM_TARGET2 relocations. */ int target2_reloc; + /* Nonzero to fix BX instructions for ARMv4 targets. */ + int fix_v4bx; + /* The number of bytes in the initial entry in the PLT. */ bfd_size_type plt_header_size; @@ -1931,7 +1934,8 @@ error_return: void bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info, int target1_is_rel, - char * target2_type) + char * target2_type, + int fix_v4bx) { struct elf32_arm_link_hash_table *globals; @@ -1949,6 +1953,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info, _bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."), target2_type); } + globals->fix_v4bx = fix_v4bx; } #endif @@ -2985,6 +2990,22 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, case R_ARM_RBASE: return bfd_reloc_notsupported; + case R_ARM_V4BX: + if (globals->fix_v4bx) + { + bfd_vma insn = bfd_get_32 (input_bfd, hit_data); + + /* Ensure that we have a BX instruction. */ + BFD_ASSERT ((insn & 0x0ffffff0) == 0x012fff10); + + /* Preserve Rm (lowest four bits) and the condition code + (highest four bits). Other bits encode MOV PC,Rm. */ + insn = (insn & 0xf000000f) | 0x01a0f000; + + bfd_put_32 (input_bfd, insn, hit_data); + } + return bfd_reloc_ok; + default: return bfd_reloc_notsupported; } diff --git a/ld/ChangeLog b/ld/ChangeLog index 2180c9dfcd5..0972c51259a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2005-01-28 Julian Brown + + * emultempl/armelf.em (fix_v4bx): New variable. + (arm_elf_create_output_section_statements): Communicate fix_v4bx flag + value to bfd. + (PARSE_AND_LIST_PROLOGUE): Add option token OPTION_FIX_V4BX. + (PARSE_AND_LIST_LONGOPTS): Add option --fix-v4bx. + (PARSE_AND_LIST_OPTIONS): Add option --fix-v4bx. + (PARSE_AND_LIST_ARGS_CASES): Add option OPTION_FIX_V4BX. + * NEWS: Mention --fix-v4bx. + * ld.texinfo: Document --fix-v4bx. + 2005-01-25 Mark Mitchell * emulparams/armsymbian.sh (OTHER_READONLY_SECTIONS): Define, so diff --git a/ld/NEWS b/ld/NEWS index e157fbf0ff0..c30b62c1b1a 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Support for the R_ARM_V4BX relocation as defined in the ARM AAELF + specification has been added via the --fix-v4bx command-line option. + * New linker script construct AS_NEEDED(), which sets the --as-needed flag for input files listed inside of it. diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index b292cd13fb5..01955f41123 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -30,6 +30,7 @@ static bfd *bfd_for_interwork; static int byteswap_code = 0; static int target1_is_rel = 0${TARGET1_IS_REL}; static char *target2_type = "${TARGET2_TYPE}"; +static int fix_v4bx = 0; static void gld${EMULATION_NAME}_before_parse (void) @@ -189,7 +190,8 @@ arm_elf_finish (void) static void arm_elf_create_output_section_statements (void) { - bfd_elf32_arm_set_target_relocs (&link_info, target1_is_rel, target2_type); + bfd_elf32_arm_set_target_relocs (&link_info, target1_is_rel, target2_type, + fix_v4bx); } EOF @@ -203,6 +205,7 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_TARGET1_REL 303 #define OPTION_TARGET1_ABS 304 #define OPTION_TARGET2 305 +#define OPTION_FIX_V4BX 306 ' PARSE_AND_LIST_SHORTOPTS=p @@ -214,6 +217,7 @@ PARSE_AND_LIST_LONGOPTS=' { "target1-rel", no_argument, NULL, OPTION_TARGET1_REL}, { "target1-abs", no_argument, NULL, OPTION_TARGET1_ABS}, { "target2", required_argument, NULL, OPTION_TARGET2}, + { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX}, ' PARSE_AND_LIST_OPTIONS=' @@ -222,6 +226,7 @@ PARSE_AND_LIST_OPTIONS=' fprintf (file, _(" --target1=rel Interpret R_ARM_TARGET1 as R_ARM_REL32\n")); fprintf (file, _(" --target1=abs Interpret R_ARM_TARGET1 as R_ARM_ABS32\n")); fprintf (file, _(" --target2= Specify definition of R_ARM_TARGET2\n")); + fprintf (file, _(" --fix-v4bx Rewrite BX rn as MOV pc, rn for ARMv4\n")); ' PARSE_AND_LIST_ARGS_CASES=' @@ -248,6 +253,10 @@ PARSE_AND_LIST_ARGS_CASES=' case OPTION_TARGET2: target2_type = optarg; break; + + case OPTION_FIX_V4BX: + fix_v4bx = 1; + break; ' # We have our own after_open and before_allocation functions, but they call diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 5452fe9193b..4511868081c 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -5139,6 +5139,20 @@ meanings, and target defaults are as follows: @samp{R_ARM_GOT_PREL} (arm*-*-linux, arm*-*-*bsd) @end table +@cindex FIX_V4BX +@kindex --fix-v4bx +The @samp{R_ARM_V4BX} relocation (defined by the ARM AAELF +specification) enables objects compiled for the ARMv4 architecture to be +interworking-safe when linked with other objects compiled for ARMv4t, but +also allows pure ARMv4 binaries to be built from the same ARMv4 objects. + +In the latter case, the switch @option{--fix-v4bx} must be passed to the +linker, which causes v4t @code{BX rM} instructions to be rewritten as +@code{MOV PC,rM}, since v4 processors do not have a @code{BX} instruction. + +In the former case, the switch should not be used, and @samp{R_ARM_V4BX} +relocations are ignored. + @ifclear GENERIC @lowersections @end ifclear