aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/configure.in7
-rw-r--r--bfd/elf32-hppa.c1307
-rw-r--r--bfd/elf32-hppa.h52
-rw-r--r--bfd/libhppa.h454
-rw-r--r--bfd/som.c602
5 files changed, 1860 insertions, 562 deletions
diff --git a/bfd/configure.in b/bfd/configure.in
index 2c375fe..9f23637 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -51,6 +51,10 @@ for targ in $target $canon_targets
do
bfd_target=`$srcdir/config.bfd $targ`
+ case "$targ" in
+ netbsd386) bfd_target=i386-netbsd ;;
+ esac
+
if [ "x$bfd_target" = "xall" ]; then
all_targets=true
else
@@ -171,9 +175,10 @@ if [ x${all_targets} = xfalse ]; then
host_aout_vec) tb="$tb host-aout.o aout32.o stab-syms.o" ;;
hp300bsd_vec) tb="$tb hp300bsd.o aout32.o stab-syms.o" ;;
hp300hpux_vec) tb="$tb hp300hpux.o aout32.o stab-syms.o" ;;
- hppa_vec) tb="$tb hppa.o" ;;
+ hppa_vec) tb="$tb som.o" ;;
i386aout_vec) tb="$tb i386aout.o aout32.o stab-syms.o" ;;
i386bsd_vec) tb="$tb i386bsd.o aout32.o stab-syms.o" ;;
+ netbsd386_vec) tb="$tb netbsd386.o aout32.o stab-syms.o" ;;
i386coff_vec) tb="$tb coff-i386.o" ;;
i386linux_vec) tb="$tb i386linux.o aout32.o stab-syms.o" ;;
i386lynx_vec) tb="$tb i386lynx.o aout32.o stab-syms.o" ;;
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index afc4011..99801bd 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -45,156 +45,157 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "elf32-hppa.h"
-/*#include "libhppa.h"*/
-#define BYTES_IN_WORD 4
+#include "libhppa.h"
#include "aout/aout64.h"
+#include "hppa_stubs.h"
/* ELF/PA relocation howto entries */
static bfd_reloc_status_type hppa_elf_reloc ();
-reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
+static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
{
/* 'bitpos' and 'abs' are obsolete */
/* type rs sz bsz pcrel bpos abs ovrf sf name */
/* 9.3.4. Address relocation types */
- {R_HPPA_NONE, 0, 3, 19, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NONE"},
- {R_HPPA_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_32"},
- {R_HPPA_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_11"},
- {R_HPPA_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_14"},
- {R_HPPA_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_17"},
-{R_HPPA_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L21"},
-{R_HPPA_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R11"},
-{R_HPPA_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R14"},
-{R_HPPA_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R17"},
- {R_HPPA_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LS21"},
- {R_HPPA_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS11"},
- {R_HPPA_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS14"},
- {R_HPPA_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS17"},
- {R_HPPA_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LD21"},
- {R_HPPA_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD11"},
- {R_HPPA_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD14"},
- {R_HPPA_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD17"},
- {R_HPPA_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LR21"},
- {R_HPPA_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR14"},
- {R_HPPA_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR17"},
+ {R_HPPA_NONE, 0, 3, 19, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NONE"},
+ {R_HPPA_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_32"},
+ {R_HPPA_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_11"},
+ {R_HPPA_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_14"},
+ {R_HPPA_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_17"},
+{R_HPPA_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L21"},
+{R_HPPA_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R11"},
+{R_HPPA_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R14"},
+{R_HPPA_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R17"},
+ {R_HPPA_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LS21"},
+ {R_HPPA_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS11"},
+ {R_HPPA_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS14"},
+ {R_HPPA_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS17"},
+ {R_HPPA_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LD21"},
+ {R_HPPA_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD11"},
+ {R_HPPA_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD14"},
+ {R_HPPA_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD17"},
+ {R_HPPA_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LR21"},
+ {R_HPPA_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR14"},
+ {R_HPPA_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR17"},
/* 9.3.5. GOTOFF address relocation types */
- {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_11"},
- {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_14"},
- {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"},
- {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"},
- {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"},
- {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"},
- {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"},
- {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"},
- {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"},
- {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"},
- {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"},
- {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"},
- {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"},
+ {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_11"},
+ {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_14"},
+ {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"},
+ {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"},
+ {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"},
+ {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"},
+ {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"},
+ {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"},
+ {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"},
+ {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"},
+ {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"},
+ {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"},
+ {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"},
/* 9.3.6. Absolute call relocation types */
- {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"},
- {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"},
- {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"},
- {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"},
- {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"},
- {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"},
- {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"},
- {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"},
- {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"},
- {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"},
- {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"},
- {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"},
- {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"},
- {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"},
- {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"},
- {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"},
- {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"},
- {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"},
+ {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"},
+ {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"},
+ {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"},
+ {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"},
+ {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"},
+ {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"},
+ {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"},
+ {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"},
+ {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"},
+ {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"},
+ {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"},
+ {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"},
+ {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"},
+ {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"},
+ {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"},
+ {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"},
+ {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"},
+ {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"},
/* 9.3.7. PC-relative call relocation types */
- {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"},
- {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"},
- {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"},
- {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"},
- {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"},
- {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"},
- {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"},
- {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"},
- {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"},
- {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"},
- {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"},
- {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"},
- {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"},
- {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"},
- {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"},
- {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"},
- {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"},
- {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"},
- {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"},
+ {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"},
+ {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"},
+ {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"},
+ {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"},
+ {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"},
+ {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"},
+ {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"},
+ {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"},
+ {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"},
+ {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"},
+ {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"},
+ {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"},
+ {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"},
+ {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"},
+ {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"},
+ {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"},
+ {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"},
+ {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"},
+ {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"},
/* 9.3.8. Plabel relocation types */
- {R_HPPA_PLABEL_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_32"},
- {R_HPPA_PLABEL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_11"},
- {R_HPPA_PLABEL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_14"},
- {R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_L21"},
- {R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R11"},
- {R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R14"},
+ {R_HPPA_PLABEL_32, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_32"},
+ {R_HPPA_PLABEL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_11"},
+ {R_HPPA_PLABEL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_14"},
+ {R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_L21"},
+ {R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R11"},
+ {R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R14"},
/* 9.3.9. Data linkage table (DLT) relocation types */
- {R_HPPA_DLT_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_32"},
- {R_HPPA_DLT_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_11"},
- {R_HPPA_DLT_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_14"},
- {R_HPPA_DLT_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_L21"},
- {R_HPPA_DLT_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R11"},
- {R_HPPA_DLT_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R14"},
+ {R_HPPA_DLT_32, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_32"},
+ {R_HPPA_DLT_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_11"},
+ {R_HPPA_DLT_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_14"},
+ {R_HPPA_DLT_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_L21"},
+ {R_HPPA_DLT_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R11"},
+ {R_HPPA_DLT_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R14"},
/* 9.3.10. Relocations for unwinder tables */
- {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
- {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"},
+ {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
+ {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"},
/* 9.3.11. Relocation types for complex expressions */
- {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_CONST"},
- {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PC"},
- {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_SYM"},
- {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"},
- {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"},
- {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"},
- {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"},
-{R_HPPA_MAX, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MAX"},
-{R_HPPA_MIN, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MIN"},
-{R_HPPA_ADD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ADD"},
-{R_HPPA_SUB, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_SUB"},
- {R_HPPA_MULT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MULT"},
-{R_HPPA_DIV, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_DIV"},
-{R_HPPA_MOD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MOD"},
-{R_HPPA_AND, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_AND"},
- {R_HPPA_OR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_OR"},
-{R_HPPA_XOR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_XOR"},
-{R_HPPA_NOT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NOT"},
- {R_HPPA_LSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LSHIFT"},
- {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"},
- {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"},
-{R_HPPA_EXPR_F, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L"},
- {R_HPPA_EXPR_L, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_L"},
- {R_HPPA_EXPR_R, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_R"},
- {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LS"},
- {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RS"},
- {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LD"},
- {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RD"},
- {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LR"},
- {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RR"},
-
- {R_HPPA_EXPR_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_32"},
- {R_HPPA_EXPR_21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_21"},
- {R_HPPA_EXPR_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_11"},
- {R_HPPA_EXPR_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_14"},
- {R_HPPA_EXPR_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_17"},
- {R_HPPA_EXPR_12, 0, 3, 12, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_12"},
- {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, false, false, NULL, "R_HPPA_UNIMPLEMENTED"},
+ {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_CONST"},
+ {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PC"},
+ {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_SYM"},
+ {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"},
+ {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"},
+ {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"},
+ {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"},
+{R_HPPA_MAX, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MAX"},
+{R_HPPA_MIN, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MIN"},
+{R_HPPA_ADD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ADD"},
+{R_HPPA_SUB, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_SUB"},
+ {R_HPPA_MULT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MULT"},
+{R_HPPA_DIV, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_DIV"},
+{R_HPPA_MOD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MOD"},
+{R_HPPA_AND, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_AND"},
+ {R_HPPA_OR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_OR"},
+{R_HPPA_XOR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_XOR"},
+{R_HPPA_NOT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NOT"},
+ {R_HPPA_LSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LSHIFT"},
+ {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"},
+ {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"},
+{R_HPPA_EXPR_F, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L"},
+ {R_HPPA_EXPR_L, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_L"},
+ {R_HPPA_EXPR_R, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_R"},
+ {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LS"},
+ {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RS"},
+ {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LD"},
+ {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RD"},
+ {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LR"},
+ {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RR"},
+
+ {R_HPPA_EXPR_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_32"},
+ {R_HPPA_EXPR_21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_21"},
+ {R_HPPA_EXPR_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_11"},
+ {R_HPPA_EXPR_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_14"},
+ {R_HPPA_EXPR_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_17"},
+ {R_HPPA_EXPR_12, 0, 3, 12, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_12"},
+ {R_HPPA_STUB_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_STUB_CALL_17"},
+ {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_HPPA_UNIMPLEMENTED"},
};
-static symext_chainS *symext_rootP = NULL;
-static symext_chainS *symext_lastP = NULL;
+static symext_chainS *symext_rootP;
+static symext_chainS *symext_lastP;
static unsigned long
DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format),
@@ -301,7 +302,7 @@ DEFUN (hppa_elf_relocate_insn,
if (pcrel)
sym_value -= address;
sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
- return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_format, r_format);
+ return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
case COMICLR:
case SUBI: /* case SUBIO: */
@@ -407,32 +408,23 @@ DEFUN (hppa_elf_relocate_unwind_table,
case R_HPPA_UNWIND_ENTRIES:
for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long))
{
- unsigned int fsize;
+ unsigned int adjustment;
start_offset = bfd_get_32 (abfd, hit_data);
/* Stuff the symbol value into the first word */
/* of the unwind descriptor */
bfd_put_32 (abfd, sym_value, hit_data);
+ adjustment = sym_value - start_offset;
hit_data += sizeof (unsigned long);
- end_offset = bfd_get_32 (abfd, hit_data);
- /* We could also compute the ending offset for */
- /* the 2nd word of the unwind entry by */
- /* retrieving the st_size field of the Elf_Sym */
- /* structure stored with this symbol. We can */
- /* get it with: */
- /* e = (elf_symbol_type *)symp */
- /* fsize = e->internal_elf_sym.st_size */
-
- fsize = end_offset - start_offset;
- relocated_value = hppa_field_adjust (sym_value, fsize, r_field);
- bfd_put_32 (abfd, relocated_value, hit_data);
+ end_offset = adjustment + bfd_get_32 (abfd, hit_data);
+ bfd_put_32 (abfd, end_offset, hit_data);
/* If this is not the last unwind entry, */
/* adjust the symbol value. */
if (i + 1 < r_addend)
{
start_offset = bfd_get_32 (abfd, hit_data + 3 * sizeof (unsigned long));
- sym_value += fsize + start_offset - end_offset;
+ sym_value = start_offset + adjustment;
}
}
break;
@@ -495,7 +487,7 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
int format;
int field;
{
-#define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field);
+#define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field)
elf32_hppa_reloc_type *finaltype;
elf32_hppa_reloc_type **final_types;
@@ -1178,13 +1170,13 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
#undef final_type
-/* 12.4.4. Derive format from instruction */
+/* 12.4.4. Derive format from instruction
-/* Given a machine instruction, this function determines its format. */
-/* The format can be determined solely from looking at the first six */
-/* bits (the major opcode) of the instruction. Several major opcodes */
-/* map to the same format. Opcodes which do not map to a known format */
-/* should probably be reported as an error. */
+ Given a machine instruction, this function determines its format.
+ The format can be determined solely from looking at the first six
+ bits (the major opcode) of the instruction. Several major opcodes
+ map to the same format. Opcodes which do not map to a known format
+ should probably be reported as an error. */
unsigned char
hppa_elf_insn2fmt (type, insn)
@@ -1249,9 +1241,10 @@ hppa_elf_insn2fmt (type, insn)
}
/* this function is in charge of performing all the HP PA relocations */
-static long global_value = 0;
-static long GOT_value = 0; /* XXX: need to calculate this! For HPUX, GOT == DP */
-static asymbol *global_symbol = (asymbol *) NULL;
+static long global_value;
+static long GOT_value; /* XXX: need to calculate this! For HPUX, GOT == DP */
+static asymbol *global_symbol;
+static int global_sym_defined;
static bfd_reloc_status_type
DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
@@ -1293,20 +1286,15 @@ DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, outpu
/* compute value of $global$ if it is there. */
- if (global_symbol == (asymbol *) NULL)
+ if (!global_sym_defined)
{
- struct elf_backend_data *bed
- = (struct elf_backend_data *) abfd->xvec->backend_data;
-
- if (bed && bed->global_sym)
+ if (global_symbol)
{
- asymbol *gsym = &bed->global_sym->symbol;
- global_value
- = gsym->value
- + gsym->section->output_section->vma
- + gsym->section->output_offset;
+ global_value = (global_symbol->value
+ + global_symbol->section->output_section->vma
+ + global_symbol->section->output_offset);
GOT_value = global_value; /* XXX: For HP-UX, GOT==DP */
- global_symbol = gsym;
+ global_sym_defined++;
}
}
@@ -1618,6 +1606,21 @@ DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, outpu
fprintf (stderr, "Unimplemented reloc type %d, in module %s\n",
r_type, abfd->filename);
return (bfd_reloc_notsupported);
+ case R_HPPA_STUB_CALL_17:
+ /* yes, a branch to a long branch stub. Change instruction to a BLE */
+ /* or BLE,N */
+ if ( *(unsigned *)hit_data & 2 )
+ insn = BLE_N_XXX_0_0;
+ else
+ insn = BLE_XXX_0_0;
+ bfd_put_32 (abfd, insn, hit_data);
+ r_type = R_HPPA_ABS_CALL_17;
+ r_pcrel = 0;
+ insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
+ symbol_in, sym_value, r_addend,
+ r_type, r_format, r_field, r_pcrel);
+ break;
+
default:
fprintf (stderr, "Relocation problem : ");
fprintf (stderr, "Unrecognized reloc type %d, in module %s\n",
@@ -1632,107 +1635,11 @@ DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, outpu
}
-struct elf_reloc_map
- {
- unsigned char bfd_reloc_val;
- unsigned char elf_reloc_val;
- };
-
-static CONST struct elf_reloc_map elf_hppa_reloc_map[] =
-{
- {BFD_RELOC_NONE, R_HPPA_NONE,},
- {BFD_RELOC_HPPA_32, R_HPPA_32,},
- {BFD_RELOC_HPPA_11, R_HPPA_11,},
- {BFD_RELOC_HPPA_14, R_HPPA_14,},
- {BFD_RELOC_HPPA_17, R_HPPA_17,},
- {BFD_RELOC_HPPA_L21, R_HPPA_L21,},
- {BFD_RELOC_HPPA_R11, R_HPPA_R11,},
- {BFD_RELOC_HPPA_R14, R_HPPA_R14,},
- {BFD_RELOC_HPPA_R17, R_HPPA_R17,},
- {BFD_RELOC_HPPA_LS21, R_HPPA_LS21,},
- {BFD_RELOC_HPPA_RS11, R_HPPA_RS11,},
- {BFD_RELOC_HPPA_RS14, R_HPPA_RS14,},
- {BFD_RELOC_HPPA_RS17, R_HPPA_RS17,},
- {BFD_RELOC_HPPA_LD21, R_HPPA_LD21,},
- {BFD_RELOC_HPPA_RD11, R_HPPA_RD11,},
- {BFD_RELOC_HPPA_RD14, R_HPPA_RD14,},
- {BFD_RELOC_HPPA_RD17, R_HPPA_RD17,},
- {BFD_RELOC_HPPA_LR21, R_HPPA_LR21,},
- {BFD_RELOC_HPPA_RR14, R_HPPA_RR14,},
- {BFD_RELOC_HPPA_RR17, R_HPPA_RR17,},
- {BFD_RELOC_HPPA_GOTOFF_11, R_HPPA_GOTOFF_11,},
- {BFD_RELOC_HPPA_GOTOFF_14, R_HPPA_GOTOFF_14,},
- {BFD_RELOC_HPPA_GOTOFF_L21, R_HPPA_GOTOFF_L21,},
- {BFD_RELOC_HPPA_GOTOFF_R11, R_HPPA_GOTOFF_R11,},
- {BFD_RELOC_HPPA_GOTOFF_R14, R_HPPA_GOTOFF_R14,},
- {BFD_RELOC_HPPA_GOTOFF_LS21, R_HPPA_GOTOFF_LS21,},
- {BFD_RELOC_HPPA_GOTOFF_RS11, R_HPPA_GOTOFF_RS11,},
- {BFD_RELOC_HPPA_GOTOFF_RS14, R_HPPA_GOTOFF_RS14,},
- {BFD_RELOC_HPPA_GOTOFF_LD21, R_HPPA_GOTOFF_LD21,},
- {BFD_RELOC_HPPA_GOTOFF_RD11, R_HPPA_GOTOFF_RD11,},
- {BFD_RELOC_HPPA_GOTOFF_RD14, R_HPPA_GOTOFF_RD14,},
- {BFD_RELOC_HPPA_GOTOFF_LR21, R_HPPA_GOTOFF_LR21,},
- {BFD_RELOC_HPPA_GOTOFF_RR14, R_HPPA_GOTOFF_RR14,},
- {BFD_RELOC_HPPA_ABS_CALL_11, R_HPPA_ABS_CALL_11,},
- {BFD_RELOC_HPPA_ABS_CALL_14, R_HPPA_ABS_CALL_14,},
- {BFD_RELOC_HPPA_ABS_CALL_17, R_HPPA_ABS_CALL_17,},
- {BFD_RELOC_HPPA_ABS_CALL_L21, R_HPPA_ABS_CALL_L21,},
- {BFD_RELOC_HPPA_ABS_CALL_R11, R_HPPA_ABS_CALL_R11,},
- {BFD_RELOC_HPPA_ABS_CALL_R14, R_HPPA_ABS_CALL_R14,},
- {BFD_RELOC_HPPA_ABS_CALL_R17, R_HPPA_ABS_CALL_R17,},
- {BFD_RELOC_HPPA_ABS_CALL_LS21, R_HPPA_ABS_CALL_LS21,},
- {BFD_RELOC_HPPA_ABS_CALL_RS11, R_HPPA_ABS_CALL_RS11,},
- {BFD_RELOC_HPPA_ABS_CALL_RS14, R_HPPA_ABS_CALL_RS14,},
- {BFD_RELOC_HPPA_ABS_CALL_RS17, R_HPPA_ABS_CALL_RS17,},
- {BFD_RELOC_HPPA_ABS_CALL_LD21, R_HPPA_ABS_CALL_LD21,},
- {BFD_RELOC_HPPA_ABS_CALL_RD11, R_HPPA_ABS_CALL_RD11,},
- {BFD_RELOC_HPPA_ABS_CALL_RD14, R_HPPA_ABS_CALL_RD14,},
- {BFD_RELOC_HPPA_ABS_CALL_RD17, R_HPPA_ABS_CALL_RD17,},
- {BFD_RELOC_HPPA_ABS_CALL_LR21, R_HPPA_ABS_CALL_LR21,},
- {BFD_RELOC_HPPA_ABS_CALL_RR14, R_HPPA_ABS_CALL_RR14,},
- {BFD_RELOC_HPPA_ABS_CALL_RR17, R_HPPA_ABS_CALL_RR17,},
- {BFD_RELOC_HPPA_PCREL_CALL_11, R_HPPA_PCREL_CALL_11,},
- {BFD_RELOC_HPPA_PCREL_CALL_14, R_HPPA_PCREL_CALL_14,},
- {BFD_RELOC_HPPA_PCREL_CALL_17, R_HPPA_PCREL_CALL_17,},
- {BFD_RELOC_HPPA_PCREL_CALL_12, R_HPPA_PCREL_CALL_12,},
- {BFD_RELOC_HPPA_PCREL_CALL_L21, R_HPPA_PCREL_CALL_L21,},
- {BFD_RELOC_HPPA_PCREL_CALL_R11, R_HPPA_PCREL_CALL_R11,},
- {BFD_RELOC_HPPA_PCREL_CALL_R14, R_HPPA_PCREL_CALL_R14,},
- {BFD_RELOC_HPPA_PCREL_CALL_R17, R_HPPA_PCREL_CALL_R17,},
- {BFD_RELOC_HPPA_PCREL_CALL_LS21, R_HPPA_PCREL_CALL_LS21,},
- {BFD_RELOC_HPPA_PCREL_CALL_RS11, R_HPPA_PCREL_CALL_RS11,},
- {BFD_RELOC_HPPA_PCREL_CALL_RS14, R_HPPA_PCREL_CALL_RS14,},
- {BFD_RELOC_HPPA_PCREL_CALL_RS17, R_HPPA_PCREL_CALL_RS17,},
- {BFD_RELOC_HPPA_PCREL_CALL_LD21, R_HPPA_PCREL_CALL_LD21,},
- {BFD_RELOC_HPPA_PCREL_CALL_RD11, R_HPPA_PCREL_CALL_RD11,},
- {BFD_RELOC_HPPA_PCREL_CALL_RD14, R_HPPA_PCREL_CALL_RD14,},
- {BFD_RELOC_HPPA_PCREL_CALL_RD17, R_HPPA_PCREL_CALL_RD17,},
- {BFD_RELOC_HPPA_PCREL_CALL_LR21, R_HPPA_PCREL_CALL_LR21,},
- {BFD_RELOC_HPPA_PCREL_CALL_RR14, R_HPPA_PCREL_CALL_RR14,},
- {BFD_RELOC_HPPA_PCREL_CALL_RR17, R_HPPA_PCREL_CALL_RR17,},
- {BFD_RELOC_HPPA_PLABEL_32, R_HPPA_PLABEL_32,},
- {BFD_RELOC_HPPA_PLABEL_11, R_HPPA_PLABEL_11,},
- {BFD_RELOC_HPPA_PLABEL_14, R_HPPA_PLABEL_14,},
- {BFD_RELOC_HPPA_PLABEL_L21, R_HPPA_PLABEL_L21,},
- {BFD_RELOC_HPPA_PLABEL_R11, R_HPPA_PLABEL_R11,},
- {BFD_RELOC_HPPA_PLABEL_R14, R_HPPA_PLABEL_R14,},
- {BFD_RELOC_HPPA_DLT_32, R_HPPA_DLT_32,},
- {BFD_RELOC_HPPA_DLT_11, R_HPPA_DLT_11,},
- {BFD_RELOC_HPPA_DLT_14, R_HPPA_DLT_14,},
- {BFD_RELOC_HPPA_DLT_L21, R_HPPA_DLT_L21,},
- {BFD_RELOC_HPPA_DLT_R11, R_HPPA_DLT_R11,},
- {BFD_RELOC_HPPA_DLT_R14, R_HPPA_DLT_R14,},
- {BFD_RELOC_HPPA_UNWIND_ENTRY, R_HPPA_UNWIND_ENTRY,},
- {BFD_RELOC_HPPA_UNWIND_ENTRIES, R_HPPA_UNWIND_ENTRIES,},
-};
-
static reloc_howto_type *
elf_hppa_reloc_type_lookup (arch, code)
bfd_arch_info_type *arch;
bfd_reloc_code_real_type code;
{
- int i;
-
if ((int) code < (int) R_HPPA_UNIMPLEMENTED)
{
BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
@@ -1783,8 +1690,14 @@ DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx),
}
}
-static symext_entryS *symextn_contents = NULL;
-static unsigned int symextn_contents_real_size = 0;
+/* Accessor function for the list of symbol extension records. */
+symext_chainS *elf32_hppa_get_symextn_chain()
+{
+ return symext_rootP;
+}
+
+static symext_entryS *symextn_contents;
+static unsigned int symextn_contents_real_size;
void
DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
@@ -1792,11 +1705,9 @@ DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
PTR ignored)
{
symext_chainS *symextP;
- symext_entryS *outbound_symexts;
int size;
int n;
int i;
- extern char *stub_section_contents; /* forward declaration */
void hppa_elf_stub_finish (); /* forward declaration */
asection *symextn_sec;
@@ -1894,6 +1805,9 @@ elf32_hppa_get_sym_extn (abfd, sym, type)
retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
break;
}
+ /* This should never happen. */
+ default:
+ abort();
}
return retval;
}
@@ -1919,7 +1833,7 @@ typedef struct Elf32_hppa_Stub_list_struct
struct Elf32_hppa_Stub_list_struct *next;
} Elf32_hppa_Stub_list;
-static Elf32_hppa_Stub_list *elf_hppa_stub_rootP = NULL;
+static Elf32_hppa_Stub_list *elf_hppa_stub_rootP;
/* Locate the stub section information for the given bfd. */
static Elf32_hppa_Stub_description *
@@ -1995,8 +1909,12 @@ add_stub (stub)
#define NO_ARG_RELOC 0
#define R_TO_FR 1
-#define FR_TO_R 2
-#define ARG_RELOC_ERR 3
+#define R01_TO_FR 2
+#define R23_TO_FR 3
+#define FR_TO_R 4
+#define FR_TO_R01 5
+#define FR_TO_R23 6
+#define ARG_RELOC_ERR 7
#define ARG0 0
#define ARG1 1
@@ -2008,34 +1926,55 @@ add_stub (stub)
#define AR_GR 1
#define AR_FR 2
#define AR_FU 3
+/* FP register in arg0/arg1. This value can only appear in the arg0 location. */
+#define AR_DBL01 4
+/* FP register in arg2/arg3. This value can only appear in the arg2 location. */
+#define AR_DBL23 5
+
+#define AR_WARN(type,loc) \
+ fprintf(stderr,"WARNING: Illegal argument relocation: %s for %s\n", \
+ reloc_type_strings[type],reloc_loc_strings[loc])
static CONST char *CONST reloc_type_strings[] =
{
- "NONE", "GR->FR", "FR->GR", "ERROR"
+ "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
+};
+
+static CONST char *CONST reloc_loc_strings[] =
+{
+ "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
};
-static CONST char mismatches[4][4] =
-{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU */
+static CONST char mismatches[6][6] =
+{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
/* CALLER NONE */
- {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC},
+ {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
/* CALLER GR */
- {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR},
+ {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
/* CALLER FR */
- {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+ {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR},
/* CALLER FU */
- {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+ {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
+ /* CALLER DBL01 */
+ {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
+ /* CALLER DBL23 */
+ {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
};
-static CONST char retval_mismatches[4][4] =
-{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU */
+static CONST char retval_mismatches[6][6] =
+{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
/* CALLER NONE */
- {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC},
+ {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
/* CALLER GR */
- {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR},
+ {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
/* CALLER FR */
- {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+ {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
/* CALLER FU */
- {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+ {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
+ /* CALLER DBL01 */
+ {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
+ /* CALLER DBL23 */
+ {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
};
static int
@@ -2057,13 +1996,16 @@ type_of_mismatch (caller_bits, callee_bits, type)
#define EXTRACT_ARBITS(ar,which) ((ar) >> (8-(which*2))) & 3
-#include "hppa_stubs.h"
-
#define NEW_INSTRUCTION(desc,insn) \
*((desc)->stub_secp)++ = (insn); \
(desc)->real_size += sizeof(int); \
bfd_set_section_size((desc)->this_bfd,(desc)->stub_sec,(desc)->real_size);
+#define CURRENT_STUB_OFFSET(desc) \
+ ((int)(desc)->stub_secp - (int)(desc)->stub_contents - 4)
+
+static boolean stubs_finished = false;
+
void
hppa_elf_stub_finish (output_bfd)
bfd *output_bfd;
@@ -2073,6 +2015,9 @@ hppa_elf_stub_finish (output_bfd)
/* All the stubs have been built. Finish up building */
/* stub section. Apply relocations to the section. */
+ if ( stubs_finished )
+ return;
+
for (; stub_list; stub_list = stub_list->next)
{
if (stub_list->stub->real_size)
@@ -2140,16 +2085,17 @@ hppa_elf_stub_finish (output_bfd)
free (reloc_vector);
}
}
+ stubs_finished = true;
}
void
hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */
output_bfd, /* the output bfd */
- stub_sym, /* the stub symbol */
+ target_sym, /* the target symbol */
offset) /* the offset within the stub buffer (pre-calculated) */
Elf32_hppa_Stub_description *stub_desc;
bfd *output_bfd;
- asymbol *stub_sym;
+ asymbol *target_sym;
int offset;
{
/* Allocate a new relocation entry. */
@@ -2179,8 +2125,61 @@ hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */
relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
BFD_ASSERT (relent.sym_ptr_ptr);
- relent.sym_ptr_ptr[0] = stub_sym;
- relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_ABS_CALL_17);
+ relent.sym_ptr_ptr[0] = target_sym;
+ relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_PCREL_CALL_17);
+
+ /* Save it in the array of relocations for the stub section. */
+
+ memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
+ &relent,
+ sizeof (arelent));
+}
+
+void
+hppa_elf_stub_reloc (stub_desc, /* the bfd */
+ output_bfd, /* the output bfd */
+ target_sym, /* the target symbol */
+ offset, /* the offset within the stub buffer (pre-calculated) */
+ type)
+Elf32_hppa_Stub_description *stub_desc;
+bfd *output_bfd;
+asymbol *target_sym;
+int offset;
+elf32_hppa_reloc_type type;
+{
+ /* Allocate a new relocation entry. */
+ arelent relent;
+ int size;
+ Elf_Internal_Shdr *rela_hdr;
+
+ if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
+ {
+ if (stub_desc->stub_sec->relocation == NULL)
+ {
+ stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
+ size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
+ stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
+ }
+ else
+ {
+ stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
+ size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
+ stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
+ size);
+ }
+ }
+
+ rela_hdr = &elf_section_data(stub_desc->stub_sec)->rel_hdr;
+ rela_hdr->sh_size += sizeof(Elf32_External_Rela);
+
+ /* Fill in the details. */
+ relent.address = offset;
+ relent.addend = 0;
+ relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
+ BFD_ASSERT (relent.sym_ptr_ptr);
+
+ relent.sym_ptr_ptr[0] = target_sym;
+ relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, type);
/* Save it in the array of relocations for the stub section. */
@@ -2199,6 +2198,7 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, stub_sec);
asymbol *stub_sym = NULL;
+ asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
int i;
char stub_sym_name[128];
@@ -2207,12 +2207,12 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
{
BFD_ASSERT (stub_desc == NULL);
stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
- bfd_set_section_flags (output_bfd,
+ bfd_set_section_flags (abfd,
stub_sec,
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_READONLY);
stub_sec->output_section = output_text_section->output_section;
stub_sec->output_offset = 0;
- bfd_set_section_alignment (output_bfd, stub_sec, 2);
+ bfd_set_section_alignment (abfd, stub_sec, 2);
stub_desc = new_stub (abfd, stub_sec);
add_stub (stub_desc);
}
@@ -2247,7 +2247,7 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
"_stub_%s_%02d_%02d_%02d_%02d_%02d\000",
reloc_entry->sym_ptr_ptr[0]->name,
stub_types[0], stub_types[1], stub_types[2], stub_types[3], stub_types[4]);
- stub_sym->name = bfd_zalloc (output_bfd, strlen (stub_sym_name) + 1);
+ stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
strcpy ((char *) stub_sym->name, stub_sym_name);
stub_sym->value = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
stub_sym->section = stub_sec;
@@ -2275,62 +2275,128 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
switch (i)
{
case ARG0:
- NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG0);
- NEW_INSTRUCTION (stub_desc, FSTWS_FARG0_M8SP);
+ NEW_INSTRUCTION (stub_desc, STWS_ARG0_M8SP);
+ NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG0);
break;
case ARG1:
- NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
- NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
break;
case ARG2:
- NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
- NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, STWS_ARG2_M8SP);
+ NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG2);
break;
case ARG3:
- NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
- NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, STWS_ARG3_M8SP);
+ NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG3);
break;
}
+ continue;
+
+ case R01_TO_FR:
+ switch (i)
+ {
+ case ARG0:
+ NEW_INSTRUCTION(stub_desc, STWS_ARG0_M4SP);
+ NEW_INSTRUCTION(stub_desc, STWS_ARG1_M8SP);
+ NEW_INSTRUCTION(stub_desc, FLDDS_M8SP_FARG1);
break;
+ default:
+ AR_WARN(stub_types[i],i);
+ break;
+ }
+ continue;
+
+ case R23_TO_FR:
+ switch (i)
+ {
+ case ARG2:
+ NEW_INSTRUCTION(stub_desc, STWS_ARG2_M4SP);
+ NEW_INSTRUCTION(stub_desc, STWS_ARG3_M8SP);
+ NEW_INSTRUCTION(stub_desc, FLDDS_M8SP_FARG3);
+ break;
+ default:
+ AR_WARN(stub_types[i],i);
+ break;
+ }
+ continue;
case FR_TO_R:
switch (i)
{
case ARG0:
- NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG0);
- NEW_INSTRUCTION (stub_desc, STWS_ARG0_M8SP);
+ NEW_INSTRUCTION (stub_desc, FSTWS_FARG0_M8SP);
+ NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG0);
break;
case ARG1:
- NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
- NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG1);
break;
case ARG2:
- NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
- NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, FSTWS_FARG2_M8SP);
+ NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG2);
break;
case ARG3:
- NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
- NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
+ NEW_INSTRUCTION (stub_desc, FSTWS_FARG3_M8SP);
+ NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG3);
break;
}
+ continue;
+
+ case FR_TO_R01:
+ switch (i)
+ {
+ case ARG0:
+ NEW_INSTRUCTION(stub_desc, FSTDS_FARG1_M8SP);
+ NEW_INSTRUCTION(stub_desc, LDWS_M4SP_ARG0);
+ NEW_INSTRUCTION(stub_desc, LDWS_M8SP_ARG1);
break;
+ default:
+ AR_WARN(stub_types[i],i);
+ break;
+ }
+ continue;
+ case FR_TO_R23:
+ switch (i)
+ {
+ case ARG2:
+ NEW_INSTRUCTION(stub_desc, FSTDS_FARG3_M8SP);
+ NEW_INSTRUCTION(stub_desc, LDWS_M4SP_ARG2);
+ NEW_INSTRUCTION(stub_desc, LDWS_M8SP_ARG3);
+ break;
+ default:
+ AR_WARN(stub_types[i],i);
+ break;
}
+ continue;
+
}
}
+ }
+
+ NEW_INSTRUCTION (stub_desc, ADDI_M8_SP);
/* generate the branch to the target routine */
NEW_INSTRUCTION (stub_desc, STW_RP_M8SP); /* First, save the return address */
- NEW_INSTRUCTION (stub_desc, BL_XXX_RP); /* set up a branch to the function */
-
- /* Fix the branch to the function. We can do this with a relocation. */
- hppa_elf_stub_branch_reloc (stub_desc,
- output_bfd, /* the output bfd */
- stub_sym, /* the stub symbol */
- (int) stub_desc->stub_secp - (int) stub_desc->stub_contents - 4); /* the offset within the stub buffer */
-
- NEW_INSTRUCTION (stub_desc, NOP);
+ /* Branch to the target function. */
+ /* (Make it a long call, so we do not */
+ /* have to worry about generating a */
+ /* long call stub.) */
+ NEW_INSTRUCTION(stub_desc, LDIL_XXX_31);
+ hppa_elf_stub_reloc (stub_desc,
+ abfd, /* the output bfd */
+ target_sym, /* the target symbol */
+ CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
+ R_HPPA_L21);
+ NEW_INSTRUCTION(stub_desc,BLE_XXX_0_31);
+ hppa_elf_stub_reloc (stub_desc,
+ abfd, /* the output bfd */
+ target_sym, /* the target symbol */
+ CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
+ R_HPPA_ABS_CALL_R17);
+ NEW_INSTRUCTION(stub_desc,COPY_31_2);
/* generate the code to move the return value around */
i = RETVAL;
@@ -2340,13 +2406,13 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
switch (stub_types[i])
{
case R_TO_FR:
- NEW_INSTRUCTION (stub_desc, LDWS_M8SP_RET0);
- NEW_INSTRUCTION (stub_desc, FSTWS_FRET0_M8SP);
+ NEW_INSTRUCTION (stub_desc, STWS_RET0_M8SP);
+ NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FRET0);
break;
case FR_TO_R:
- NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FRET0);
- NEW_INSTRUCTION (stub_desc, STWS_RET0_M8SP);
+ NEW_INSTRUCTION (stub_desc, FSTWS_FRET0_M8SP);
+ NEW_INSTRUCTION (stub_desc, LDWS_M4SP_RET0);
break;
}
}
@@ -2354,7 +2420,6 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
/* generate the ending common section for all stubs */
NEW_INSTRUCTION (stub_desc, LDW_M8SP_RP); /* restore return address */
- NEW_INSTRUCTION (stub_desc, SUBI_8_SP);
/* XXX: can we assume this is a save return? */
NEW_INSTRUCTION (stub_desc, BV_N_0RP);
@@ -2368,7 +2433,6 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
arelent *reloc_entry;
int stub_types[5];
{
- int i;
/* If the symbol is still undefined, there is */
/* no way to know if a stub is required. */
@@ -2407,22 +2471,22 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
{
- caller_loc[ARG0] = AR_FU;
+ caller_loc[ARG0] = AR_DBL01;
caller_loc[ARG1] = AR_NO;
}
if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
{
- caller_loc[ARG2] = AR_FU;
+ caller_loc[ARG2] = AR_DBL23;
caller_loc[ARG3] = AR_NO;
}
if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
{
- callee_loc[ARG0] = AR_FU;
+ callee_loc[ARG0] = AR_DBL01;
callee_loc[ARG1] = AR_NO;
}
if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
{
- callee_loc[ARG2] = AR_FU;
+ callee_loc[ARG2] = AR_DBL23;
callee_loc[ARG3] = AR_NO;
}
@@ -2432,10 +2496,7 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS);
stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE);
- /* XXX for now, just report a */
- /* warning */
-
- /* But, when we start building stubs, here are the steps involved: */
+ /* Steps involved in building stubs: */
/* 1. Determine what argument registers need to relocated. This */
/* step is already done here. */
/* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
@@ -2448,7 +2509,7 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
/* 4. Change the instruction of the original branch into a branch to */
/* the stub routine. */
/* 5. Build a relocation entry for the instruction of the original */
- /* branch to be R_HPPA_ABS_CALL to the stub routine. */
+ /* branch to be R_HPPA_PCREL_CALL to the stub routine. */
if (stub_types[0]
@@ -2483,10 +2544,243 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
}
asymbol *
-hppa_elf_stub_check (abfd, output_bfd, reloc_entry)
+hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
+ bfd *abfd;
+ bfd *output_bfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ unsigned *data;
+{
+ asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
+ Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, stub_sec);
+ asymbol *stub_sym = NULL;
+ asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
+ asymbol *return_sym = NULL;
+ asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
+ char stub_sym_name[128];
+ int milli = false;
+
+ if (!stub_sec)
+ {
+ BFD_ASSERT (stub_desc == NULL);
+ stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
+ bfd_set_section_flags (abfd,
+ stub_sec,
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_READONLY);
+ stub_sec->output_section = output_text_section->output_section;
+ stub_sec->output_offset = 0;
+ /* set up the ELF section header for this new section. */
+ /* This is basically the same processing as elf_make_sections() */
+ /* (elf_make_sections() is static so it is not accessible from */
+ /* here.) */
+
+ {
+ Elf_Internal_Shdr *this_hdr;
+ this_hdr = &elf_section_data (stub_sec)->this_hdr;
+
+ this_hdr->sh_addr = stub_sec->vma;
+ this_hdr->sh_size = stub_sec->_raw_size;
+ /* contents already set by elf_set_section_contents */
+
+ if (stub_sec->flags & SEC_RELOC)
+ {
+ /* emit a reloc section, and thus strtab and symtab... */
+ Elf_Internal_Shdr *rela_hdr;
+ int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
+
+ rela_hdr = &elf_section_data (stub_sec)->rel_hdr;
+
+ /* orelocation has the data, reloc_count has the count... */
+ if (use_rela_p)
+ {
+ rela_hdr->sh_type = SHT_RELA;
+ rela_hdr->sh_entsize = sizeof (Elf32_External_Rela);
+ }
+ else
+ /* REL relocations */
+ {
+ rela_hdr->sh_type = SHT_REL;
+ rela_hdr->sh_entsize = sizeof (Elf32_External_Rel);
+ }
+ rela_hdr->sh_flags = 0;
+ rela_hdr->sh_addr = 0;
+ rela_hdr->sh_offset = 0;
+ rela_hdr->sh_addralign = 0;
+ rela_hdr->size = 0;
+ }
+ if (stub_sec->flags & SEC_ALLOC)
+ {
+ this_hdr->sh_flags |= SHF_ALLOC;
+ if (stub_sec->flags & SEC_LOAD)
+ {
+ /* @@ Do something with sh_type? */
+ }
+ }
+ if (!(stub_sec->flags & SEC_READONLY))
+ this_hdr->sh_flags |= SHF_WRITE;
+
+ if (stub_sec->flags & SEC_CODE)
+ this_hdr->sh_flags |= SHF_EXECINSTR;
+ }
+
+ bfd_set_section_alignment (abfd, stub_sec, 2);
+ stub_desc = new_stub (abfd, stub_sec);
+ add_stub (stub_desc);
+ }
+
+ if (!stub_desc)
+ {
+ stub_desc = new_stub (abfd, stub_sec);
+ add_stub (stub_desc);
+ }
+
+ /* allocate some space to write the stub */
+
+ if (!stub_desc->stub_contents)
+ {
+ stub_desc->allocated_size = STUB_BUFFER_INCR;
+ stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR);
+ }
+ else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
+ {
+ stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
+ stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
+ stub_desc->allocated_size);
+ }
+
+ stub_desc->stub_secp = (int *) (stub_desc->stub_contents + stub_desc->real_size);
+
+ /* create a symbol to point to this stub */
+ stub_sym = bfd_make_empty_symbol (abfd);
+ sprintf (stub_sym_name,
+ "_lb_stub_%s\000", reloc_entry->sym_ptr_ptr[0]->name);
+ stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
+ strcpy ((char *) stub_sym->name, stub_sym_name);
+ stub_sym->value = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
+ stub_sym->section = stub_sec;
+ stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
+
+ /* create a symbol to point to the return location */
+ return_sym = bfd_make_empty_symbol (abfd);
+ sprintf (stub_sym_name,
+ "_lb_rtn_%s\000", reloc_entry->sym_ptr_ptr[0]->name);
+ return_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
+ strcpy ((char *) return_sym->name, stub_sym_name);
+ return_sym->value = reloc_entry->address + 8;
+ return_sym->section = stub_sec;
+ return_sym->flags = BSF_LOCAL | BSF_FUNCTION;
+
+ /* redirect the original relocation from the old symbol (a function) */
+ /* to the stub (the stub calls the function). */
+ /* XXX do we need to change the relocation type? */
+ reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
+ reloc_entry->sym_ptr_ptr[0] = stub_sym;
+ reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
+
+ /* Build the stub */
+
+ /* A millicode call? */
+ /* If so, the return address comes in on r31 rather than r2 (rp) so a */
+ /* slightly different code sequence is needed. */
+ if ( ((*data & 0x03e00000) >> 21) == 31 )
+ milli = true;
+
+ /* 1. initialization for the call. */
+
+ NEW_INSTRUCTION(stub_desc, LDSID_31_RP);
+ NEW_INSTRUCTION(stub_desc, MTSP_RP_SR0);
+ if ( !milli )
+ {
+ NEW_INSTRUCTION(stub_desc, COPY_31_2);
+
+ NEW_INSTRUCTION(stub_desc, LDIL_XXX_31);
+ hppa_elf_stub_reloc (stub_desc,
+ abfd, /* the output bfd */
+ target_sym, /* the target symbol */
+ CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
+ R_HPPA_L21);
+
+ /* 2. Make the call. */
+
+ NEW_INSTRUCTION(stub_desc,BE_N_XXX_0_31);
+ hppa_elf_stub_reloc (stub_desc,
+ abfd, /* the output bfd */
+ target_sym, /* the target symbol */
+ CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
+ R_HPPA_ABS_CALL_R17);
+ /* 3. Branch back to the original location. */
+ /* (accomplished with the COPY_31_2 instruction) */
+ }
+ else
+ {
+ NEW_INSTRUCTION(stub_desc, STW_31_M24SP);
+ NEW_INSTRUCTION(stub_desc, LDIL_XXX_RP);
+ hppa_elf_stub_reloc (stub_desc,
+ abfd, /* the output bfd */
+ target_sym, /* the target symbol */
+ CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
+ R_HPPA_L21);
+
+ /* 2. Make the call. */
+
+ NEW_INSTRUCTION(stub_desc,BLE_XXX_0_RP);
+ hppa_elf_stub_reloc (stub_desc,
+ abfd, /* the output bfd */
+ target_sym, /* the target symbol */
+ CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
+ R_HPPA_ABS_CALL_R17);
+ NEW_INSTRUCTION(stub_desc,COPY_31_2);
+
+ /* 3. Branch back to the original location. */
+ NEW_INSTRUCTION(stub_desc, LDW_M24SP_RP);
+ NEW_INSTRUCTION(stub_desc, BV_N_0RP);
+ }
+
+ return stub_sym;
+}
+
+int
+hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
+ bfd *abfd;
+ asection *asec;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ unsigned insn;
+{
+ long sym_value = get_symbol_value(symbol);
+ int fmt = reloc_entry->howto->bitsize;
+ unsigned char op = get_opcode(insn);
+ unsigned raddr;
+
+#define too_far(val,num_bits) ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
+
+ BFD_ASSERT(fmt == hppa_elf_insn2fmt(reloc_entry->howto->type,insn));
+
+ switch (op)
+ {
+ case BL:
+ raddr =
+ reloc_entry->address + asec->output_offset + asec->output_section->vma;
+ if ( too_far(sym_value - raddr,fmt+1) )
+ {
+#ifdef DETECT_STUBS
+ fprintf(stderr,"long_branch needed on BL insn: abfd=%s,sym=%s,distance=0x%x\n",abfd->filename,symbol->name,sym_value - reloc_entry->address);
+#endif
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
+asymbol *
+hppa_elf_stub_check (abfd, output_bfd, input_section, reloc_entry, symbol, hit_data)
bfd *abfd;
bfd *output_bfd;
+ asection *input_section;
arelent *reloc_entry;
+ asymbol *symbol;
+ bfd_byte *hit_data;
{
int stub_types[5];
@@ -2533,7 +2827,15 @@ hppa_elf_stub_check (abfd, output_bfd, reloc_entry)
if (hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types))
{
/* generate a stub */
- return hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types);
+ return hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
+ stub_types);
+ }
+ if (hppa_elf_long_branch_needed_p (abfd, input_section, reloc_entry, symbol,*(unsigned *)hit_data))
+ {
+ /* generate a stub */
+ return hppa_elf_build_long_branch_stub (abfd, output_bfd,
+ reloc_entry, symbol,
+ (unsigned *)hit_data);
}
break;
@@ -2547,7 +2849,8 @@ hppa_elf_stub_check (abfd, output_bfd, reloc_entry)
#define STUB_SYM_BUFFER_INC 5
asymbol *
-hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt)
+hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec, syms, new_sym_cnt)
+ bfd *stub_bfd;
bfd *abfd;
bfd *output_bfd;
asection *asec;
@@ -2628,13 +2931,44 @@ hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt)
{
/* generate a stub */
/* keep track of the new symbol */
+
+ asymbol *r;
+
if (new_cnt == new_max)
{
new_max += STUB_SYM_BUFFER_INC;
new_syms = (asymbol *) realloc (new_syms, new_max * sizeof (asymbol));
}
- new_syms[new_cnt++] = *(hppa_elf_build_arg_reloc_stub (abfd, output_bfd, rle, stub_types));
+ r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd, rle,
+ stub_types);
+ new_syms[new_cnt++] = *r;
}
+ /* We need to retrieve the section contents to check for */
+ /* long branch stubs. */
+ {
+ unsigned insn;
+
+ bfd_get_section_contents(abfd, asec, &insn, rle->address, sizeof(insn));
+ if (hppa_elf_long_branch_needed_p (abfd, asec, rle, rle->sym_ptr_ptr[0], insn))
+ {
+ /* generate a stub */
+ /* keep track of the new symbol */
+
+ asymbol *r;
+
+ if (new_cnt == new_max)
+ {
+ new_max += STUB_SYM_BUFFER_INC;
+ new_syms = (asymbol *) realloc (new_syms, new_max * sizeof (asymbol));
+ }
+ r = hppa_elf_build_long_branch_stub (stub_bfd,
+ output_bfd,
+ rle,
+ rle->sym_ptr_ptr[0],
+ &insn);
+ new_syms[new_cnt++] = *r;
+ }
+ }
break;
default:
@@ -2647,12 +2981,37 @@ hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt)
return new_syms;
}
-int
-hppa_look_for_stubs (abfd, output_bfd)
- bfd *abfd;
- bfd *output_bfd;
+
+char *linker_stubs = NULL;
+int linker_stubs_size = 0;
+int linker_stubs_max_size = 0;
+#define STUB_ALLOC_INCR 100
+
+boolean
+DEFUN (hppa_elf_set_section_contents, (abfd, section, location, offset, count),
+ bfd * abfd AND
+ sec_ptr section AND
+ PTR location AND
+ file_ptr offset AND
+ bfd_size_type count)
{
- /* bfd_map_over_sections(abfd,hppa_look_for_stubs_in_section,(PTR)output_bfd,NULL); */
+ if ( strcmp(section->name, ".hppa_linker_stubs") == 0 )
+ {
+ if ( linker_stubs_max_size < offset + count )
+ {
+ linker_stubs_max_size = offset + count + STUB_ALLOC_INCR;
+ linker_stubs = (char *)realloc(linker_stubs, linker_stubs_max_size);
+ }
+
+ if ( offset + count > linker_stubs_size )
+ linker_stubs_size = offset + count;
+
+ memcpy(linker_stubs + offset,location,count);
+ return (true);
+ }
+ else
+ return bfd_elf32_set_section_contents (abfd, section, location,
+ offset, count);
}
boolean
@@ -2703,9 +3062,281 @@ DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst),
arelent * cache_ptr AND
Elf32_Internal_Rela * dst)
{
- abort ();
+ BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED);
+ cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)];
+}
+
+static void
+DEFUN (elf32_hppa_backend_symbol_processing, (abfd, sym),
+ bfd * abfd AND
+ asymbol * sym)
+{
+ /* Is this a definition of $global$? If so, keep it because it will be
+ needed if any relocations are performed. */
+
+ if (!strcmp (sym->name, "$global$")
+ && sym->section != &bfd_und_section)
+ {
+ global_symbol = sym;
+ }
+}
+
+#define elf_backend_symbol_processing elf32_hppa_backend_symbol_processing
+
+struct elf32_hppa_symextn_map_struct
+{
+ int old_index;
+ bfd *bfd;
+ asymbol *sym;
+ int new_index;
+};
+
+static struct elf32_hppa_symextn_map_struct *elf32_hppa_symextn_map;
+static int elf32_hppa_symextn_map_size;
+
+static boolean
+DEFUN (elf32_hppa_backend_symbol_table_processing, (abfd, esyms,symcnt),
+ bfd * abfd AND
+ elf32_symbol_type *esyms AND
+ int symcnt)
+{
+ Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
+ int i;
+ int current_sym_idx = 0;
+
+ /* If the symbol extension section does not exist, all the symbol */
+ /* all the symbol extension information is assumed to be zero. */
+
+ if ( symextn_hdr == NULL )
+ {
+ for ( i = 0; i < symcnt; i++ )
+ {
+ esyms[i].tc_data.hppa_arg_reloc = 0;
+ }
+ return (true);
+ }
+
+ /* allocate a buffer of the appropriate size for the symextn section */
+
+ symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size);
+ symextn_hdr->size = symextn_hdr->sh_size;
+
+ /* read in the symextn section */
+
+ if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1)
+ {
+ bfd_error = system_call_error;
+ return (false);
+ }
+ if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->size, abfd)
+ != symextn_hdr->size)
+ {
+ free ((PTR)symextn_hdr->contents);
+ bfd_error = system_call_error;
+ return (false);
+ }
+
+ /* parse the entries, updating the symtab entries as we go */
+
+ for ( i = 0; i < symextn_hdr->size / sizeof(symext_entryS); i++ )
+ {
+ symext_entryS *seP = ((symext_entryS *)symextn_hdr->contents) + i;
+ int se_value = ELF32_HPPA_SX_VAL(*seP);
+ int se_type = ELF32_HPPA_SX_TYPE(*seP);
+
+ switch ( se_type )
+ {
+ case HPPA_SXT_NULL:
+ break;
+
+ case HPPA_SXT_SYMNDX:
+ if ( se_value >= symcnt )
+ {
+ bfd_error = bad_value;
+ bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
+ return (false);
+ }
+ current_sym_idx = se_value - 1;
+ break;
+
+ case HPPA_SXT_ARG_RELOC:
+ esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value;
+ break;
+
+ default:
+ bfd_error = bad_value;
+ bfd_perror("elf32_hppa_backend_symbol_table_processing");
+ return (false);
+ }
+ }
+ return (true);
+}
+
+#define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing
+
+static boolean
+DEFUN (elf32_hppa_backend_section_processing, (abfd, secthdr),
+ bfd * abfd AND
+ Elf32_Internal_Shdr *secthdr)
+{
+ int i,j,k;
+
+ if ( secthdr->sh_type == SHT_HPPA_SYMEXTN )
+ {
+ for ( i = 0; i < secthdr->size / sizeof(symext_entryS); i++ )
+ {
+ symext_entryS *seP = ((symext_entryS *)secthdr->contents) + i;
+ int se_value = ELF32_HPPA_SX_VAL(*seP);
+ int se_type = ELF32_HPPA_SX_TYPE(*seP);
+
+ switch ( se_type )
+ {
+ case HPPA_SXT_NULL:
+ break;
+
+ case HPPA_SXT_SYMNDX:
+ for ( j = 0; j < abfd->symcount; j++ )
+ {
+ /* locate the map entry for this symbol, if there is one. */
+ /* modify the symbol extension section symbol index entry */
+ /* to reflect the new symbol table index */
+
+ for ( k = 0; k < elf32_hppa_symextn_map_size; k++ )
+ {
+ if ( elf32_hppa_symextn_map[k].old_index == se_value
+ && elf32_hppa_symextn_map[k].bfd == abfd->outsymbols[j]->the_bfd
+ && elf32_hppa_symextn_map[k].sym == abfd->outsymbols[j] )
+ {
+ bfd_put_32(abfd,
+ ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, j),
+ (char *)seP);
+ }
+ }
+ }
+ break;
+
+ case HPPA_SXT_ARG_RELOC:
+ break;
+
+ default:
+ bfd_error = bad_value;
+ bfd_perror("elf32_hppa_backend_section_processing");
+ return (false);
+ }
+ }
+ }
+ return true;
+}
+
+#define elf_backend_section_processing elf32_hppa_backend_section_processing
+
+static boolean
+DEFUN (elf32_hppa_backend_section_from_shdr, (abfd, hdr, name),
+ bfd * abfd AND
+ Elf32_Internal_Shdr *hdr AND
+ char * name)
+{
+ asection *newsect;
+
+ if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
+ {
+ BFD_ASSERT ( strcmp(name,".hppa_symextn") == 0 );
+
+ /* Bits that get saved. This one is real. */
+ if (!hdr->rawdata)
+ {
+ newsect = bfd_make_section (abfd, name);
+ if (newsect != NULL)
+ {
+ newsect->vma = hdr->sh_addr;
+ newsect->_raw_size = hdr->sh_size;
+ newsect->filepos = hdr->sh_offset; /* so we can read back the bits */
+ newsect->flags |= SEC_HAS_CONTENTS;
+ newsect->alignment_power = hdr->sh_addralign;
+
+ if (hdr->sh_flags & SHF_ALLOC)
+ {
+ newsect->flags |= SEC_ALLOC;
+ newsect->flags |= SEC_LOAD;
+ }
+
+ if (!(hdr->sh_flags & SHF_WRITE))
+ newsect->flags |= SEC_READONLY;
+
+ if (hdr->sh_flags & SHF_EXECINSTR)
+ newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
+ else
+ newsect->flags |= SEC_DATA;
+
+ hdr->rawdata = (void *) newsect;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+#define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr
+
+static boolean
+DEFUN (elf32_hppa_backend_fake_sections, (abfd, secthdr, asect),
+ bfd * abfd AND
+ Elf_Internal_Shdr *secthdr AND
+ asection *asect)
+{
+
+ if ( strcmp(asect->name, ".hppa_symextn") == 0 )
+ {
+ secthdr->sh_type = SHT_HPPA_SYMEXTN;
+ secthdr->sh_flags = 0;
+ secthdr->sh_info = elf_section_data(asect)->rel_hdr.sh_link;
+ secthdr->sh_link = elf_onesymtab(abfd);
+ return true;
+ }
+
+ if (!strcmp (asect->name, ".hppa_unwind"))
+ {
+ secthdr->sh_type = SHT_PROGBITS;
+ /* Unwind descriptors are not part of the program memory image. */
+ secthdr->sh_flags = 0;
+ secthdr->sh_info = 0;
+ secthdr->sh_link = 0;
+ secthdr->sh_entsize = 16;
+ return true;
+ }
+
+ return false;
+}
+
+#define elf_backend_fake_sections elf32_hppa_backend_fake_sections
+
+static boolean
+DEFUN (elf32_hppa_backend_section_from_bfd_section, (abfd, hdr, asect),
+ bfd *abfd AND
+ Elf32_Internal_Shdr *hdr AND
+ asection *asect)
+{
+
+ if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
+ {
+ if (hdr->rawdata)
+ {
+ if (((struct sec *) (hdr->rawdata)) == asect)
+ {
+ BFD_ASSERT( strcmp(asect->name, ".hppa_symextn") == 0 );
+ return true;
+ }
+ }
+ }
+
+ return false;
}
+#define elf_backend_section_from_bfd_section elf32_hppa_backend_section_from_bfd_section
+
+#define bfd_generic_get_section_contents hppa_elf_get_section_contents
+#define bfd_elf32_set_section_contents hppa_elf_set_section_contents
+
#define TARGET_BIG_SYM bfd_elf32_hppa_vec
#define TARGET_BIG_NAME "elf32-hppa"
#define ELF_ARCH bfd_arch_hppa
diff --git a/bfd/elf32-hppa.h b/bfd/elf32-hppa.h
index e392eeb..77d5827 100644
--- a/bfd/elf32-hppa.h
+++ b/bfd/elf32-hppa.h
@@ -288,6 +288,7 @@ typedef enum
R_HPPA_EXPR_14, /* pop - 14 */
R_HPPA_EXPR_17, /* pop - 17 */
R_HPPA_EXPR_12, /* pop - 12 */
+ R_HPPA_STUB_CALL_17, /* Symbol + Addend 17 */
R_HPPA_UNIMPLEMENTED /* N/A */
} elf32_hppa_reloc_type;
@@ -308,50 +309,6 @@ typedef enum
#define R_HPPA_COMPLEX_ABS_CALL R_HPPA_PUSH_CONST + 2
-enum hppa_reloc_field_selector_type
-{
- R_HPPA_FSEL = 0x0,
- R_HPPA_LSSEL = 0x1,
- R_HPPA_RSSEL = 0x2,
- R_HPPA_LSEL = 0x3,
- R_HPPA_RSEL = 0x4,
- R_HPPA_LDSEL = 0x5,
- R_HPPA_RDSEL = 0x6,
- R_HPPA_LRSEL = 0x7,
- R_HPPA_RRSEL = 0x8,
- R_HPPA_PSEL = 0x9, /* P' : procedure address for shlib's */
- R_HPPA_LPSEL = 0xa, /* LP' : L' for procedure addresses */
- R_HPPA_RPSEL = 0xb, /* RP' : R' for procedure addresses */
-
- R_HPPA_TSEL = 0xc, /* T' : DLT-relative offset for shlib's */
- R_HPPA_LTSEL = 0xd, /* LT' : L' for DLT-relative offsets */
- R_HPPA_RTSEL = 0xe /* RT' : R' for DLT-relative offsets */
-
-};
-
-#define N_HPPA_FIELD_SELECTORS 15
-
-/* for compatibility */
-enum hppa_reloc_field_selector_type_alt
-{
- e_fsel = R_HPPA_FSEL,
- e_lssel = R_HPPA_LSSEL,
- e_rssel = R_HPPA_RSSEL,
- e_lsel = R_HPPA_LSEL,
- e_rsel = R_HPPA_RSEL,
- e_ldsel = R_HPPA_LDSEL,
- e_rdsel = R_HPPA_RDSEL,
- e_lrsel = R_HPPA_LRSEL,
- e_rrsel = R_HPPA_RRSEL,
- e_psel = R_HPPA_PSEL, /* P' : procedure address for shlib's */
- e_lpsel = R_HPPA_LPSEL, /* LP' : L' for procedure addresses */
- e_rpsel = R_HPPA_RPSEL, /* RP' : R' for procedure addresses */
-
- e_tsel = R_HPPA_TSEL, /* T' : DLT-relative offset for shlib's */
- e_ltsel = R_HPPA_LTSEL, /* LT' : L' for DLT-relative offsets */
- e_rtsel = R_HPPA_RTSEL /* RT' : R' for DLT-relative offsets */
-};
-
/* PA-RISC OPCODES */
#define get_opcode(insn) ((insn) & 0xfc000000) >> 26
@@ -445,8 +402,8 @@ elf32_hppa_reloc_type **hppa_elf_gen_reloc_type ();
#define ELF_TC_FAKE_SECTIONS 1 /* # of "hand_made" tc-specific sections */
#define SYMEXTN_SECTION_NAME ".hppa_symextn"
-extern void EXFUN (elf_hppa_tc_symbol, (bfd *, elf32_symbol_type *, int));
-extern void EXFUN (elf_hppa_tc_make_sections, (bfd *, PTR));
+extern void elf_hppa_tc_symbol PARAMS ((bfd *, elf32_symbol_type *, int));
+extern void elf_hppa_tc_make_sections PARAMS ((bfd *, PTR));
typedef Elf32_Word symext_entryS;
@@ -458,7 +415,4 @@ struct symext_chain
typedef struct symext_chain symext_chainS;
-extern symext_chainS *symext_rootP;
-extern symext_chainS *symext_lastP;
-
#endif /* _ELF32_HPPA_H */
diff --git a/bfd/libhppa.h b/bfd/libhppa.h
index cf69813..14c8899 100644
--- a/bfd/libhppa.h
+++ b/bfd/libhppa.h
@@ -4,213 +4,319 @@
Contributed by the Center for Software Science at the
University of Utah (pa-gdb-bugs@cs.utah.edu).
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#ifndef _LIBHPPA_H
-#define _LIBHPPA_H
+#ifndef _HPPA_H
+#define _HPPA_H
-#include "../bfd/sysdep.h"
-
-#ifdef HOST_HPPAHPUX
-
-#include <sys/core.h>
-#include <sys/utsname.h>
+#define BYTES_IN_WORD 4
-#endif /* HOST_HPPAHPUX */
+#ifndef INLINE
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif /* GNU C? */
+#endif /* INLINE */
-#ifdef HOST_HPPABSD
+/* HP PA-RISC relocation types */
-/* BSD uses a completely different scheme for object file identification.
- so for now, define _PA_RISC_ID to accept any random value for a model
- number. */
+enum hppa_reloc_field_selector_type
+ {
+ R_HPPA_FSEL = 0x0,
+ R_HPPA_LSSEL = 0x1,
+ R_HPPA_RSSEL = 0x2,
+ R_HPPA_LSEL = 0x3,
+ R_HPPA_RSEL = 0x4,
+ R_HPPA_LDSEL = 0x5,
+ R_HPPA_RDSEL = 0x6,
+ R_HPPA_LRSEL = 0x7,
+ R_HPPA_RRSEL = 0x8,
+ R_HPPA_PSEL = 0x9,
+ R_HPPA_LPSEL = 0xa,
+ R_HPPA_RPSEL = 0xb,
+ R_HPPA_TSEL = 0xc,
+ R_HPPA_LTSEL = 0xd,
+ R_HPPA_RTSEL = 0xe
+ };
-#include <a.out.h>
+/* for compatibility */
+enum hppa_reloc_field_selector_type_alt
+ {
+ e_fsel = R_HPPA_FSEL,
+ e_lssel = R_HPPA_LSSEL,
+ e_rssel = R_HPPA_RSSEL,
+ e_lsel = R_HPPA_LSEL,
+ e_rsel = R_HPPA_RSEL,
+ e_ldsel = R_HPPA_LDSEL,
+ e_rdsel = R_HPPA_RDSEL,
+ e_lrsel = R_HPPA_LRSEL,
+ e_rrsel = R_HPPA_RRSEL,
+ e_psel = R_HPPA_PSEL,
+ e_lpsel = R_HPPA_LPSEL,
+ e_rpsel = R_HPPA_RPSEL,
+ e_tsel = R_HPPA_TSEL,
+ e_ltsel = R_HPPA_LTSEL,
+ e_rtsel = R_HPPA_RTSEL
+ };
-/* Not a very swift place to put it, but that's where the BSD port
- puts them. */
-#include "/hpux/usr/include/sys/core.h"
-#ifndef _PA_RISC_ID
-#define _PA_RISC_ID(__m_num) 1
-#endif
+enum hppa_reloc_expr_type
+ {
+ R_HPPA_E_ONE = 0,
+ R_HPPA_E_TWO = 1,
+ R_HPPA_E_PCREL = 2,
+ R_HPPA_E_CON = 3,
+ R_HPPA_E_PLABEL = 7,
+ R_HPPA_E_ABS = 18
+ };
-#endif /* HOST_HPPABSD */
+/* for compatibility */
+enum hppa_reloc_expr_type_alt
+ {
+ e_one = R_HPPA_E_ONE,
+ e_two = R_HPPA_E_TWO,
+ e_pcrel = R_HPPA_E_PCREL,
+ e_con = R_HPPA_E_CON,
+ e_plabel = R_HPPA_E_PLABEL,
+ e_abs = R_HPPA_E_ABS
+ };
+
+
+/* Some functions to manipulate PA instructions. */
+static INLINE unsigned int
+assemble_3 (x)
+ unsigned int x;
+{
+ return (((x & 1) << 2) | ((x & 6) >> 1)) & 7;
+}
-/* Defining MAXCOMLEN avoids bringing in several (7 or 8) otherwise
- useless include files which tend to clutter up the namespace. */
+static INLINE void
+dis_assemble_3 (x, r)
+ unsigned int x;
+ unsigned int *r;
+{
+ *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
+}
-#define MAXCOMLEN 16
+static INLINE unsigned int
+assemble_12 (x, y)
+ unsigned int x, y;
+{
+ return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff;
+}
-#define BYTES_IN_WORD 4
+static INLINE void
+dis_assemble_12 (as12, x, y)
+ unsigned int as12;
+ unsigned int *x, *y;
+{
+ *y = (as12 & 0x800) >> 11;
+ *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
+}
-struct header;
-struct som_exec_auxhdr;
-struct subspace_dictionary;
+static INLINE unsigned long
+assemble_17 (x, y, z)
+ unsigned int x, y, z;
+{
+ unsigned long temp;
+
+ temp = ((z & 1) << 16) |
+ ((x & 0x1f) << 11) |
+ ((y & 1) << 10) |
+ ((y & 0x7fe) >> 1);
+ return temp & 0x1ffff;
+}
+
+static INLINE void
+dis_assemble_17 (as17, x, y, z)
+ unsigned int as17;
+ unsigned int *x, *y, *z;
+{
-#define FILE_HDR_SIZE sizeof(struct header)
-#define AUX_HDR_SIZE sizeof(struct som_exec_auxhdr)
+ *z = (as17 & 0x10000) >> 16;
+ *x = (as17 & 0x0f800) >> 11;
+ *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
+}
-typedef struct hppa_symbol
+static INLINE unsigned long
+assemble_21 (x)
+ unsigned int x;
{
- asymbol symbol;
- short desc;
- char other;
- unsigned char type;
-} hppa_symbol_type;
-
-struct hppadata
+ unsigned long temp;
+
+ temp = ((x & 1) << 20) |
+ ((x & 0xffe) << 8) |
+ ((x & 0xc000) >> 7) |
+ ((x & 0x1f0000) >> 14) |
+ ((x & 0x003000) >> 12);
+ return temp & 0x1fffff;
+}
+
+static INLINE void
+dis_assemble_21 (as21, x)
+ unsigned int as21, *x;
{
- struct header *file_hdr;
- struct som_exec_auxhdr *aux_hdr;
- hppa_symbol_type *symbols;
+ unsigned long temp;
- /* We remember these offsets so that after check_file_format, we have
- no dependencies on the particular format of the exec_hdr. */
- file_ptr sym_filepos;
- file_ptr str_filepos;
+ temp = (as21 & 0x100000) >> 20;
+ temp |= (as21 & 0x0ffe00) >> 8;
+ temp |= (as21 & 0x000180) << 7;
+ temp |= (as21 & 0x00007c) << 14;
+ temp |= (as21 & 0x000003) << 12;
+ *x = temp;
+}
- unsigned stringtab_size;
+static INLINE unsigned long
+sign_ext (x, len)
+ unsigned int x, len;
+{
+ return (x << (32 - len)) >> (32 - len);
+}
- /* Size of a symbol table entry in external form */
- unsigned hp_symbol_entry_size;
-};
+static INLINE unsigned int
+ones (n)
+ int n;
+{
+ unsigned int len_ones;
+ int i;
+
+ i = 0;
+ len_ones = 0;
+ while (i < n)
+ {
+ len_ones = (len_ones << 1) | 1;
+ i++;
+ }
+
+ return len_ones;
+}
+
+static INLINE void
+sign_unext (x, len, result)
+ unsigned int x, len;
+ unsigned int *result;
+{
+ unsigned int len_ones;
-struct hppa_data_struct {
- struct hppadata a;
-};
+ len_ones = ones (len);
-#define padata(bfd) ((bfd)->tdata.hppa_data->a)
-#define obj_file_hdr(bfd) (padata(bfd).file_hdr)
-#define obj_aux_hdr(bfd) (padata(bfd).aux_hdr)
-#define obj_pa_symbols(bfd) (padata(bfd).symbols)
-#define obj_sym_filepos(bfd) (padata(bfd).sym_filepos)
-#define obj_str_filepos(bfd) (padata(bfd).str_filepos)
-#define obj_stringtab_size(bfd) (padata(bfd).stringtab_size)
+ *result = x & len_ones;
+}
-/* We take the address of the first element of an asymbol to ensure that the
- macro is only ever applied to an asymbol */
-#define hppa_symbol(asymbol) ((hppa_symbol_type *)(&(asymbol)->the_bfd))
+static INLINE unsigned long
+low_sign_ext (x, len)
+ unsigned int x, len;
+{
+ unsigned int temp1, temp2;
+ unsigned int len_ones;
+ len_ones = ones (len);
-/* These are stored in the bfd's tdata */
+ temp1 = (x & 1) << (len - 1);
+ temp2 = ((x & 0xfffffffe) & len_ones) >> 1;
+ return sign_ext ((temp1 | temp2), len);
+}
-struct hppa_core_struct
+static INLINE void
+low_sign_unext (x, len, result)
+ unsigned int x, len;
+ unsigned int *result;
{
- int sig;
- char cmd[MAXCOMLEN + 1];
- asection *data_section;
- asection *stack_section;
- asection *reg_section;
-};
-
-#define core_hdr(bfd) ((bfd)->tdata.hppa_core_data)
-#define core_signal(bfd) (core_hdr(bfd)->sig)
-#define core_command(bfd) (core_hdr(bfd)->cmd)
-#define core_datasec(bfd) (core_hdr(bfd)->data_section)
-#define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
-#define core_regsec(bfd) (core_hdr(bfd)->reg_section)
+ unsigned int temp;
+ unsigned int sign;
+ unsigned int rest;
+ unsigned int one_bit_at_len;
+ unsigned int len_ones;
-/* HP PA-RISC relocation types */
+ len_ones = ones (len);
+ one_bit_at_len = 1 << (len - 1);
-enum hppa_reloc_field_selector_type
-{
- R_HPPA_FSEL = 0x0,
- R_HPPA_LSSEL = 0x1,
- R_HPPA_RSSEL = 0x2,
- R_HPPA_LSEL = 0x3,
- R_HPPA_RSEL = 0x4,
- R_HPPA_LDSEL = 0x5,
- R_HPPA_RDSEL = 0x6,
- R_HPPA_LRSEL = 0x7,
- R_HPPA_RRSEL = 0x8,
- R_HPPA_PSEL = 0x9, /* P' : procedure address for shlib's */
- R_HPPA_LPSEL = 0xa, /* LP' : L' for procedure addresses */
- R_HPPA_RPSEL = 0xb, /* RP' : R' for procedure addresses */
-
- R_HPPA_TSEL = 0xc, /* T' : DLT-relative offset for shlib's */
- R_HPPA_LTSEL = 0xd, /* LT' : L' for DLT-relative offsets */
- R_HPPA_RTSEL = 0xe /* RT' : R' for DLT-relative offsets */
-
-};
-
-/* Need to undefine things defined in <machine/som.h> */
-
-#undef e_fsel
-#undef e_lssel
-#undef e_rssel
-#undef e_lsel
-#undef e_rsel
-#undef e_ldsel
-#undef e_rdsel
-#undef e_lrsel
-#undef e_rrsel
-#undef e_psel
-#undef e_lpsel
-#undef e_rpsel
-#undef e_tsel
-#undef e_ltsel
-#undef e_rtsel
-#undef e_one
-#undef e_two
-#undef e_pcrel
-#undef e_con
-#undef e_plabel
-#undef e_abs
+ sign_unext (x, len, &temp);
+ sign = temp & one_bit_at_len;
+ sign >>= (len - 1);
-/* for compatibility */
-enum hppa_reloc_field_selector_type_alt
-{
- e_fsel = R_HPPA_FSEL,
- e_lssel = R_HPPA_LSSEL,
- e_rssel = R_HPPA_RSSEL,
- e_lsel = R_HPPA_LSEL,
- e_rsel = R_HPPA_RSEL,
- e_ldsel = R_HPPA_LDSEL,
- e_rdsel = R_HPPA_RDSEL,
- e_lrsel = R_HPPA_LRSEL,
- e_rrsel = R_HPPA_RRSEL,
- e_psel = R_HPPA_PSEL, /* P' : procedure address for shlib's */
- e_lpsel = R_HPPA_LPSEL, /* LP' : L' for procedure addresses */
- e_rpsel = R_HPPA_RPSEL, /* RP' : R' for procedure addresses */
-
- e_tsel = R_HPPA_TSEL, /* T' : DLT-relative offset for shlib's */
- e_ltsel = R_HPPA_LTSEL, /* LT' : L' for DLT-relative offsets */
- e_rtsel = R_HPPA_RTSEL /* RT' : R' for DLT-relative offsets */
-};
+ rest = temp & (len_ones ^ one_bit_at_len);
+ rest <<= 1;
-enum hppa_reloc_expr_type
-{
- R_HPPA_E_ONE = 0,
- R_HPPA_E_TWO = 1,
- R_HPPA_E_PCREL = 2,
- R_HPPA_E_CON = 3,
- R_HPPA_E_PLABEL = 7,
- R_HPPA_E_ABS = 18
-};
+ *result = rest | sign;
+}
-/* for compatibility */
-enum hppa_reloc_expr_type_alt
+/* Handle field selectors for PA instructions. */
+
+static INLINE unsigned long
+hppa_field_adjust (value, constant_value, r_field)
+ unsigned long value;
+ unsigned long constant_value;
+ unsigned short r_field;
{
- e_one = R_HPPA_E_ONE,
- e_two = R_HPPA_E_TWO,
- e_pcrel = R_HPPA_E_PCREL,
- e_con = R_HPPA_E_CON,
- e_plabel = R_HPPA_E_PLABEL,
- e_abs = R_HPPA_E_ABS
-};
-
-#endif /* _LIBHPPA_H */
+ unsigned long init_value = value;
+ value += constant_value;
+ switch (r_field)
+ {
+ case e_fsel: /* F : no change */
+ break;
+
+ case e_lssel: /* LS : if (bit 21) then add 0x800
+ arithmetic shift right 11 bits */
+ if (value & 0x00000400)
+ value += 0x800;
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rssel: /* RS : Sign extend from bit 21 */
+ if (value & 0x00000400)
+ value |= 0xfffff800;
+ else
+ value &= 0x7ff;
+ break;
+
+ case e_lsel: /* L : Arithmetic shift right 11 bits */
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rsel: /* R : Set bits 0-20 to zero */
+ value = value & 0x7ff;
+ break;
+
+ case e_ldsel: /* LD : Add 0x800, arithmetic shift
+ right 11 bits */
+ value += 0x800;
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rdsel: /* RD : Set bits 0-20 to one */
+ value |= 0xfffff800;
+ break;
+
+ case e_lrsel: /* LR : L with "rounded" constant */
+ value = value + ((constant_value + 0x1000) & 0xffffe000);
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rrsel: /* RR : R with "rounded" constant */
+ value = value + ((constant_value + 0x1000) & 0xffffe000);
+ value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
+ break;
+
+ default:
+ abort ();
+ }
+ return value;
+
+}
+#endif /* _HPPA_H */
diff --git a/bfd/som.c b/bfd/som.c
new file mode 100644
index 0000000..8fd1324
--- /dev/null
+++ b/bfd/som.c
@@ -0,0 +1,602 @@
+/* bfd back-end for HP PA-RISC SOM objects.
+ Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+/* @@FIXME This is not a reasonable set of conditions to permit
+ cross-compilation, obviously. It also isn't enough to support hppa-elf
+ targets either. Can we eliminate the HPUX or BSD dependencies, or
+ at least get the conditionals more localized? */
+#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
+
+#include "libbfd.h"
+#include "som.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <machine/reg.h>
+#include <sys/user.h> /* After a.out.h */
+#include <sys/file.h>
+#include <errno.h>
+
+/* Magic not defined in standard HP-UX header files until 8.0 */
+
+#ifndef CPU_PA_RISC1_0
+#define CPU_PA_RISC1_0 0x20B
+#endif /* CPU_PA_RISC1_0 */
+
+#ifndef CPU_PA_RISC1_1
+#define CPU_PA_RISC1_1 0x210
+#endif /* CPU_PA_RISC1_1 */
+
+#ifndef _PA_RISC1_0_ID
+#define _PA_RISC1_0_ID CPU_PA_RISC1_0
+#endif /* _PA_RISC1_0_ID */
+
+#ifndef _PA_RISC1_1_ID
+#define _PA_RISC1_1_ID CPU_PA_RISC1_1
+#endif /* _PA_RISC1_1_ID */
+
+#ifndef _PA_RISC_MAXID
+#define _PA_RISC_MAXID 0x2FF
+#endif /* _PA_RISC_MAXID */
+
+#ifndef _PA_RISC_ID
+#define _PA_RISC_ID(__m_num) \
+ (((__m_num) == _PA_RISC1_0_ID) || \
+ ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
+#endif /* _PA_RISC_ID */
+
+struct container
+ {
+ struct header f;
+ struct som_exec_auxhdr e;
+ };
+
+static bfd_target *
+hppa_object_setup (abfd, file_hdrp, aux_hdrp)
+ bfd *abfd;
+ struct header *file_hdrp;
+ struct som_exec_auxhdr *aux_hdrp;
+{
+ struct container *rawptr;
+ struct header *f;
+ struct hppa_data_struct *rawptr1;
+ asection *text, *data, *bss;
+
+ rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
+ if (rawptr == NULL)
+ {
+ bfd_error = no_memory;
+ return 0;
+ }
+
+ rawptr1 = (struct hppa_data_struct *) bfd_zalloc (abfd, sizeof (struct hppa_data_struct));
+ if (rawptr1 == NULL)
+ {
+ bfd_error = no_memory;
+ return 0;
+ }
+
+ abfd->tdata.hppa_data = rawptr1;
+ obj_file_hdr (abfd) = &rawptr->f;
+ obj_aux_hdr (abfd) = &rawptr->e;
+ *obj_file_hdr (abfd) = *file_hdrp;
+ *obj_aux_hdr (abfd) = *aux_hdrp;
+
+ /* Set the file flags */
+ abfd->flags = NO_FLAGS;
+ if (file_hdrp->entry_offset)
+ abfd->flags |= HAS_RELOC;
+ if (file_hdrp->symbol_total)
+ abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
+
+ bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
+
+ obj_pa_symbols (abfd) = (hppa_symbol_type *) NULL;
+ bfd_get_symcount (abfd) = file_hdrp->symbol_total;
+
+ bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
+
+ /* create the sections. This is raunchy, but bfd_close wants to reclaim
+ them */
+
+ text = bfd_make_section (abfd, ".text");
+ data = bfd_make_section (abfd, ".data");
+ bss = bfd_make_section (abfd, ".bss");
+
+ text->_raw_size = aux_hdrp->exec_tsize;
+ data->_raw_size = aux_hdrp->exec_dsize;
+ bss->_raw_size = aux_hdrp->exec_bsize;
+
+ text->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
+ data->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
+ bss->flags = (SEC_ALLOC | SEC_IS_COMMON);
+
+ /* The virtual memory addresses of the sections */
+ text->vma = aux_hdrp->exec_tmem;
+ data->vma = aux_hdrp->exec_dmem;
+ bss->vma = aux_hdrp->exec_bfill;
+
+ /* The file offsets of the sections */
+ text->filepos = aux_hdrp->exec_tfile;
+ data->filepos = aux_hdrp->exec_dfile;
+
+ /* The file offsets of the relocation info */
+ text->rel_filepos = 0;
+ data->rel_filepos = 0;
+
+ /* The file offsets of the string table and symbol table. */
+ obj_sym_filepos (abfd) = file_hdrp->symbol_location;
+ bfd_get_symcount (abfd) = file_hdrp->symbol_total;
+ obj_str_filepos (abfd) = file_hdrp->symbol_strings_location;
+ obj_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
+
+ return abfd->xvec;
+}
+
+/* Create a new BFD section for NAME. If NAME already exists, then create a
+ new unique name, with NAME as the prefix. This exists because SOM .o files
+ created by the native compiler can have a $CODE$ section for each
+ subroutine.
+ */
+
+static asection *
+make_unique_section (abfd, name, num)
+ bfd *abfd;
+ CONST char *name;
+ int num;
+{
+ asection *sect;
+ char *newname;
+ char altname[100];
+
+ sect = bfd_make_section (abfd, name);
+ while (!sect)
+ {
+ sprintf (altname, "%s-%d", name, num++);
+ sect = bfd_make_section (abfd, altname);
+ }
+
+ newname = bfd_alloc (abfd, strlen (sect->name) + 1);
+ strcpy (newname, sect->name);
+
+ sect->name = newname;
+ return sect;
+}
+
+/* Convert all of the space and subspace info into BFD sections. Each space
+ contains a number of subspaces, which in turn describe the mapping between
+ regions of the exec file, and the address space that the program runs in.
+ BFD sections which correspond to spaces will overlap the sections for the
+ associated subspaces. */
+
+static int
+setup_sections (abfd, file_hdr)
+ bfd *abfd;
+ struct header *file_hdr;
+{
+ char *space_strings;
+ int space_index;
+
+ /* First, read in space names */
+
+ space_strings = alloca (file_hdr->space_strings_size);
+ if (!space_strings)
+ return 0;
+
+ if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
+ return 0;
+ if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
+ != file_hdr->space_strings_size)
+ return 0;
+
+ /* Loop over all of the space dictionaries, building up sections */
+
+ for (space_index = 0; space_index < file_hdr->space_total; space_index++)
+ {
+ struct space_dictionary_record space;
+ struct subspace_dictionary_record subspace;
+ int subspace_index, tmp;
+ asection *space_asect;
+
+ /* Read the space dictionary element */
+ if (bfd_seek (abfd, file_hdr->space_location
+ + space_index * sizeof space, SEEK_SET) < 0)
+ return 0;
+ if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
+ return 0;
+
+ /* Setup the space name string */
+ space.name.n_name = space.name.n_strx + space_strings;
+
+ /* Make a section out of it */
+ space_asect = make_unique_section (abfd, space.name.n_name, space_index);
+ if (!space_asect)
+ return 0;
+
+ /* Now, read in the first subspace for this space */
+ if (bfd_seek (abfd, file_hdr->subspace_location
+ + space.subspace_index * sizeof subspace,
+ SEEK_SET) < 0)
+ return 0;
+ if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
+ return 0;
+ /* Seek back to the start of the subspaces for loop below */
+ if (bfd_seek (abfd, file_hdr->subspace_location
+ + space.subspace_index * sizeof subspace,
+ SEEK_SET) < 0)
+ return 0;
+
+ /* Setup the section flags as appropriate (this is somewhat bogus, as
+ there isn't a clear mapping between what's in the space record, and
+ what BFD can describe here). */
+ if (space.is_loadable)
+ space_asect->flags |= SEC_ALLOC;
+ if (space.is_defined)
+ space_asect->flags |= SEC_LOAD;
+
+ /* Setup the start address and file loc from the first subspace record */
+ space_asect->vma = subspace.subspace_start;
+ space_asect->filepos = subspace.file_loc_init_value;
+ space_asect->alignment_power = subspace.alignment;
+
+ /* Loop over the rest of the subspaces, building up more sections */
+ for (subspace_index = 0; subspace_index < space.subspace_quantity;
+ subspace_index++)
+ {
+ asection *subspace_asect;
+
+ /* Read in the next subspace */
+ if (bfd_read (&subspace, 1, sizeof subspace, abfd)
+ != sizeof subspace)
+ return 0;
+
+ /* Setup the subspace name string */
+ subspace.name.n_name = subspace.name.n_strx + space_strings;
+
+ /* Make a section out of this subspace */
+ subspace_asect = make_unique_section (abfd, subspace.name.n_name,
+ space.subspace_index + subspace_index);
+
+ if (!subspace_asect)
+ return 0;
+
+ if (subspace.is_loadable)
+ subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
+ if (subspace.code_only)
+ subspace_asect->flags |= SEC_CODE;
+
+ subspace_asect->vma = subspace.subspace_start;
+ subspace_asect->_cooked_size = subspace.subspace_length;
+ subspace_asect->_raw_size = subspace.initialization_length;
+ subspace_asect->alignment_power = subspace.alignment;
+ subspace_asect->filepos = subspace.file_loc_init_value;
+
+ }
+ /* Setup the sizes for the space section based upon the info in the
+ last subspace of the space. */
+ space_asect->_cooked_size = (subspace.subspace_start - space_asect->vma)
+ + subspace.subspace_length;
+ space_asect->_raw_size = (subspace.file_loc_init_value
+ - space_asect->filepos)
+ + subspace.initialization_length;
+ }
+}
+
+static bfd_target *
+hppa_object_p (abfd)
+ bfd *abfd;
+{
+ struct header file_hdr;
+ struct som_exec_auxhdr aux_hdr;
+
+ if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
+ return 0;
+
+ if (!_PA_RISC_ID (file_hdr.system_id))
+ {
+ bfd_error = wrong_format;
+ return 0;
+ }
+
+ switch (file_hdr.a_magic)
+ {
+ case RELOC_MAGIC: /* I'm not really sure about all of these types... */
+ case EXEC_MAGIC:
+ case SHARE_MAGIC:
+ case DEMAND_MAGIC:
+#ifdef DL_MAGIC
+ case DL_MAGIC:
+#endif
+#ifdef SHL_MAGIC
+ case SHL_MAGIC:
+#endif
+ break;
+ default:
+ bfd_error = wrong_format;
+ return 0;
+ }
+
+ if (file_hdr.version_id != VERSION_ID
+ && file_hdr.version_id != NEW_VERSION_ID)
+ {
+ bfd_error = wrong_format;
+ return 0;
+ }
+
+ if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
+ bfd_error = wrong_format;
+
+ if (!setup_sections (abfd, &file_hdr))
+ return 0;
+
+ return hppa_object_setup (abfd, &file_hdr, &aux_hdr);
+}
+
+static boolean
+hppa_mkobject (abfd)
+ bfd *abfd;
+{
+ fprintf (stderr, "hppa_mkobject unimplemented\n");
+ fflush (stderr);
+ abort ();
+ return (false);
+}
+
+boolean
+hppa_write_object_contents(abfd)
+ bfd *abfd;
+{
+ fprintf (stderr, "hppa_write_object_contents unimplemented\n");
+ fflush (stderr);
+ abort ();
+ return (false);
+}
+
+static unsigned int
+hppa_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ fprintf (stderr, "hppa_get_symtab_upper_bound unimplemented\n");
+ fflush (stderr);
+ abort ();
+ return (0);
+}
+
+static unsigned int
+hppa_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ fprintf (stderr, "hppa_get_reloc_upper_bound unimplemented\n");
+ fflush (stderr);
+ abort ();
+ return (0);
+}
+
+static unsigned int
+hppa_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ fprintf (stderr, "hppa_canonicalize_reloc unimplemented\n");
+ fflush (stderr);
+ abort ();
+}
+
+extern bfd_target hppa_vec;
+
+static unsigned int
+hppa_get_symtab (abfd, location)
+ bfd *abfd;
+ asymbol **location;
+{
+ fprintf (stderr, "hppa_get_symtab unimplemented\n");
+ fflush (stderr);
+ abort ();
+ return (0);
+}
+
+static asymbol *
+hppa_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ hppa_symbol_type *new =
+ (hppa_symbol_type *) bfd_zalloc (abfd, sizeof (hppa_symbol_type));
+ new->symbol.the_bfd = abfd;
+
+ return &new->symbol;
+}
+
+static void
+hppa_print_symbol (ignore_abfd, afile, symbol, how)
+ bfd *ignore_abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ fprintf (stderr, "hppa_print_symbol unimplemented\n");
+ fflush (stderr);
+ abort ();
+}
+
+static boolean
+hppa_new_section_hook (abfd, newsect)
+ bfd *abfd;
+ asection *newsect;
+{
+ newsect->alignment_power = 3;
+
+ /* We allow more than three sections internally */
+ return true;
+}
+
+static boolean
+hppa_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ fprintf (stderr, "hppa_set_section_contents unimplimented\n");
+ fflush (stderr);
+ abort ();
+ return false;
+}
+
+static boolean
+hppa_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ fprintf (stderr, "hppa_set_arch_mach unimplemented\n");
+ fflush (stderr);
+ /* Allow any architecture to be supported by the hppa backend */
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
+static boolean
+hppa_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
+ functionname_ptr, line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ CONST char **filename_ptr;
+ CONST char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ fprintf (stderr, "hppa_find_nearest_line unimplemented\n");
+ fflush (stderr);
+ abort ();
+ return (false);
+}
+
+static int
+hppa_sizeof_headers (abfd, reloc)
+ bfd *abfd;
+ boolean reloc;
+{
+ fprintf (stderr, "hppa_sizeof_headers unimplemented\n");
+ fflush (stderr);
+ abort ();
+ return (0);
+}
+
+/* Return information about SOM symbol SYMBOL in RET. */
+
+static void
+hppa_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd; /* Ignored. */
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/* End of miscellaneous support functions. */
+
+#define hppa_bfd_debug_info_start bfd_void
+#define hppa_bfd_debug_info_end bfd_void
+#define hppa_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
+
+#define hppa_openr_next_archived_file bfd_generic_openr_next_archived_file
+#define hppa_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#define hppa_slurp_armap bfd_false
+#define hppa_slurp_extended_name_table _bfd_slurp_extended_name_table
+#define hppa_truncate_arname (void (*)())bfd_nullvoidptr
+#define hppa_write_armap 0
+
+#define hppa_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
+#define hppa_close_and_cleanup bfd_generic_close_and_cleanup
+#define hppa_get_section_contents bfd_generic_get_section_contents
+
+#define hppa_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define hppa_bfd_relax_section bfd_generic_relax_section
+#define hppa_bfd_seclet_link bfd_generic_seclet_link
+#define hppa_bfd_reloc_type_lookup \
+ ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
+#define hppa_bfd_make_debug_symbol \
+ ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+
+/* Core file support is in the hpux-core backend. */
+#define hppa_core_file_failing_command _bfd_dummy_core_file_failing_command
+#define hppa_core_file_failing_signal _bfd_dummy_core_file_failing_signal
+#define hppa_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
+
+bfd_target hppa_vec =
+{
+ "hppa", /* name */
+ bfd_target_hppa_flavour,
+ true, /* target byte order */
+ true, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+
+/* leading_symbol_char: is the first char of a user symbol
+ predictable, and if so what is it */
+ 0,
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ 3, /* minimum alignment */
+ _do_getb64, _do_getb_signed_64, _do_putb64,
+ _do_getb32, _do_getb_signed_32, _do_putb32,
+ _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
+ _do_getb64, _do_getb_signed_64, _do_putb64,
+ _do_getb32, _do_getb_signed_32, _do_putb32,
+ _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
+ {_bfd_dummy_target,
+ hppa_object_p, /* bfd_check_format */
+ bfd_generic_archive_p,
+ _bfd_dummy_target
+ },
+ {
+ bfd_false,
+ hppa_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+ {
+ bfd_false,
+ hppa_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+#undef hppa
+ JUMP_TABLE (hppa),
+ (PTR) 0
+};
+
+#endif /* HOST_HPPAHPUX || HOST_HPPABSD */