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.
This commit is contained in:
Joern Rennecke 2003-03-03 21:04:01 +00:00
parent a0ed55327d
commit bdfaef528f
7 changed files with 91 additions and 19 deletions

View file

@ -1,3 +1,16 @@
Mon Mar 3 20:48:23 2003 J"orn Rennecke <joern.rennecke@superh.com>
* 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.
2003-03-03 Nick Clifton <nickc@redhat.com>
* po/da.po: Installed latest translation.

View file

@ -179,6 +179,8 @@ static reloc_howto_type sh_elf_howto_table[] =
TRUE), /* pcrel_offset */
/* 12 bit PC relative branch divided by 2. */
/* This cannot be partial_inplace because relaxation can't know the
eventual value of a symbol. */
HOWTO (R_SH_IND12W, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
@ -186,10 +188,10 @@ static reloc_howto_type sh_elf_howto_table[] =
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
sh_elf_reloc, /* special_function */
NULL, /* special_function */
"R_SH_IND12W", /* name */
TRUE, /* partial_inplace */
0xfff, /* src_mask */
FALSE, /* partial_inplace */
0x0, /* src_mask */
0xfff, /* dst_mask */
TRUE), /* pcrel_offset */
@ -2232,6 +2234,12 @@ sh_elf_relax_section (abfd, sec, link_info, again)
/* Change the R_SH_USES reloc into an R_SH_IND12W reloc, and
replace the jsr with a bsr. */
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_SH_IND12W);
/* We used to test (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
here, but that only checks if the symbol is an external symbol,
not if the symbol is in a different section. Besides, we need
a consistent meaning for the relocation, so we just assume here that
the value of the symbol is not available. */
#if 0
if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
{
/* If this needs to be changed because of future relaxing,
@ -2242,12 +2250,14 @@ sh_elf_relax_section (abfd, sec, link_info, again)
contents + irel->r_offset);
}
else
#endif
{
/* We can't fully resolve this yet, because the external
symbol value may be changed by future relaxing. We let
the final link phase handle it. */
bfd_put_16 (abfd, (bfd_vma) 0xb000, contents + irel->r_offset);
}
irel->r_addend = -4;
/* See if there is another R_SH_USES reloc referring to the same
register load. */
@ -2316,7 +2326,8 @@ sh_elf_relax_section (abfd, sec, link_info, again)
/* Look for load and store instructions that we can align on four
byte boundaries. */
if (have_code)
if ((elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK) != EF_SH4
&& have_code)
{
bfd_boolean swapped;
@ -2542,14 +2553,28 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
break;
case R_SH_IND12W:
if (ELF32_R_SYM (irel->r_info) >= symtab_hdr->sh_info)
start = stop = addr;
off = insn & 0xfff;
if (! off)
{
/* This has been made by previous relaxation. Since the
relocation will be against an external symbol, the
final relocation will just do the right thing. */
start = stop = addr;
}
else
{
off = insn & 0xfff;
if (off & 0x800)
off -= 0x1000;
stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
/* The addend will be against the section symbol, thus
for adjusting the addend, the relevant start is the
start of the section.
N.B. If we want to abandom in-place changes here and
test directly using symbol + addend, we have to take into
account that the addend has already been adjusted by -4. */
if (stop > addr && stop < toaddr)
irel->r_addend -= count;
}
break;
@ -4811,7 +4836,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
break;
case R_SH_IND12W:
relocation -= 4;
goto final_link_relocate;
case R_SH_DIR8WPN:

View file

@ -1,3 +1,17 @@
Mon Mar 3 20:36:47 2003 J"orn Rennecke <joern.rennecke@superh.com>
* 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.
2003-03-02 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
* config/tc-mips.c (append_insn): Add handling of

View file

@ -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,

View file

@ -235,6 +235,8 @@ extern bfd_boolean sh_fix_adjustable PARAMS ((struct fix *));
|| (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC \
|| TC_FORCE_RELOCATION (FIX))
#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) (sh_relax && SWITCH_TABLE (FIX))
/* This keeps the subtracted symbol around, for use by PLT_PCREL
relocs. */
#define TC_FORCE_RELOCATION_SUB_ABS(FIX) \

View file

@ -1,3 +1,8 @@
Mon Mar 3 20:35:58 2003 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (EF_SH_MERGE_MACH): Make sure SH2E & SH3/SH3E merge to SH3E,
and SH2E & SH4 merge to SH4, not SH2E.
2003-02-21 Ian Wienand <ianw@gelato.unsw.edu.au>
* ia64.h (SHT_IA_64_LOPSREG, SHT_IA_64_HIPSREG,

View file

@ -56,7 +56,8 @@
: (((mach1) == EF_SH3E && (mach2) == EF_SH_UNKNOWN) \
|| ((mach2) == EF_SH3E && (mach1) == EF_SH_UNKNOWN)) \
? EF_SH4 \
: ((mach1) > (mach2) ? (mach1) : (mach2)))
: (((mach1) == EF_SH2E ? 7 : (mach1)) > ((mach2) == EF_SH2E ? 7 : (mach2)) \
? (mach1) : (mach2)))
/* Flags for the st_other symbol field.
Keep away from the STV_ visibility flags (bit 0..1). */