diff options
author | Alan Modra <amodra@gmail.com> | 2001-01-14 05:22:51 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2001-01-14 05:22:51 +0000 |
commit | b352eebf39412ea12700904ec4667d907fe45ea5 (patch) | |
tree | e4e3f5d0902e51c5ff835e568cd49673644aaa35 /bfd/elf64-hppa.c | |
parent | 1328dc9844bf1fc941f648d0df5b7c2b3b5fcaba (diff) | |
download | gdb-b352eebf39412ea12700904ec4667d907fe45ea5.zip gdb-b352eebf39412ea12700904ec4667d907fe45ea5.tar.gz gdb-b352eebf39412ea12700904ec4667d907fe45ea5.tar.bz2 |
Wide mode .plt offsets for elf64-hppa
Diffstat (limited to 'bfd/elf64-hppa.c')
-rw-r--r-- | bfd/elf64-hppa.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 22a6f9e..42dbf60 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -1,5 +1,5 @@ -/* Generic support for 64-bit ELF - Copyright 1999, 2000 Free Software Foundation, Inc. +/* Support for HPPA 64-bit ELF + Copyright 1999, 2000, 2001 Free Software Foundation, Inc. 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; int insn; + unsigned int max_offset; /* 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; insn = bfd_get_32 (stub->owner, stub->contents + dyn_h->stub_offset); - insn &= 0xffffc00e; - insn |= ((value & 0x2000) >> 13); - value &= 0x1ff8; - value <<= 1; - bfd_put_32 (stub->owner, (insn | value), + if (output_bfd->arch_info->mach >= 25) + { + /* Wide mode allows 16 bit offsets. */ + max_offset = 32768; + 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); /* 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 &= 0xffffc00e; - insn |= ((value & 0x2000) >> 13); - value &= 0x1ff8; - value <<= 1; - bfd_put_32 (stub->owner, (insn | value), + if (output_bfd->arch_info->mach >= 25) + { + insn &= ~ 0xfff1; + insn |= re_assemble_16 (value); + } + else + { + insn &= ~ 0x3ff1; + insn |= re_assemble_14 (value); + } + bfd_put_32 (stub->owner, insn, stub->contents + dyn_h->stub_offset + 8); } |