mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
* elf32-iq2000.c (iq2000_elf_relocate_section): Adjust addend of
relocation pointing to local symbol in merged section. * elf32-iq2000.c (iq2000_elf_relocate_offset16): New. (iq2000_elf_relocate_section): Call it.
This commit is contained in:
parent
e8efc4d9fd
commit
f15557e4ab
@ -1,3 +1,11 @@
|
||||
2008-02-12 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* elf32-iq2000.c (iq2000_elf_relocate_section): Adjust addend of
|
||||
relocation pointing to local symbol in merged section.
|
||||
|
||||
* elf32-iq2000.c (iq2000_elf_relocate_offset16): New.
|
||||
(iq2000_elf_relocate_section): Call it.
|
||||
|
||||
2008-02-12 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR ld/5692
|
||||
|
@ -306,6 +306,34 @@ iq2000_elf_relocate_hi16 (bfd *input_bfd,
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
static bfd_reloc_status_type
|
||||
iq2000_elf_relocate_offset16 (bfd *input_bfd,
|
||||
Elf_Internal_Rela *rel,
|
||||
bfd_byte *contents,
|
||||
bfd_vma value,
|
||||
bfd_vma location)
|
||||
{
|
||||
bfd_vma insn;
|
||||
bfd_vma jtarget;
|
||||
|
||||
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
|
||||
value += rel->r_addend;
|
||||
|
||||
if (value & 3)
|
||||
return bfd_reloc_dangerous;
|
||||
|
||||
jtarget = (value & 0x3fffc) | (location & 0xf0000000L);
|
||||
|
||||
if (jtarget != value)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
insn = (insn & ~0xFFFF) | ((value >> 2) & 0xFFFF);
|
||||
|
||||
bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
/* Map BFD reloc types to IQ2000 ELF reloc types. */
|
||||
|
||||
static reloc_howto_type *
|
||||
@ -572,15 +600,25 @@ iq2000_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
asection *osec;
|
||||
|
||||
sym = local_syms + r_symndx;
|
||||
sec = local_sections [r_symndx];
|
||||
osec = sec = local_sections [r_symndx];
|
||||
if ((sec->flags & SEC_MERGE)
|
||||
&& ELF_ST_TYPE (sym->st_info) == STT_SECTION)
|
||||
/* This relocation is relative to a section symbol that is
|
||||
going to be merged. Change it so that it is relative
|
||||
to the merged section symbol. */
|
||||
rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym, &sec,
|
||||
rel->r_addend);
|
||||
|
||||
relocation = (sec->output_section->vma
|
||||
+ sec->output_offset
|
||||
+ sym->st_value);
|
||||
|
||||
name = bfd_elf_string_from_elf_section
|
||||
(input_bfd, symtab_hdr->sh_link, sym->st_name);
|
||||
name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
|
||||
name = (name == NULL) ? bfd_section_name (input_bfd, osec) : name;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -615,6 +653,13 @@ iq2000_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||
r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
|
||||
break;
|
||||
|
||||
case R_IQ2000_OFFSET_16:
|
||||
r = iq2000_elf_relocate_offset16 (input_bfd, rel, contents, relocation,
|
||||
input_section->output_section->vma
|
||||
+ input_section->output_offset
|
||||
+ rel->r_offset);
|
||||
break;
|
||||
|
||||
case R_IQ2000_PC16:
|
||||
rel->r_addend -= 4;
|
||||
/* Fall through. */
|
||||
|
Loading…
Reference in New Issue
Block a user