PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
static enum elf_reloc_type_class sh_elf_reloc_type_class
- PARAMS ((int));
+ PARAMS ((const Elf_Internal_Rela *));
/* The name of the dynamic interpreter. This is put in the .interp
section. */
complain_overflow_signed, /* complain_on_overflow */
sh_elf_ignore_reloc, /* special_function */
"R_SH_REL32", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
true), /* pcrel_offset */
if (laddr >= sec->_raw_size)
{
(*_bfd_error_handler) (_("%s: 0x%lx: warning: bad R_SH_USES offset"),
- bfd_get_filename (abfd),
+ bfd_archive_filename (abfd),
(unsigned long) irel->r_offset);
continue;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
- bfd_get_filename (abfd), (unsigned long) irel->r_offset, insn));
+ bfd_archive_filename (abfd), (unsigned long) irel->r_offset, insn));
continue;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: warning: bad R_SH_USES load offset"),
- bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
continue;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: warning: could not find expected reloc"),
- bfd_get_filename (abfd), (unsigned long) paddr));
+ bfd_archive_filename (abfd), (unsigned long) paddr));
continue;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: warning: symbol in unexpected section"),
- bfd_get_filename (abfd), (unsigned long) paddr));
+ bfd_archive_filename (abfd), (unsigned long) paddr));
continue;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: warning: could not find expected COUNT reloc"),
- bfd_get_filename (abfd), (unsigned long) paddr));
+ bfd_archive_filename (abfd), (unsigned long) paddr));
continue;
}
if (irelcount->r_addend == 0)
{
((*_bfd_error_handler) (_("%s: 0x%lx: warning: bad count"),
- bfd_get_filename (abfd),
+ bfd_archive_filename (abfd),
(unsigned long) paddr));
continue;
}
else
{
/* Cache the symbols for elf_link_input_bfd. */
- symtab_hdr->contents = extsyms;
+ symtab_hdr->contents = (unsigned char *) extsyms;
}
free_extsyms = NULL;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
- bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
bfd_set_error (bfd_error_bad_value);
return false;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
- bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
bfd_set_error (bfd_error_bad_value);
return false;
}
howto = sh_elf_howto_table + r_type;
- /* This is a final link. */
+ /* For relocs that aren't partial_inplace, we get the addend from
+ the relocation. */
+ if (! howto->partial_inplace)
+ addend = rel->r_addend;
+
h = NULL;
sym = NULL;
sec = NULL;
section symbol winds up in the output section. */
sym = local_syms + r_symndx;
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
- goto final_link_relocate;
+ {
+ if (! howto->partial_inplace)
+ {
+ /* For relocations with the addend in the
+ relocation, we need just to update the addend.
+ All real relocs are of type partial_inplace; this
+ code is mostly for completeness. */
+ rel->r_addend += sec->output_offset + sym->st_value;
+
+ continue;
+ }
+
+ /* Relocs of type partial_inplace need to pick up the
+ contents in the contents and add the offset resulting
+ from the changed location of the section symbol.
+ Using _bfd_final_link_relocate (e.g. goto
+ final_link_relocate) here would be wrong, because
+ relocations marked pc_relative would get the current
+ location subtracted, and we must only do that at the
+ final link. */
+ r = _bfd_relocate_contents (howto, input_bfd,
+ sec->output_offset
+ + sym->st_value,
+ contents + rel->r_offset);
+ goto relocation_done;
+ }
continue;
}
{
(*_bfd_error_handler)
(_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
- bfd_get_filename (input_bfd), h->root.root.string,
+ bfd_archive_filename (input_bfd), h->root.root.string,
bfd_get_section_name (input_bfd, input_section));
relocation = 0;
}
{
((*_bfd_error_handler)
(_("%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
- bfd_get_filename (input_section->owner),
+ bfd_archive_filename (input_section->owner),
(unsigned long) rel->r_offset));
bfd_set_error (bfd_error_bad_value);
return false;
case R_SH_DIR32:
case R_SH_REL32:
if (info->shared
+ && r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0
&& (r_type != R_SH_REL32
|| (h != NULL
BFD_ASSERT (h != NULL && h->dynindx != -1);
relocate = false;
outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32);
- outrel.r_addend = rel->r_addend;
+ outrel.r_addend
+ = bfd_get_32 (input_bfd, contents + rel->r_offset);
}
else
{
{
relocate = true;
outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
- outrel.r_addend = relocation + rel->r_addend;
+ outrel.r_addend
+ = relocation + bfd_get_32 (input_bfd,
+ contents + rel->r_offset);
}
else
{
BFD_ASSERT (h->dynindx != -1);
relocate = false;
outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_DIR32);
- outrel.r_addend = relocation + rel->r_addend;
+ outrel.r_addend
+ = relocation + bfd_get_32 (input_bfd,
+ contents + rel->r_offset);
}
}
if (! relocate)
continue;
}
- else if (r_type == R_SH_DIR32)
- addend = rel->r_addend;
goto final_link_relocate;
case R_SH_GOT32:
}
}
+ relocation_done:
if (r != bfd_reloc_ok)
{
switch (r)
{
(*_bfd_error_handler)
("%s: uses %s instructions while previous modules use %s instructions",
- bfd_get_filename (ibfd),
+ bfd_archive_filename (ibfd),
EF_SH_HAS_DSP (new_flags) ? "dsp" : "floating point",
EF_SH_HAS_DSP (new_flags) ? "floating point" : "dsp");
bfd_set_error (bfd_error_bad_value);
}
static enum elf_reloc_type_class
-sh_elf_reloc_type_class (type)
- int type;
+sh_elf_reloc_type_class (rela)
+ const Elf_Internal_Rela *rela;
{
- switch (type)
+ switch ((int) ELF32_R_TYPE (rela->r_info))
{
case R_SH_RELATIVE:
return reloc_class_relative;