diff options
author | Joern Rennecke <joern.rennecke@embecosm.com> | 2003-03-03 21:04:01 +0000 |
---|---|---|
committer | Joern Rennecke <joern.rennecke@embecosm.com> | 2003-03-03 21:04:01 +0000 |
commit | bdfaef528f42e9c07279aab2f37e3b888a08fc22 (patch) | |
tree | 7d39668f5661d2f58be6c5a8aa5d7e9cb93dc85b /gas/config/tc-sh.c | |
parent | a0ed55327d141094e07c8cdb3ac6f877109d917c (diff) | |
download | gdb-bdfaef528f42e9c07279aab2f37e3b888a08fc22.zip gdb-bdfaef528f42e9c07279aab2f37e3b888a08fc22.tar.gz gdb-bdfaef528f42e9c07279aab2f37e3b888a08fc22.tar.bz2 |
Fix sh-elf linker relaxation:
gcc:
* config/sh/sh.h (EXTRA_SPECS): Add subtarget_asm_relax_spec and
subtarget_asm_isa_spec.
(SUBTARGET_ASM_RELAX_SPEC, SUBTARGET_ASM_ISA_SPEC): Define.
(ASM_SPEC): Define as SH_ASM_SPEC.
(SH_ASM_SPEC): New; take the role of ASM_SPEC, but safe from svr4.h.
Use subtarget_asm_relax_spec and subtarget_asm_isa_spec.
* config/sh/elf.h (ASM_SPEC): Use SH_ASM_SPEC.
(SUBTARGET_ASM_ISA_SPEC): Undef / define.
gcc/testsuite:
gcc.dg/sh-relax.c: New test.
include/elf:
* sh.h (EF_SH_MERGE_MACH): Make sure SH2E & SH3/SH3E merge to SH3E,
and SH2E & SH4 merge to SH4, not SH2E.
gas:
* config/tc-sh.c (sh_dsp): Replace with preset_target_arch.
(md_begin): Use preset_target_arch.
(md_longopts): Make isa option unconditional.
(md_parse_option): Make OPTION_DSP and OPTION_ISA sh4 / any
set preset_target_arch.
(md_apply_fix3): If BFD_ASSEMBLER, adjust SWITCH_TABLE fixups
by -S_GET_VALUE (fixP->fx_subsy).
(tc_gen_reloc): For SWITCH_TABLE fixups, the symbol is fixp->fx_subsy,
and the addend is 0.
Adjust addend of R_SH_IND12W relocations by fixp->fx_offset - 4.
* config/tc-sh.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define.
bfd:
elf32-sh.c (sh_elf_howto_tab): Make R_SH_IND12W into an ordinary
relocation (no special function), and make it non-partial_inplace.
(sh_elf_relax_section): When creating a bsr, use a consistent value
no matter if the symbol is extern or not; set addend to -4.
Don't swap load / non-load instructions for SH4.
(sh_elf_relax_delete_bytes): In R_SH_IND12W case, check the offset
rather than if the symbol is external to determine if adjusting the
offset makes sense. Adjust the addend too if appropriate.
(sh_elf_relocate_section): In R_SH_IND12W, don't fiddle with the
relocation.
Diffstat (limited to 'gas/config/tc-sh.c')
-rw-r--r-- | gas/config/tc-sh.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index d3a6ac3..c73b81f 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -163,9 +163,9 @@ int sh_relax; /* set if -relax seen */ int sh_small; -/* Whether -dsp was seen. */ +/* preset architecture set, if given; zero otherwise. */ -static int sh_dsp; +static int preset_target_arch; /* The bit mask of architectures that could accomodate the insns seen so far. */ @@ -867,7 +867,8 @@ md_begin () char *prev_name = ""; int target_arch; - target_arch = arch_sh1_up & ~(sh_dsp ? arch_sh3e_up : arch_sh_dsp_up); + target_arch + = preset_target_arch ? preset_target_arch : arch_sh1_up & ~arch_sh_dsp_up; valid_arch = target_arch; #ifdef HAVE_SH64 @@ -2593,20 +2594,20 @@ struct option md_longopts[] = #define OPTION_LITTLE (OPTION_BIG + 1) #define OPTION_SMALL (OPTION_LITTLE + 1) #define OPTION_DSP (OPTION_SMALL + 1) +#define OPTION_ISA (OPTION_DSP + 1) {"relax", no_argument, NULL, OPTION_RELAX}, {"big", no_argument, NULL, OPTION_BIG}, {"little", no_argument, NULL, OPTION_LITTLE}, {"small", no_argument, NULL, OPTION_SMALL}, {"dsp", no_argument, NULL, OPTION_DSP}, + {"isa", required_argument, NULL, OPTION_ISA}, #ifdef HAVE_SH64 -#define OPTION_ISA (OPTION_DSP + 1) #define OPTION_ABI (OPTION_ISA + 1) #define OPTION_NO_MIX (OPTION_ABI + 1) #define OPTION_SHCOMPACT_CONST_CRANGE (OPTION_NO_MIX + 1) #define OPTION_NO_EXPAND (OPTION_SHCOMPACT_CONST_CRANGE + 1) #define OPTION_PT32 (OPTION_NO_EXPAND + 1) - {"isa", required_argument, NULL, OPTION_ISA}, {"abi", required_argument, NULL, OPTION_ABI}, {"no-mix", no_argument, NULL, OPTION_NO_MIX}, {"shcompact-const-crange", no_argument, NULL, OPTION_SHCOMPACT_CONST_CRANGE}, @@ -2642,12 +2643,16 @@ md_parse_option (c, arg) break; case OPTION_DSP: - sh_dsp = 1; + preset_target_arch = arch_sh1_up & ~arch_sh3e_up; break; -#ifdef HAVE_SH64 case OPTION_ISA: - if (strcasecmp (arg, "shmedia") == 0) + if (strcasecmp (arg, "sh4") == 0) + preset_target_arch = arch_sh4; + else if (strcasecmp (arg, "any") == 0) + preset_target_arch = arch_sh1_up; +#ifdef HAVE_SH64 + else if (strcasecmp (arg, "shmedia") == 0) { if (sh64_isa_mode == sh64_isa_shcompact) as_bad (_("Invalid combination: --isa=SHcompact with --isa=SHmedia")); @@ -2661,10 +2666,12 @@ md_parse_option (c, arg) as_bad (_("Invalid combination: --abi=64 with --isa=SHcompact")); sh64_isa_mode = sh64_isa_shcompact; } +#endif /* HAVE_SH64 */ else as_bad ("Invalid argument to --isa option: %s", arg); break; +#ifdef HAVE_SH64 case OPTION_ABI: if (strcmp (arg, "32") == 0) { @@ -3381,7 +3388,10 @@ md_apply_fix3 (fixP, valP, seg) val -= S_GET_VALUE (fixP->fx_addsy); #endif -#ifndef BFD_ASSEMBLER +#ifdef BFD_ASSEMBLER + if (SWITCH_TABLE (fixP)) + val -= S_GET_VALUE (fixP->fx_subsy); +#else if (fixP->fx_r_type == 0) { if (fixP->fx_size == 2) @@ -3902,7 +3912,8 @@ tc_gen_reloc (section, fixp) if (SWITCH_TABLE (fixp)) { - rel->addend = rel->address - S_GET_VALUE (fixp->fx_subsy); + *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); + rel->addend = 0; if (r_type == BFD_RELOC_16) r_type = BFD_RELOC_SH_SWITCH16; else if (r_type == BFD_RELOC_8) @@ -3941,6 +3952,8 @@ tc_gen_reloc (section, fixp) rel->addend = 0; rel->howto = bfd_reloc_type_lookup (stdoutput, r_type); + if (rel->howto->type == R_SH_IND12W) + rel->addend += fixp->fx_offset - 4; if (rel->howto == NULL) { as_bad_where (fixp->fx_file, fixp->fx_line, |