Wide mode .plt offsets for elf64-hppa

This commit is contained in:
Alan Modra 2001-01-14 05:22:51 +00:00
parent 1328dc9844
commit b352eebf39
2 changed files with 43 additions and 14 deletions

View file

@ -1,3 +1,8 @@
2001-01-14 Alan Modra <alan@linuxcare.com.au>
* elf64-hppa.c (elf64_hppa_finish_dynamic_symbol): Use 16-bit
offsets for stub .plt access if wide mode. Check offset in range.
2001-01-13 Nick Clifton <nickc@redhat.com> 2001-01-13 Nick Clifton <nickc@redhat.com>
* elf32-fr30.c (fr30_elf_howto_table): Remove spurious blank * elf32-fr30.c (fr30_elf_howto_table): Remove spurious blank

View file

@ -1,5 +1,5 @@
/* Generic support for 64-bit ELF /* Support for HPPA 64-bit ELF
Copyright 1999, 2000 Free Software Foundation, Inc. Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library. This file is part of BFD, the Binary File Descriptor library.
@ -1954,6 +1954,7 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
{ {
bfd_vma value; bfd_vma value;
int insn; int insn;
unsigned int max_offset;
/* Install the generic stub template. /* Install the generic stub template.
@ -1975,22 +1976,45 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
value = dyn_h->plt_offset - hppa_info->gp_offset; value = dyn_h->plt_offset - hppa_info->gp_offset;
insn = bfd_get_32 (stub->owner, stub->contents + dyn_h->stub_offset); insn = bfd_get_32 (stub->owner, stub->contents + dyn_h->stub_offset);
insn &= 0xffffc00e; if (output_bfd->arch_info->mach >= 25)
insn |= ((value & 0x2000) >> 13); {
value &= 0x1ff8; /* Wide mode allows 16 bit offsets. */
value <<= 1; max_offset = 32768;
bfd_put_32 (stub->owner, (insn | value), insn &= ~ 0xfff1;
insn |= re_assemble_16 (value);
}
else
{
max_offset = 8192;
insn &= ~ 0x3ff1;
insn |= re_assemble_14 (value);
}
if ((value & 7) || value + max_offset >= 2*max_offset - 8)
{
(*_bfd_error_handler) (_("stub entry for %s cannot load .plt, dp offset = %ld"),
dyn_h->root.string,
(long) value);
return false;
}
bfd_put_32 (stub->owner, insn,
stub->contents + dyn_h->stub_offset); stub->contents + dyn_h->stub_offset);
/* Fix up the second ldd instruction. */ /* Fix up the second ldd instruction. */
value = dyn_h->plt_offset - hppa_info->gp_offset + 8; value += 8;
insn = bfd_get_32 (stub->owner, stub->contents + dyn_h->stub_offset + 8); insn = bfd_get_32 (stub->owner, stub->contents + dyn_h->stub_offset + 8);
insn &= 0xffffc00e; if (output_bfd->arch_info->mach >= 25)
insn |= ((value & 0x2000) >> 13); {
value &= 0x1ff8; insn &= ~ 0xfff1;
value <<= 1; insn |= re_assemble_16 (value);
bfd_put_32 (stub->owner, (insn | value), }
else
{
insn &= ~ 0x3ff1;
insn |= re_assemble_14 (value);
}
bfd_put_32 (stub->owner, insn,
stub->contents + dyn_h->stub_offset + 8); stub->contents + dyn_h->stub_offset + 8);
} }