updates from Utah
authorKen Raeburn <raeburn@cygnus>
Thu, 3 Jun 1993 20:55:48 +0000 (20:55 +0000)
committerKen Raeburn <raeburn@cygnus>
Thu, 3 Jun 1993 20:55:48 +0000 (20:55 +0000)
bfd/elf32-hppa.c

index bc347afa51bd29b5fd16a40db293f50584d65877..65940dc88810736a87f1f1010324ec34ee1f7dda 100644 (file)
@@ -2,7 +2,7 @@
    Copyright (C) 1990-1991 Free Software Foundation, Inc.
 
    Written by
-       
+
        Center for Software Science
        Department of Computer Science
        University of Utah
@@ -29,11 +29,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "obstack.h"
 #include "libelf.h"
 
-
-static struct elf_backend_data elf_hppa_backend_data = {
-  NULL                 /* initially, $global$ is undefined */
-};
-
 /* ELF32/HPPA relocation support
 
        This file contains ELF32/HPPA relocation support as specified
@@ -43,424 +38,432 @@ static struct elf_backend_data elf_hppa_backend_data = {
 
 /*
        Written by:
-       
+
        Center for Software Science
        Department of Computer Science
        University of Utah
 */
 
 #include "elf32-hppa.h"
-
-/* ELF/PA stab entries */
-
-#ifdef hp800
-#undef hp800
-#include <a.out.h>     /* we want the non-hp800 definition of 'struct nlist' */
-#define hp800
-#else
-#include <a.out.h>
-#endif
+#include "libhppa.h"
+#include "aout/aout64.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] = {
-       /*  '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"        },
-       /* 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" },
-       /* 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"       },
-       /* 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_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"     }, /* #69 */
-
-       /* 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"  },      /* 75 */
-
-       /* 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"     },      /* 81 */
-
-       /* 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"},    /* 83 */
-
-       { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 84-89 */
-       { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 90-99 */
-       { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 100-109 */
-       { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 110-119 */
-       { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },             /* 120-127 */
-       
-       /*  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_SYM,      0, 3, 32, false, 0,   false, true, hppa_elf_reloc, "R_HPPA_PUSH_SYM"    },
-       { R_HPPA_PUSH_GOT,      0, 3, 32, false, 0,   false, true, hppa_elf_reloc, "R_HPPA_PUSH_GOT"    },
-       { R_HPPA_PUSH_PC,       0, 3, 32, false, 0,   false, true, hppa_elf_reloc, "R_HPPA_PUSH_PC"     },
-       { R_HPPA_PUSH_PROC,     0, 3, 32, false, 0,   false, true, hppa_elf_reloc, "R_HPPA_PUSH_PROC"   },
-       { 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"},     /* 163 */
-};
+static bfd_reloc_status_type hppa_elf_reloc ();
 
-static unsigned long
-DEFUN(hppa_elf_rebuild_insn, (abfd,insn,value,r_type,r_field, r_format),
-      bfd *abfd AND
-      unsigned long insn AND
-      unsigned long value AND
-      unsigned short r_type AND
-      unsigned short r_field AND
-      unsigned short r_format)
+reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
 {
-       unsigned long const_part; /* part of the instruction that does not change */
-       unsigned long rebuilt_part;
-
-       switch ( r_format ) {
-       case 11: {
-               unsigned w1, w;
-
-               const_part = insn & 0xffffe002;
-               dis_assemble_12(value,&w1,&w);
-               rebuilt_part = (w1 << 2) | w;
-               return const_part | rebuilt_part;
-       }
-
-       case 12: {
-               unsigned w1, w;
-
-               const_part = insn & 0xffffe002;
-               dis_assemble_12(value,&w1,&w);
-               rebuilt_part = (w1 << 2) | w;
-               return const_part | rebuilt_part;
-       }
-
-       case 14:
-               const_part = insn & 0xffffc000;
-               low_sign_unext(value,14,&rebuilt_part);
-               return const_part | rebuilt_part;
-
-       case 17: {
-               unsigned w1, w2, w;
-
-               const_part = insn & 0xffe0e002;
-               dis_assemble_17(value,&w1,&w2,&w);
-               rebuilt_part = (w2 << 2) | (w1 << 16) | w;
-               return const_part | rebuilt_part;
-       }
+/*  '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"},
+/* 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"},
+/* 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"},
+/* 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"},
+
+/* 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"},
+
+/* 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"},
+
+/* 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"},
+
+/*  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"},
+};
 
-       case 21:
-               const_part = insn & 0xffe00000;
-               dis_assemble_21(value,&rebuilt_part);
-               return const_part | rebuilt_part;
+static symext_chainS *symext_rootP = NULL;
+static symext_chainS *symext_lastP = NULL;
 
-       case 32:
-               const_part = 0;
-               return value;
-               
-       default:
-               fprintf(stderr,"Relocation problem : ");
-               fprintf(stderr,"Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
-                       r_type, r_format, r_field, abfd->filename); 
-       }
-       return insn;
+static unsigned long
+DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format),
+       bfd * abfd AND
+       unsigned long insn AND
+       unsigned long value AND
+       unsigned short r_type AND
+       unsigned short r_field AND
+       unsigned short r_format)
+{
+  unsigned long const_part;    /* part of the instruction that does not change */
+  unsigned long rebuilt_part;
+
+  switch (r_format)
+    {
+    case 11:
+      {
+       unsigned w1, w;
+
+       const_part = insn & 0xffffe002;
+       dis_assemble_12 (value, &w1, &w);
+       rebuilt_part = (w1 << 2) | w;
+       return const_part | rebuilt_part;
+      }
+
+    case 12:
+      {
+       unsigned w1, w;
+
+       const_part = insn & 0xffffe002;
+       dis_assemble_12 (value, &w1, &w);
+       rebuilt_part = (w1 << 2) | w;
+       return const_part | rebuilt_part;
+      }
+
+    case 14:
+      const_part = insn & 0xffffc000;
+      low_sign_unext (value, 14, &rebuilt_part);
+      return const_part | rebuilt_part;
+
+    case 17:
+      {
+       unsigned w1, w2, w;
+
+       const_part = insn & 0xffe0e002;
+       dis_assemble_17 (value, &w1, &w2, &w);
+       rebuilt_part = (w2 << 2) | (w1 << 16) | w;
+       return const_part | rebuilt_part;
+      }
+
+    case 21:
+      const_part = insn & 0xffe00000;
+      dis_assemble_21 (value, &rebuilt_part);
+      return const_part | rebuilt_part;
+
+    case 32:
+      const_part = 0;
+      return value;
+
+    default:
+      fprintf (stderr, "Relocation problem : ");
+      fprintf (stderr,
+              "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
+              r_type, r_format, r_field, abfd->filename);
+    }
+  return insn;
 }
 
 static unsigned long
-DEFUN(hppa_elf_relocate_insn,
-      (abfd, input_sect,
-       insn, address, symp, sym_value, r_addend,
-       r_type, r_format, r_field, pcrel),
-      bfd *abfd AND
-      asection *input_sect AND
-      unsigned long insn AND
-      unsigned long address AND
-      asymbol *symp AND
-      long sym_value AND
-      long r_addend AND
-      unsigned short r_type AND
-      unsigned short r_format AND
-      unsigned short r_field AND
-      unsigned char pcrel)
+DEFUN (hppa_elf_relocate_insn,
+       (abfd, input_sect,
+       insn, address, symp, sym_value, r_addend,
+       r_type, r_format, r_field, pcrel),
+       bfd * abfd AND
+       asection * input_sect AND
+       unsigned long insn AND
+       unsigned long address AND
+       asymbol * symp AND
+       long sym_value AND
+       long r_addend AND
+       unsigned short r_type AND
+       unsigned short r_format AND
+       unsigned short r_field AND
+       unsigned char pcrel)
 {
-       unsigned char opcode = get_opcode(insn);
-       long constant_value;
-       unsigned arg_reloc;
-
-       switch ( opcode ) {
-           case LDO:
-           case LDB:
-           case LDH:
-           case LDW:
-           case LDWM:
-           case STB:
-           case STH:
-           case STW:
-           case STWM:
-               constant_value = ELF32_HPPA_R_CONSTANT(r_addend);
-               BFD_ASSERT(r_format == 14);
-
-               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);
-
-           case COMICLR:
-           case SUBI:  /* case SUBIO: */
-           case ADDIT: /* case ADDITO: */
-           case ADDI:  /* case ADDIO: */
-               BFD_ASSERT(r_format == 11);
-
-               constant_value = ((insn & 0x1) << 10) | ((insn & 0xffe) >> 1);
-               sym_value = hppa_field_adjust(sym_value,constant_value,r_field);
-               return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_field, r_format);
-
-           case LDIL:
-           case ADDIL:
-               BFD_ASSERT(r_format == 21);
-
-               constant_value = assemble_21(insn);
-               sym_value = hppa_field_adjust(sym_value,constant_value,r_field);
-               return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_field, r_format);
-
-           case BL:
-           case BE:
-           case BLE:
-               arg_reloc = ELF32_HPPA_R_ARG_RELOC(r_addend);
-
-               BFD_ASSERT(r_format == 17);
-
-               /* XXX computing constant_value is not needed??? */
-               constant_value = assemble_17((insn & 0x001f0000) >> 16,
-                                            (insn & 0x00001ffc) >> 2,
-                                            insn & 1);
-               constant_value = sign_ext(constant_value,17);
-               if ( pcrel ) {
-                       sym_value -=
-                               address + input_sect->output_offset
-                                       + input_sect->output_section->vma;
-                       sym_value = hppa_field_adjust(sym_value,-8,r_field);
-               }
-               else
-                       sym_value = hppa_field_adjust(sym_value, constant_value, r_field);
+  unsigned char opcode = get_opcode (insn);
+  long constant_value;
+  unsigned arg_reloc;
+
+  switch (opcode)
+    {
+    case LDO:
+    case LDB:
+    case LDH:
+    case LDW:
+    case LDWM:
+    case STB:
+    case STH:
+    case STW:
+    case STWM:
+      constant_value = ELF32_HPPA_R_CONSTANT (r_addend);
+      BFD_ASSERT (r_format == 14);
+
+      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);
+
+    case COMICLR:
+    case SUBI:                 /* case SUBIO: */
+    case ADDIT:                /* case ADDITO: */
+    case ADDI:                 /* case ADDIO: */
+      BFD_ASSERT (r_format == 11);
+
+      constant_value = ((insn & 0x1) << 10) | ((insn & 0xffe) >> 1);
+      sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
+      return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
+
+    case LDIL:
+    case ADDIL:
+      BFD_ASSERT (r_format == 21);
+
+      constant_value = assemble_21 (insn);
+      constant_value += ELF32_HPPA_R_CONSTANT (r_addend);
+      sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
+      return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
+
+    case BL:
+    case BE:
+    case BLE:
+      arg_reloc = ELF32_HPPA_R_ARG_RELOC (r_addend);
+
+      BFD_ASSERT (r_format == 17);
+
+      /* XXX computing constant_value is not needed??? */
+      constant_value = assemble_17 ((insn & 0x001f0000) >> 16,
+                                   (insn & 0x00001ffc) >> 2,
+                                   insn & 1);
+      /* @@ Assumes only 32 bits.  */
+      constant_value = (constant_value << 15) >> 15;
+      if (pcrel)
+       {
+         sym_value -=
+           address + input_sect->output_offset
+           + input_sect->output_section->vma;
+         sym_value = hppa_field_adjust (sym_value, -8, r_field);
+       }
+      else
+       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
 
-               return hppa_elf_rebuild_insn(abfd,insn,sym_value >> 2,r_type,r_field, r_format);
+      return hppa_elf_rebuild_insn (abfd, insn, sym_value >> 2, r_type, r_field, r_format);
 
-           default:
-               if ( opcode == 0 && r_format == 32 ) {
-                       constant_value = insn;
-                       sym_value = hppa_field_adjust(sym_value,constant_value,r_field);
-                       return sym_value;                       
-               }
-               else {
-                       fprintf(stderr,
-                               "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
-                               opcode, r_format, r_field);
-                       return (insn);
-               }
+    default:
+      if (opcode == 0)
+       {
+         BFD_ASSERT (r_format == 32);
+         constant_value = insn;
+         constant_value += ELF32_HPPA_R_CONSTANT (r_addend);
+
+         return hppa_field_adjust (sym_value, constant_value, r_field);
+       }
+      else
+       {
+         fprintf (stderr,
+                  "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
+                  opcode, r_format, r_field);
+         return insn;
        }
+    }
 }
 
 static void
-DEFUN(hppa_elf_relocate_unwind_table,
-      (abfd, input_sect,
-       data, address, symp, sym_value, r_addend,
-       r_type, r_format, r_field, pcrel),
-      bfd *abfd AND
-      asection *input_sect AND
-      PTR data AND
-      unsigned long address AND
-      asymbol *symp AND
-      long sym_value AND
-      long r_addend AND
-      unsigned short r_type AND
-      unsigned short r_format AND
-      unsigned short r_field AND
-      unsigned char pcrel)
+DEFUN (hppa_elf_relocate_unwind_table,
+       (abfd, input_sect,
+       data, address, symp, sym_value, r_addend,
+       r_type, r_format, r_field, pcrel),
+       bfd * abfd AND
+       asection * input_sect AND
+       PTR data AND
+       unsigned long address AND
+       asymbol * symp AND
+       long sym_value AND
+       long r_addend AND
+       unsigned short r_type AND
+       unsigned short r_format AND
+       unsigned short r_field AND
+       unsigned char pcrel)
 {
-       bfd_byte  *hit_data     = address + (bfd_byte *)(data);
-       long constant_value;
-       long start_offset;
-       long end_offset;
-       long relocated_value;
-       int i;
-
-       BFD_ASSERT( r_format == 32 );
-       BFD_ASSERT( r_field == e_fsel );
-       switch ( r_type ) {
-           case R_HPPA_UNWIND_ENTRY:
-               start_offset = bfd_get_32(abfd, hit_data);
-               relocated_value = hppa_field_adjust(sym_value,start_offset,r_field);
-               bfd_put_32(abfd, relocated_value ,hit_data);
-
-               hit_data += sizeof(unsigned long);
-               end_offset = bfd_get_32(abfd, hit_data);
-               relocated_value = hppa_field_adjust(sym_value,end_offset,r_field);
-               bfd_put_32(abfd, relocated_value ,hit_data);
-               break;
-
-           case R_HPPA_UNWIND_ENTRIES:
-               for ( i = 0; i < r_addend; i++,hit_data += 3*sizeof(unsigned long) ) {
-                       unsigned int fsize;
-                       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);
-
-                       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);
-
-                       /* 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;
-                       }
-               }
-               break;
-
-           default:
-               fprintf(stderr,
-                       "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
-                       r_type, r_format, r_field);
+  bfd_byte *hit_data = address + (bfd_byte *) (data);
+  long start_offset;
+  long end_offset;
+  long relocated_value;
+  int i;
+
+  BFD_ASSERT (r_format == 32);
+  BFD_ASSERT (r_field == e_fsel);
+  switch (r_type)
+    {
+    case R_HPPA_UNWIND_ENTRY:
+      start_offset = bfd_get_32 (abfd, hit_data);
+      relocated_value = hppa_field_adjust (sym_value, start_offset, r_field);
+      bfd_put_32 (abfd, relocated_value, hit_data);
+
+      hit_data += sizeof (unsigned long);
+      end_offset = bfd_get_32 (abfd, hit_data);
+      relocated_value = hppa_field_adjust (sym_value, end_offset, r_field);
+      bfd_put_32 (abfd, relocated_value, hit_data);
+      break;
+
+    case R_HPPA_UNWIND_ENTRIES:
+      for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long))
+       {
+         unsigned int fsize;
+         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);
+
+         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);
+
+         /* 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;
+           }
        }
-       return;
+      break;
+
+    default:
+      fprintf (stderr,
+              "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
+              r_type, r_format, r_field);
+    }
 }
 
 /* Provided the symbol, returns the value reffed */
-static  long
-get_symbol_value(symbol)       
-asymbol *symbol;
-{                                             
-       long relocation = 0;
-
-       if ( symbol == (asymbol *)NULL )
-               relocation = 0;
-       else if (symbol->section == &bfd_com_section) {
-               relocation = 0;                           
-       }
-       else {                                      
-               relocation = symbol->value +
-                       symbol->section->output_section->vma +
-                               symbol->section->output_offset;
-       }                                           
-
-       return(relocation);
+static long
+get_symbol_value (symbol)
+     asymbol *symbol;
+{
+  long relocation = 0;
+
+  if (symbol == (asymbol *) NULL)
+    relocation = 0;
+  else if (symbol->section == &bfd_com_section)
+    {
+      relocation = 0;
+    }
+  else
+    {
+      relocation = symbol->value +
+       symbol->section->output_section->vma +
+       symbol->section->output_offset;
+    }
+
+  return (relocation);
 }
 
 /* This function provides a pretty straight-forward mapping between a */
@@ -475,576 +478,705 @@ asymbol *symbol;
 /* handled yet. */
 
 static void
-       hppa_elf_gen_reloc_error(base_type,fmt,field)
-elf32_hppa_reloc_type base_type;
-int fmt;
-int field;
+hppa_elf_gen_reloc_error (base_type, fmt, field)
+     elf32_hppa_reloc_type base_type;
+     int fmt;
+     int field;
 {
-       fprintf(stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
-               base_type, fmt, field);
+  fprintf (stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
+          base_type, fmt, field);
 }
 
-unsigned char
-hppa_elf_gen_reloc_type(base_type, format, field)
-elf32_hppa_reloc_type base_type;
-int format;
-int field;
+elf32_hppa_reloc_type **
+hppa_elf_gen_reloc_type (abfd, base_type, format, field)
+     bfd *abfd;
+     elf32_hppa_reloc_type base_type;
+     int format;
+     int field;
 {
 #define UNDEFINED      hppa_elf_gen_reloc_error(base_type,format,field);
 
-       elf32_hppa_reloc_type final_type = base_type;
-       switch ( base_type ) {
-           case R_HPPA:
-               switch (format) {
-                   case 11:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_R11;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_RS11;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_RD11;
-                               break;
-                               
-                           case e_psel:
-                               final_type = R_HPPA_PLABEL_11;
-                               break;
-                           case e_rpsel:
-                               final_type = R_HPPA_PLABEL_R11;
-                               break;
-                           case e_lpsel:
-                           case e_tsel:
-                           case e_ltsel:
-                           case e_rtsel:
-                               
-                           case e_fsel:
-                           case e_lsel:
-                           case e_lrsel:
-                           case e_lssel:
-                           case e_rrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 12:
-                       UNDEFINED;
-                       break;
-                   case 14:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_R14;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_RS14;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_RD14;
-                               break;
-                           case e_rrsel:
-                               final_type = R_HPPA_RR14;
-                               break;
-                               
-                           case e_psel:
-                               final_type = R_HPPA_PLABEL_14;
-                               break;
-                           case e_rpsel:
-                               final_type = R_HPPA_PLABEL_R14;
-                               break;
-                           case e_lpsel:
-                           case e_tsel:
-                           case e_ltsel:
-                           case e_rtsel:
-                               
-                           case e_fsel:
-                           case e_lsel:
-                           case e_lssel:
-                           case e_ldsel:
-                           case e_lrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 17:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_R17;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_RS17;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_RD17;
-                               break;
-                           case e_rrsel:
-                               final_type = R_HPPA_RR17;
-                               break;
-                           case e_fsel:
-                           case e_lsel:
-                           case e_lssel:
-                           case e_ldsel:
-                           case e_lrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 21:
-                       switch ( field ) {
-                           case e_lsel:
-                               final_type = R_HPPA_L21;
-                               break;
-                           case e_lssel:
-                               final_type = R_HPPA_LS21;
-                               break;
-                           case e_ldsel:
-                               final_type = R_HPPA_LD21;
-                               break;
-                           case e_lrsel:
-                               final_type = R_HPPA_LR21;
-                               break;
-                           case e_lpsel:
-                               final_type = R_HPPA_PLABEL_L21;
-                               break;
-                           case e_rsel:
-                           case e_rssel:
-                           case e_rdsel:
-                           case e_rrsel:
-                           case e_fsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 32:
-                       switch ( field ) {
-                           case e_fsel:
-                               final_type = R_HPPA_32;
-                               break;
-                           case e_psel:
-                               final_type = R_HPPA_PLABEL_32;
-                               break;
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   default:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-               }
-               break;
-           case R_HPPA_GOTOFF:
-               switch (format) {
-                   case 11:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_GOTOFF_R11;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_GOTOFF_RS11;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_GOTOFF_RD11;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_GOTOFF_11;
-                               break;
-                           case e_lsel:
-                           case e_lrsel:
-                           case e_lssel:
-                           case e_rrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 12:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-                   case 14:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_GOTOFF_R14;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_GOTOFF_RS14;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_GOTOFF_RD14;
-                               break;
-                           case e_rrsel:
-                               final_type = R_HPPA_GOTOFF_RR14;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_GOTOFF_14;
-                               break;
-                           case e_lsel:
-                           case e_lssel:
-                           case e_ldsel:
-                           case e_lrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 17:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-                   case 21:
-                       switch ( field ) {
-                           case e_lsel:
-                               final_type = R_HPPA_GOTOFF_L21;
-                               break;
-                           case e_lssel:
-                               final_type = R_HPPA_GOTOFF_LS21;
-                               break;
-                           case e_ldsel:
-                               final_type = R_HPPA_GOTOFF_LD21;
-                               break;
-                           case e_lrsel:
-                               final_type = R_HPPA_GOTOFF_LR21;
-                               break;
-                           case e_rsel:
-                           case e_rssel:
-                           case e_rdsel:
-                           case e_rrsel:
-                           case e_fsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 32:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-                   default:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-               }
-               break;
-           case R_HPPA_PCREL_CALL:
-               switch (format) {
-                   case 11:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_PCREL_CALL_R11;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_PCREL_CALL_RS11;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_PCREL_CALL_RD11;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_PCREL_CALL_11;
-                               break;
-                           case e_lsel:
-                           case e_lrsel:
-                           case e_lssel:
-                           case e_rrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 12:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-                   case 14:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_PCREL_CALL_R14;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_PCREL_CALL_RS14;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_PCREL_CALL_RD14;
-                               break;
-                           case e_rrsel:
-                               final_type = R_HPPA_PCREL_CALL_RR14;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_PCREL_CALL_14;
-                               break;
-                           case e_lsel:
-                           case e_lssel:
-                           case e_ldsel:
-                           case e_lrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 17:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_PCREL_CALL_R17;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_PCREL_CALL_RS17;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_PCREL_CALL_RD17;
-                               break;
-                           case e_rrsel:
-                               final_type = R_HPPA_PCREL_CALL_RR17;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_PCREL_CALL_17;
-                               break;
-                           case e_lsel:
-                           case e_lssel:
-                           case e_ldsel:
-                           case e_lrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 21:
-                       switch ( field ) {
-                           case e_lsel:
-                               final_type = R_HPPA_PCREL_CALL_L21;
-                               break;
-                           case e_lssel:
-                               final_type = R_HPPA_PCREL_CALL_LS21;
-                               break;
-                           case e_ldsel:
-                               final_type = R_HPPA_PCREL_CALL_LD21;
-                               break;
-                           case e_lrsel:
-                               final_type = R_HPPA_PCREL_CALL_LR21;
-                               break;
-                           case e_rsel:
-                           case e_rssel:
-                           case e_rdsel:
-                           case e_rrsel:
-                           case e_fsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 32:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-                   default:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-               }
-               break;
-           case R_HPPA_PLABEL:
-               switch (format) {
-                   case 11:
-                       switch (field) {
-                           case e_fsel:
-                               final_type = R_HPPA_PLABEL_11;
-                               break;
-                           case e_rsel:
-                               final_type = R_HPPA_PLABEL_R11;
-                               break;
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 14:
-                       switch (field) {
-                           case e_fsel:
-                               final_type = R_HPPA_PLABEL_14;
-                               break;
-                           case e_rsel:
-                               final_type = R_HPPA_PLABEL_R14;
-                               break;
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 21:
-                       switch (field) {
-                           case e_lsel:
-                               final_type = R_HPPA_PLABEL_L21;
-                               break;
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 32:
-                       switch (field) {
-                           case e_fsel:
-                               final_type = R_HPPA_PLABEL_32;
-                               break;
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   default:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-               }
-           case R_HPPA_ABS_CALL:
-               switch (format) {
-                   case 11:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_ABS_CALL_R11;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_ABS_CALL_RS11;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_ABS_CALL_RD11;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_ABS_CALL_11;
-                               break;
-                           case e_lsel:
-                           case e_lrsel:
-                           case e_lssel:
-                           case e_rrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 12:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-                   case 14:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_ABS_CALL_R14;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_ABS_CALL_RS14;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_ABS_CALL_RD14;
-                               break;
-                           case e_rrsel:
-                               final_type = R_HPPA_ABS_CALL_RR14;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_ABS_CALL_14;
-                               break;
-                           case e_lsel:
-                           case e_lssel:
-                           case e_ldsel:
-                           case e_lrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 17:
-                       switch ( field ) {
-                           case e_rsel:
-                               final_type = R_HPPA_ABS_CALL_R17;
-                               break;
-                           case e_rssel:
-                               final_type = R_HPPA_ABS_CALL_RS17;
-                               break;
-                           case e_rdsel:
-                               final_type = R_HPPA_ABS_CALL_RD17;
-                               break;
-                           case e_rrsel:
-                               final_type = R_HPPA_ABS_CALL_RR17;
-                               break;
-                           case e_fsel:
-                               final_type = R_HPPA_ABS_CALL_17;
-                               break;
-                           case e_lsel:
-                           case e_lssel:
-                           case e_ldsel:
-                           case e_lrsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 21:
-                       switch ( field ) {
-                           case e_lsel:
-                               final_type = R_HPPA_ABS_CALL_L21;
-                               break;
-                           case e_lssel:
-                               final_type = R_HPPA_ABS_CALL_LS21;
-                               break;
-                           case e_ldsel:
-                               final_type = R_HPPA_ABS_CALL_LD21;
-                               break;
-                           case e_lrsel:
-                               final_type = R_HPPA_ABS_CALL_LR21;
-                               break;
-                           case e_rsel:
-                           case e_rssel:
-                           case e_rdsel:
-                           case e_rrsel:
-                           case e_fsel:
-                           default:
-                               UNDEFINED;
-                               final_type = base_type;
-                               break;
-                       }
-                       break;
-                   case 32:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-                   default:
-                       UNDEFINED;
-                       final_type = base_type;
-                       break;
-               }
-               break;
-           case R_HPPA_UNWIND:
-               final_type = R_HPPA_UNWIND_ENTRY;
-               break;
+  elf32_hppa_reloc_type *finaltype;
+  elf32_hppa_reloc_type **final_types;
+  int i;
+
+  final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2);
+  BFD_ASSERT (final_types != 0);
+
+  finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type));
+  BFD_ASSERT (finaltype != 0);
+
+  final_types[0] = finaltype;
+  final_types[1] = NULL;
+
+#define final_type finaltype[0]
+
+  final_type = base_type;
+
+  switch (base_type)
+    {
+    case R_HPPA:
+      switch (format)
+       {
+       case 11:
+         switch (field)
+           {
+           case e_fsel:
+             final_type = R_HPPA_11;
+             break;
+           case e_rsel:
+             final_type = R_HPPA_R11;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_RS11;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_RD11;
+             break;
+
+           case e_psel:
+             final_type = R_HPPA_PLABEL_11;
+             break;
+           case e_rpsel:
+             final_type = R_HPPA_PLABEL_R11;
+             break;
+           case e_lpsel:
+           case e_tsel:
+           case e_ltsel:
+           case e_rtsel:
+
+           case e_lsel:
+           case e_lrsel:
+           case e_lssel:
+           case e_rrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 12:
+         UNDEFINED;
+         break;
+       case 14:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_R14;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_RS14;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_RD14;
+             break;
+           case e_rrsel:
+             final_type = R_HPPA_RR14;
+             break;
+
+           case e_psel:
+             final_type = R_HPPA_PLABEL_14;
+             break;
+           case e_rpsel:
+             final_type = R_HPPA_PLABEL_R14;
+             break;
+           case e_lpsel:
+           case e_tsel:
+           case e_ltsel:
+           case e_rtsel:
+
+           case e_fsel:
+           case e_lsel:
+           case e_lssel:
+           case e_ldsel:
+           case e_lrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 17:
+         switch (field)
+           {
+           case e_fsel:
+             final_type = R_HPPA_17;
+             break;
+           case e_rsel:
+             final_type = R_HPPA_R17;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_RS17;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_RD17;
+             break;
+           case e_rrsel:
+             final_type = R_HPPA_RR17;
+             break;
+           case e_lsel:
+           case e_lssel:
+           case e_ldsel:
+           case e_lrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 21:
+         switch (field)
+           {
+           case e_lsel:
+             final_type = R_HPPA_L21;
+             break;
+           case e_lssel:
+             final_type = R_HPPA_LS21;
+             break;
+           case e_ldsel:
+             final_type = R_HPPA_LD21;
+             break;
+           case e_lrsel:
+             final_type = R_HPPA_LR21;
+             break;
+           case e_lpsel:
+             final_type = R_HPPA_PLABEL_L21;
+             break;
+           case e_rsel:
+           case e_rssel:
+           case e_rdsel:
+           case e_rrsel:
+           case e_fsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 32:
+         switch (field)
+           {
+           case e_fsel:
+             final_type = R_HPPA_32;
+             break;
+           case e_psel:
+             final_type = R_HPPA_PLABEL_32;
+             break;
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       default:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       }
+      break;
+    case R_HPPA_GOTOFF:
+      switch (format)
+       {
+       case 11:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_GOTOFF_R11;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_GOTOFF_RS11;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_GOTOFF_RD11;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_GOTOFF_11;
+             break;
+           case e_lsel:
+           case e_lrsel:
+           case e_lssel:
+           case e_rrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 12:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       case 14:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_GOTOFF_R14;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_GOTOFF_RS14;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_GOTOFF_RD14;
+             break;
+           case e_rrsel:
+             final_type = R_HPPA_GOTOFF_RR14;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_GOTOFF_14;
+             break;
+           case e_lsel:
+           case e_lssel:
+           case e_ldsel:
+           case e_lrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 17:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       case 21:
+         switch (field)
+           {
+           case e_lsel:
+             final_type = R_HPPA_GOTOFF_L21;
+             break;
+           case e_lssel:
+             final_type = R_HPPA_GOTOFF_LS21;
+             break;
+           case e_ldsel:
+             final_type = R_HPPA_GOTOFF_LD21;
+             break;
+           case e_lrsel:
+             final_type = R_HPPA_GOTOFF_LR21;
+             break;
+           case e_rsel:
+           case e_rssel:
+           case e_rdsel:
+           case e_rrsel:
+           case e_fsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 32:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       default:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       }
+      break;
+    case R_HPPA_PCREL_CALL:
+      switch (format)
+       {
+       case 11:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_PCREL_CALL_R11;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_PCREL_CALL_RS11;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_PCREL_CALL_RD11;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_PCREL_CALL_11;
+             break;
+           case e_lsel:
+           case e_lrsel:
+           case e_lssel:
+           case e_rrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 12:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       case 14:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_PCREL_CALL_R14;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_PCREL_CALL_RS14;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_PCREL_CALL_RD14;
+             break;
+           case e_rrsel:
+             final_type = R_HPPA_PCREL_CALL_RR14;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_PCREL_CALL_14;
+             break;
+           case e_lsel:
+           case e_lssel:
+           case e_ldsel:
+           case e_lrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 17:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_PCREL_CALL_R17;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_PCREL_CALL_RS17;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_PCREL_CALL_RD17;
+             break;
+           case e_rrsel:
+             final_type = R_HPPA_PCREL_CALL_RR17;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_PCREL_CALL_17;
+             break;
+           case e_lsel:
+           case e_lssel:
+           case e_ldsel:
+           case e_lrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 21:
+         switch (field)
+           {
+           case e_lsel:
+             final_type = R_HPPA_PCREL_CALL_L21;
+             break;
+           case e_lssel:
+             final_type = R_HPPA_PCREL_CALL_LS21;
+             break;
+           case e_ldsel:
+             final_type = R_HPPA_PCREL_CALL_LD21;
+             break;
+           case e_lrsel:
+             final_type = R_HPPA_PCREL_CALL_LR21;
+             break;
+           case e_rsel:
+           case e_rssel:
+           case e_rdsel:
+           case e_rrsel:
+           case e_fsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 32:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       default:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       }
+      break;
+    case R_HPPA_PLABEL:
+      switch (format)
+       {
+       case 11:
+         switch (field)
+           {
+           case e_fsel:
+             final_type = R_HPPA_PLABEL_11;
+             break;
+           case e_rsel:
+             final_type = R_HPPA_PLABEL_R11;
+             break;
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 14:
+         switch (field)
+           {
+           case e_fsel:
+             final_type = R_HPPA_PLABEL_14;
+             break;
+           case e_rsel:
+             final_type = R_HPPA_PLABEL_R14;
+             break;
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 21:
+         switch (field)
+           {
+           case e_lsel:
+             final_type = R_HPPA_PLABEL_L21;
+             break;
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 32:
+         switch (field)
+           {
+           case e_fsel:
+             final_type = R_HPPA_PLABEL_32;
+             break;
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       default:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       }
+    case R_HPPA_ABS_CALL:
+      switch (format)
+       {
+       case 11:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_ABS_CALL_R11;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_ABS_CALL_RS11;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_ABS_CALL_RD11;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_ABS_CALL_11;
+             break;
+           case e_lsel:
+           case e_lrsel:
+           case e_lssel:
+           case e_rrsel:
            default:
-               final_type = base_type;
-               break;
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 12:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       case 14:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_ABS_CALL_R14;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_ABS_CALL_RS14;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_ABS_CALL_RD14;
+             break;
+           case e_rrsel:
+             final_type = R_HPPA_ABS_CALL_RR14;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_ABS_CALL_14;
+             break;
+           case e_lsel:
+           case e_lssel:
+           case e_ldsel:
+           case e_lrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 17:
+         switch (field)
+           {
+           case e_rsel:
+             final_type = R_HPPA_ABS_CALL_R17;
+             break;
+           case e_rssel:
+             final_type = R_HPPA_ABS_CALL_RS17;
+             break;
+           case e_rdsel:
+             final_type = R_HPPA_ABS_CALL_RD17;
+             break;
+           case e_rrsel:
+             final_type = R_HPPA_ABS_CALL_RR17;
+             break;
+           case e_fsel:
+             final_type = R_HPPA_ABS_CALL_17;
+             break;
+           case e_lsel:
+           case e_lssel:
+           case e_ldsel:
+           case e_lrsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 21:
+         switch (field)
+           {
+           case e_lsel:
+             final_type = R_HPPA_ABS_CALL_L21;
+             break;
+           case e_lssel:
+             final_type = R_HPPA_ABS_CALL_LS21;
+             break;
+           case e_ldsel:
+             final_type = R_HPPA_ABS_CALL_LD21;
+             break;
+           case e_lrsel:
+             final_type = R_HPPA_ABS_CALL_LR21;
+             break;
+           case e_rsel:
+           case e_rssel:
+           case e_rdsel:
+           case e_rrsel:
+           case e_fsel:
+           default:
+             UNDEFINED;
+             final_type = base_type;
+             break;
+           }
+         break;
+       case 32:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       default:
+         UNDEFINED;
+         final_type = base_type;
+         break;
+       }
+      break;
+    case R_HPPA_UNWIND:
+      final_type = R_HPPA_UNWIND_ENTRY;
+      break;
+    case R_HPPA_COMPLEX:
+    case R_HPPA_COMPLEX_PCREL_CALL:
+    case R_HPPA_COMPLEX_ABS_CALL:
+      final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 6);
+      BFD_ASSERT (final_types != 0);
+
+      finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type) * 5);
+      BFD_ASSERT (finaltype != 0);
+
+      for (i = 0; i < 5; i++)
+       final_types[i] = &finaltype[i];
+
+      final_types[5] = NULL;
+
+      finaltype[0] = R_HPPA_PUSH_SYM;
+
+      if (base_type == R_HPPA_COMPLEX)
+       finaltype[1] = R_HPPA_PUSH_SYM;
+      else if (base_type == R_HPPA_COMPLEX_PCREL_CALL)
+       finaltype[1] = R_HPPA_PUSH_PCREL_CALL;
+      else                     /* base_type == R_HPPA_COMPLEX_ABS_CALL */
+       finaltype[1] = R_HPPA_PUSH_ABS_CALL;
+
+      finaltype[2] = R_HPPA_SUB;
+
+      switch (field)
+       {
+       case e_fsel:
+         finaltype[3] = R_HPPA_EXPR_F;
+         break;
+       case e_lsel:
+         finaltype[3] = R_HPPA_EXPR_L;
+         break;
+       case e_rsel:
+         finaltype[3] = R_HPPA_EXPR_R;
+         break;
+       case e_lssel:
+         finaltype[3] = R_HPPA_EXPR_LS;
+         break;
+       case e_rssel:
+         finaltype[3] = R_HPPA_EXPR_RS;
+         break;
+       case e_ldsel:
+         finaltype[3] = R_HPPA_EXPR_LD;
+         break;
+       case e_rdsel:
+         finaltype[3] = R_HPPA_EXPR_RD;
+         break;
+       case e_lrsel:
+         finaltype[3] = R_HPPA_EXPR_LR;
+         break;
+       case e_rrsel:
+         finaltype[3] = R_HPPA_EXPR_RR;
+         break;
        }
 
-       return final_type;
+      switch (format)
+       {
+       case 11:
+         finaltype[4] = R_HPPA_EXPR_11;
+         break;
+       case 12:
+         finaltype[4] = R_HPPA_EXPR_12;
+         break;
+       case 14:
+         finaltype[4] = R_HPPA_EXPR_14;
+         break;
+       case 17:
+         finaltype[4] = R_HPPA_EXPR_17;
+         break;
+       case 21:
+         finaltype[4] = R_HPPA_EXPR_21;
+         break;
+       case 32:
+         finaltype[4] = R_HPPA_EXPR_32;
+         break;
+       }
+
+      break;
+
+    default:
+      final_type = base_type;
+      break;
+    }
+
+  return final_types;
 }
 
+#undef final_type
+
 /* 12.4.4. Derive format from instruction      */
 
 /*     Given a machine instruction, this function determines its format.       */
@@ -1054,457 +1186,1526 @@ int field;
 /*     should probably be reported as an error.                                */
 
 unsigned char
-hppa_elf_insn2fmt(type, insn)
-elf32_hppa_reloc_type type;
-unsigned long insn;
+hppa_elf_insn2fmt (type, insn)
+     elf32_hppa_reloc_type type;
+     unsigned long insn;
 {
-       unsigned char fmt = 0;  /* XXX: is this a proper default?       */
-       unsigned char op = get_opcode(insn);
-
-       if ( type == R_HPPA_NONE )
-               fmt = 0;
-       else {
-               switch ( op ) {
-               case ADDI:
-               case ADDIT:
-               case SUBI:
-                       fmt = 11;
-                       break;
-               case MOVB:
-               case MOVIB:
-               case COMBT:
-               case COMBF:
-               case COMIBT:
-               case COMIBF:
-               case ADDBT:
-               case ADDBF:
-               case ADDIBT:
-               case ADDIBF:
-               case BVB:
-               case BB:
-                       fmt = 12;
-                       break;
-               case LDO:
-               case LDB:
-               case LDH:
-               case LDW:
-               case LDWM:
-               case STB:
-               case STH:
-               case STW:
-               case STWM:
-                       fmt = 14;
-                       break;
-               case BL:
-               case BE:
-               case BLE:
-                       fmt = 17;
-                       break;
-               case LDIL:
-               case ADDIL:
-                       fmt = 21;
-                       break;
-               default:
-                       fmt = 32;
-                       break;
-               }
-               
+  unsigned char fmt = 0;       /* XXX: is this a proper default?       */
+  unsigned char op = get_opcode (insn);
+
+  if (type == R_HPPA_NONE)
+    fmt = 0;
+  else
+    {
+      switch (op)
+       {
+       case ADDI:
+       case ADDIT:
+       case SUBI:
+         fmt = 11;
+         break;
+       case MOVB:
+       case MOVIB:
+       case COMBT:
+       case COMBF:
+       case COMIBT:
+       case COMIBF:
+       case ADDBT:
+       case ADDBF:
+       case ADDIBT:
+       case ADDIBF:
+       case BVB:
+       case BB:
+         fmt = 12;
+         break;
+       case LDO:
+       case LDB:
+       case LDH:
+       case LDW:
+       case LDWM:
+       case STB:
+       case STH:
+       case STW:
+       case STWM:
+         fmt = 14;
+         break;
+       case BL:
+       case BE:
+       case BLE:
+         fmt = 17;
+         break;
+       case LDIL:
+       case ADDIL:
+         fmt = 21;
+         break;
+       default:
+         fmt = 32;
+         break;
        }
-       return fmt;
+
+    }
+  return fmt;
 }
 
 /* this function is in charge of performing all the HP PA relocations */
-long global_value      = 0;
-long   GOT_value       = 0;    /* XXX:  need to calculate this! For HPUX, GOT == DP */
-asymbol *global_symbol = (asymbol *)NULL;
+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 bfd_reloc_status_type
-DEFUN(hppa_elf_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
-      bfd *abfd AND
-      arelent *reloc_entry AND
-      asymbol *symbol_in AND
-      PTR data AND
-      asection *input_section AND
-      bfd *output_bfd)
+DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
+       bfd * abfd AND
+       arelent * reloc_entry AND
+       asymbol * symbol_in AND
+       PTR data AND
+       asection * input_section AND
+       bfd * output_bfd)
+{
+  unsigned long insn;
+  long sym_value = 0;
+
+  unsigned long addr = reloc_entry->address;   /*+ input_section->vma*/
+  bfd_byte *hit_data = addr + (bfd_byte *) (data);
+  unsigned short r_type = reloc_entry->howto->type & 0xFF;
+  unsigned short r_field = e_fsel;
+  boolean r_pcrel = reloc_entry->howto->pc_relative;
+
+  /* howto->bitsize contains the format (11, 14, 21, etc) information */
+  unsigned r_format = reloc_entry->howto->bitsize;
+  long r_addend = reloc_entry->addend;
+
+
+  if (output_bfd)
+    {
+      /* Partial linking - do nothing */
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
+
+  if (symbol_in && symbol_in->section == &bfd_und_section)
+    return bfd_reloc_undefined;
+
+  /* Check for stubs that might be required.  */
+  /* symbol_in = hppa_elf_stub_check (abfd, input_section->output_section->owner, reloc_entry); */
+
+  sym_value = get_symbol_value (symbol_in);
+
+  /* compute value of $global$ if it is there. */
+
+  if (global_symbol == (asymbol *) NULL)
+    {
+      struct elf32_backend_data *bed
+      = (struct elf32_backend_data *) abfd->xvec->backend_data;
+
+      if (bed && bed->global_sym)
+       {
+         asymbol *gsym = &bed->global_sym->symbol;
+         global_value
+           = gsym->value
+           + gsym->section->output_section->vma
+           + gsym->section->output_offset;
+         GOT_value = global_value;     /* XXX: For HP-UX, GOT==DP */
+         global_symbol = gsym;
+       }
+    }
+
+  /* get the instruction word */
+  insn = bfd_get_32 (abfd, hit_data);
+
+  /* relocate the value based on the relocation type */
+
+  /* basic_type_1:     relocation is relative to $global$              */
+  /* basic_type_2:     relocation is relative to the current GOT       */
+  /* basic_type_3:     relocation is an absolute call                  */
+  /* basic_type_4:     relocation is an PC-relative call               */
+  /* basic_type_5:     relocation is plabel reference                  */
+  /* basic_type_6:     relocation is an unwind table relocation        */
+  /* extended_type:    unimplemented                                   */
+
+  switch (r_type)
+    {
+    case R_HPPA_NONE:
+      break;
+    case R_HPPA_32:            /*              Symbol + Addend         32      */
+      r_field = e_fsel;
+      goto do_basic_type_1;
+    case R_HPPA_11:            /*              Symbol + Addend         11      */
+      r_field = e_fsel;
+      goto do_basic_type_1;
+    case R_HPPA_14:            /*              Symbol + Addend         14      */
+      r_field = e_fsel;
+      goto do_basic_type_1;
+    case R_HPPA_17:            /*              Symbol + Addend         17      */
+      r_field = e_fsel;
+      goto do_basic_type_1;
+    case R_HPPA_L21:           /*              L (Symbol, Addend)      21      */
+      r_field = e_lsel;
+      goto do_basic_type_1;
+    case R_HPPA_R11:           /*              R (Symbol, Addend)      11      */
+      r_field = e_rsel;
+      goto do_basic_type_1;
+    case R_HPPA_R14:           /*              R (Symbol, Addend)      14      */
+      r_field = e_rsel;
+      goto do_basic_type_1;
+    case R_HPPA_R17:           /*              R (Symbol, Addend)      17      */
+      r_field = e_rsel;
+      goto do_basic_type_1;
+    case R_HPPA_LS21:          /*              LS(Symbol, Addend)      21      */
+      r_field = e_lssel;
+      goto do_basic_type_1;
+    case R_HPPA_RS11:          /*              RS(Symbol, Addend)      11      */
+      r_field = e_rssel;
+      goto do_basic_type_1;
+    case R_HPPA_RS14:          /*              RS(Symbol, Addend)      14      */
+      r_field = e_rssel;
+      goto do_basic_type_1;
+    case R_HPPA_RS17:          /*              RS(Symbol, Addend)      17      */
+      r_field = e_ldsel;
+      goto do_basic_type_1;
+    case R_HPPA_LD21:          /*              LD(Symbol, Addend)      21      */
+      r_field = e_ldsel;
+      goto do_basic_type_1;
+    case R_HPPA_RD11:          /*              RD(Symbol, Addend)      11      */
+      r_field = e_rdsel;
+      goto do_basic_type_1;
+    case R_HPPA_RD14:          /*              RD(Symbol, Addend)      14      */
+      r_field = e_rdsel;
+      goto do_basic_type_1;
+    case R_HPPA_RD17:          /*              RD(Symbol, Addend)      17      */
+      r_field = e_rdsel;
+      goto do_basic_type_1;
+    case R_HPPA_LR21:          /*              LR(Symbol, Addend)      21      */
+      r_field = e_lrsel;
+      goto do_basic_type_1;
+    case R_HPPA_RR14:          /*              RR(Symbol, Addend)      14      */
+      r_field = e_rrsel;
+      goto do_basic_type_1;
+    case R_HPPA_RR17:          /*              RR(Symbol, Addend)      17      */
+      r_field = e_rrsel;
+
+    do_basic_type_1:
+      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;
+
+    case R_HPPA_GOTOFF_11:     /*      Symbol - GOT + Addend   11      */
+      r_field = e_fsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_14:     /*      Symbol - GOT + Addend   14      */
+      r_field = e_fsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_L21:    /*      L (Sym - GOT, Addend)   21      */
+      r_field = e_lsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_R11:    /*      R (Sym - GOT, Addend)   11      */
+      r_field = e_rsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_R14:    /*      R (Sym - GOT, Addend)   14      */
+      r_field = e_rsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_LS21:   /*      LS(Sym - GOT, Addend)   21      */
+      r_field = e_lssel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_RS11:   /*      RS(Sym - GOT, Addend)   11      */
+      r_field = e_rssel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_RS14:   /*      RS(Sym - GOT, Addend)   14      */
+      r_field = e_rssel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_LD21:   /*      LD(Sym - GOT, Addend)   21      */
+      r_field = e_ldsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_RD11:   /*      RD(Sym - GOT, Addend)   11      */
+      r_field = e_rdsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_RD14:   /*      RD(Sym - GOT, Addend)   14      */
+      r_field = e_rdsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_LR21:   /*      LR(Sym - GOT, Addend)   21      */
+      r_field = e_lrsel;
+      goto do_basic_type_2;
+    case R_HPPA_GOTOFF_RR14:   /*      RR(Sym - GOT, Addend)   14      */
+      r_field = e_rrsel;
+    do_basic_type_2:
+      sym_value -= GOT_value;
+      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;
+
+    case R_HPPA_ABS_CALL_11:   /*      Symbol + Addend         11      */
+      r_field = e_fsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_14:   /*      Symbol + Addend         14      */
+      r_field = e_fsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_17:   /*      Symbol + Addend         17      */
+      r_field = e_fsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_L21:  /*      L (Symbol, Addend)      21      */
+      r_field = e_lsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_R11:  /*      R (Symbol, Addend)      11      */
+      r_field = e_rsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_R14:  /*      R (Symbol, Addend)      14      */
+      r_field = e_rsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_R17:  /*      R (Symbol, Addend)      17      */
+      r_field = e_rsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_LS21: /*      LS(Symbol, Addend)      21      */
+      r_field = e_lssel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RS11: /*      RS(Symbol, Addend)      11      */
+      r_field = e_lssel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RS14: /*      RS(Symbol, Addend)      14      */
+      r_field = e_rssel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RS17: /*      RS(Symbol, Addend)      17      */
+      r_field = e_rssel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_LD21: /*      LD(Symbol, Addend)      21      */
+      r_field = e_ldsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RD11: /*      RD(Symbol, Addend)      11      */
+      r_field = e_rdsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RD14: /*      RD(Symbol, Addend)      14      */
+      r_field = e_rdsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RD17: /*      RD(Symbol, Addend)      17      */
+      r_field = e_rdsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_LR21: /*      LR(Symbol, Addend)      21      */
+      r_field = e_lrsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RR14: /*      RR(Symbol, Addend)      14      */
+      r_field = e_rrsel;
+      goto do_basic_type_3;
+    case R_HPPA_ABS_CALL_RR17: /*      RR(Symbol, Addend)      17      */
+      r_field = e_rrsel;
+    do_basic_type_3:
+      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;
+
+    case R_HPPA_PCREL_CALL_11: /*      Symbol - PC + Addend    11      */
+      r_field = e_fsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_14: /*      Symbol - PC + Addend    14      */
+      r_field = e_fsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_17: /*      Symbol - PC + Addend    17      */
+      r_field = e_fsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_L21:/*      L (Symbol - PC, Addend) 21      */
+      r_field = e_lsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_R11:/*      R (Symbol - PC, Addend) 11      */
+      r_field = e_rsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_R14:/*      R (Symbol - PC, Addend) 14      */
+      r_field = e_rsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_R17:/*      R (Symbol - PC, Addend) 17      */
+      r_field = e_rsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_LS21:       /*      LS(Symbol - PC, Addend) 21      */
+      r_field = e_lssel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RS11:       /*      RS(Symbol - PC, Addend) 11      */
+      r_field = e_rssel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RS14:       /*      RS(Symbol - PC, Addend) 14      */
+      r_field = e_rssel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RS17:       /*      RS(Symbol - PC, Addend) 17      */
+      r_field = e_rssel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_LD21:       /*      LD(Symbol - PC, Addend) 21      */
+      r_field = e_ldsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RD11:       /*      RD(Symbol - PC, Addend) 11      */
+      r_field = e_rdsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RD14:       /*      RD(Symbol - PC, Addend) 14      */
+      r_field = e_rdsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RD17:       /*      RD(Symbol - PC, Addend) 17      */
+      r_field = e_rdsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_LR21:       /*      LR(Symbol - PC, Addend) 21      */
+      r_field = e_lrsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RR14:       /*      RR(Symbol - PC, Addend) 14      */
+      r_field = e_rrsel;
+      goto do_basic_type_4;
+    case R_HPPA_PCREL_CALL_RR17:       /*      RR(Symbol - PC, Addend) 17      *//* #69 */
+      r_field = e_rrsel;
+    do_basic_type_4:
+      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;
+
+    case R_HPPA_PLABEL_32:
+    case R_HPPA_PLABEL_11:
+    case R_HPPA_PLABEL_14:
+      r_field = e_fsel;
+      goto do_basic_type_5;
+    case R_HPPA_PLABEL_L21:
+      r_field = e_lsel;
+      goto do_basic_type_5;
+    case R_HPPA_PLABEL_R11:
+    case R_HPPA_PLABEL_R14:
+      r_field = e_rsel;
+    do_basic_type_5:
+      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;
+
+    case R_HPPA_UNWIND_ENTRY:
+    case R_HPPA_UNWIND_ENTRIES:
+      hppa_elf_relocate_unwind_table (abfd, input_section, data, addr,
+                                     symbol_in, sym_value, r_addend,
+                                     r_type, r_format, r_field, r_pcrel);
+      return (bfd_reloc_ok);
+
+    case R_HPPA_PUSH_CONST:    /*      push Addend                     -   -   */
+    case R_HPPA_PUSH_PC:       /*      push PC + Addend                -   -   */
+    case R_HPPA_PUSH_SYM:      /*      push Symbol + Addend            -   -   */
+    case R_HPPA_PUSH_GOTOFF:   /*      push Symbol - GOT + Addend      -   -   */
+    case R_HPPA_PUSH_ABS_CALL: /*      push Symbol + Addend            -   -   */
+    case R_HPPA_PUSH_PCREL_CALL:       /*      push Symbol - PC + Addend       -   -   */
+    case R_HPPA_PUSH_PLABEL:   /*      [TBD]                           -   -   */
+    case R_HPPA_MAX:           /*      pop A and B, push max(B,A)      -   -   */
+    case R_HPPA_MIN:           /*      pop A and B, push min(B,A)      -   -   */
+    case R_HPPA_ADD:           /*      pop A and B, push B + A         -   -   */
+    case R_HPPA_SUB:           /*      pop A and B, push B - A         -   -   */
+    case R_HPPA_MULT:          /*      pop A and B, push B * A         -   -   */
+    case R_HPPA_DIV:           /*      pop A and B, push B / A         -   -   */
+    case R_HPPA_MOD:           /*      pop A and B, push B % A         -   -   */
+    case R_HPPA_AND:           /*      pop A and B, push B & A         -   -   */
+    case R_HPPA_OR:            /*      pop A and B, push B | A         -   -   */
+    case R_HPPA_XOR:           /*      pop A and B, push B ^ A         -   -   */
+    case R_HPPA_NOT:           /*      pop A, push ~A                  -   -   */
+    case R_HPPA_LSHIFT:        /*      pop A, push A << Addend         -   -   */
+    case R_HPPA_ARITH_RSHIFT:  /*      pop A, push A >> Addend         -   -   */
+    case R_HPPA_LOGIC_RSHIFT:  /*      pop A, push A >> Addend         -   -   */
+    case R_HPPA_EXPR_F:        /*      pop A, push A + Addend          L   -   */
+    case R_HPPA_EXPR_L:        /*      pop A, push L(A,Addend)         L   -   */
+    case R_HPPA_EXPR_R:        /*      pop A, push R(A,Addend)         R   -   */
+    case R_HPPA_EXPR_LS:       /*      pop A, push LS(A,Addend)        LS  -   */
+    case R_HPPA_EXPR_RS:       /*      pop A, push RS(A,Addend)        RS  -   */
+    case R_HPPA_EXPR_LD:       /*      pop A, push LD(A,Addend)        LD  -   */
+    case R_HPPA_EXPR_RD:       /*      pop A, push RD(A,Addend)        RD  -   */
+    case R_HPPA_EXPR_LR:       /*      pop A, push LR(A,Addend)        LR  -   */
+    case R_HPPA_EXPR_RR:       /*      pop A, push RR(A,Addend)        RR  -   */
+
+    case R_HPPA_EXPR_32:       /*      pop                             -   32  */
+    case R_HPPA_EXPR_21:       /*      pop                             -   21  */
+    case R_HPPA_EXPR_11:       /*      pop                             -   11  */
+    case R_HPPA_EXPR_14:       /*      pop                             -   14  */
+    case R_HPPA_EXPR_17:       /*      pop                             -   17  */
+    case R_HPPA_EXPR_12:       /*      pop                             -   12  */
+      fprintf (stderr, "Relocation problem: ");
+      fprintf (stderr, "Unimplemented reloc type %d, in module %s\n",
+              r_type, abfd->filename);
+      return (bfd_reloc_notsupported);
+    default:
+      fprintf (stderr, "Relocation problem : ");
+      fprintf (stderr, "Unrecognized reloc type %d, in module %s\n",
+              r_type, abfd->filename);
+      return (bfd_reloc_dangerous);
+    }
+
+  /* update the instruction word */
+  bfd_put_32 (abfd, insn, hit_data);
+
+  return (bfd_reloc_ok);
+
+}
+
+struct elf_reloc_map
+  {
+    unsigned char bfd_reloc_val;
+    unsigned char elf_reloc_val;
+  };
+
+static CONST struct elf_reloc_map elf_hppa_reloc_map[] =
 {
-       unsigned long insn;
-       long    sym_value       = 0;
-       unsigned long unsigned_value;
-       long signed_value;
-
-       unsigned long addr      = reloc_entry->address ; /*+ input_section->vma*/
-       bfd_byte  *hit_data     = addr + (bfd_byte *)(data);
-       unsigned short r_type   = reloc_entry->howto->type & 0xFF;
-       unsigned short r_field  = e_fsel;
-       boolean r_pcrel         = reloc_entry->howto->pc_relative;
-
-       /* howto->bitsize contains the format (11, 14, 21, etc) information */
-       unsigned r_format       = reloc_entry->howto->bitsize;
-       long r_addend           = reloc_entry->addend;
-       
-
-       if (output_bfd) {
-               /* Partial linking - do nothing */
-               reloc_entry->address += input_section->output_offset;
-               return bfd_reloc_ok;
+  {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);
+      return &elf_hppa_howto_table[(int) code];
+    }
+
+  return (reloc_howto_type *) 0;
+}
+
+#define bfd_elf32_bfd_reloc_type_lookup        elf_hppa_reloc_type_lookup
+
+
+void
+DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx),
+       bfd * abfd AND
+       elf32_symbol_type * symbolP AND
+       int sym_idx)
+{
+  symext_chainS *symextP;
+  unsigned int arg_reloc;
+
+  if (!(symbolP->symbol.flags & BSF_FUNCTION))
+    return;
+
+  if (!((symbolP->symbol.flags & BSF_EXPORT) ||
+       (symbolP->symbol.flags & BSF_GLOBAL)))
+    return;
+
+  arg_reloc = symbolP->tc_data.hppa_arg_reloc;
+
+  symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
+
+  symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
+  symextP[0].next = &symextP[1];
+
+  symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
+  symextP[1].next = NULL;
+
+  if (symext_rootP == NULL)
+    {
+      symext_rootP = &symextP[0];
+      symext_lastP = &symextP[1];
+    }
+  else
+    {
+      symext_lastP->next = &symextP[0];
+      symext_lastP = &symextP[1];
+    }
+}
+
+static symext_entryS *symextn_contents = NULL;
+static unsigned int symextn_contents_real_size = 0;
+
+void
+DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
+       bfd * abfd AND
+       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;
+
+  hppa_elf_stub_finish (abfd);
+
+  if (symext_rootP == NULL)
+    return;
+
+  for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
+    ;
+
+  size = sizeof (symext_entryS) * n;
+  symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
+  if (symextn_sec == (asection *) 0)
+    {
+      symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
+      bfd_set_section_flags (abfd,
+                            symextn_sec,
+        SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE | SEC_READONLY);
+      symextn_sec->output_section = symextn_sec;
+      symextn_sec->output_offset = 0;
+      bfd_set_section_alignment (abfd, symextn_sec, 2);
+    }
+  symextn_contents = (symext_entryS *) bfd_alloc (abfd, size);
+
+  for (i = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++i)
+    symextn_contents[i] = symextP->entry;
+  symextn_contents_real_size = size;
+  bfd_set_section_size (abfd, symextn_sec, symextn_contents_real_size);
+
+  return;
+}
+
+/* Support for HP PA-RISC stub generation.
+
+   Written by
+
+       Center for Software Science
+       Department of Computer Science
+       University of Utah
+
+    */
+
+/*
+    HP-PA calling conventions state:
+
+    1. an argument relocation stub is required whenever the callee and
+    caller argument relocation bits do not match exactly.  The exception
+    to this rule is if either the caller or callee argument relocation
+    bit are 00 (do not relocate).
+
+    2. The linker can optionally add a symbol record for the stub so that
+    the stub can be reused.  The symbol record will be the same as the
+    original export symbol record, except that the relocation bits will
+    reflect the input of the stub, the type would be STUB and the symbol
+    value will be the location of the relocation stub.
+
+    Other notes:
+
+    Stubs can be inserted *before* the section of the caller.  The stubs
+    can be treated as calls to code that manipulates the arguments.
+
+ */
+
+typedef enum
+  {
+    HPPA_STUB_ILLEGAL,
+    HPPA_STUB_ARG_RELOC,
+    HPPA_STUB_LONG_BRANCH
+  } hppa_stub_type;
+
+symext_entryS
+elf32_hppa_get_sym_extn (abfd, sym, type)
+     bfd *abfd;
+     asymbol *sym;
+     int type;
+{
+  /* This function finds the symbol extension record of the */
+  /* specified type for the specified symbol.  It returns the */
+  /* value of the symbol extension record.     */
+  symext_entryS retval;
+
+  switch (type)
+    {
+    case HPPA_SXT_NULL:
+      retval = (symext_entryS) 0;
+      break;
+    case HPPA_SXT_SYMNDX:
+      retval = (symext_entryS) 0;      /* XXX: need to fix this */
+      break;
+    case HPPA_SXT_ARG_RELOC:
+      {
+       elf32_symbol_type *esymP = (elf32_symbol_type *) sym;
+
+       retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
+       break;
+      }
+    }
+  return retval;
+}
+
+
+typedef struct Elf32_hppa_Stub_description_struct
+  {
+    bfd *this_bfd;             /* bfd to which this stub */
+    /* applies */
+    asection *stub_sec;                /* stub section for this bfd */
+    unsigned relocs_allocated_cnt;     /* count of relocations for this stub section */
+    unsigned real_size;
+    unsigned allocated_size;
+    int *stub_secp;            /* pointer to the next available location in the buffer */
+    char *stub_contents;       /* contents of the stubs for this bfd */
+  }
+
+Elf32_hppa_Stub_description;
+
+typedef struct Elf32_hppa_Stub_list_struct
+  {
+    Elf32_hppa_Stub_description *stub;
+    struct Elf32_hppa_Stub_list_struct *next;
+  } Elf32_hppa_Stub_list;
+
+static Elf32_hppa_Stub_list *elf_hppa_stub_rootP = NULL;
+
+/* Locate the stub section information for the given bfd. */
+static Elf32_hppa_Stub_description *
+find_stubs (abfd, stub_sec)
+     bfd *abfd;
+     asection *stub_sec;
+{
+  Elf32_hppa_Stub_list *stubP;
+
+  for (stubP = elf_hppa_stub_rootP; stubP; stubP = stubP->next)
+    {
+      if (stubP->stub->this_bfd == abfd
+         && stubP->stub->stub_sec == stub_sec)
+       return stubP->stub;
+    }
+
+  return (Elf32_hppa_Stub_description *) NULL;
+}
+
+static Elf32_hppa_Stub_description *
+new_stub (abfd, stub_sec)
+     bfd *abfd;
+     asection *stub_sec;
+{
+  Elf32_hppa_Stub_description *stub = find_stubs (abfd, stub_sec);
+
+  if (stub)
+    return stub;
+
+  stub = (Elf32_hppa_Stub_description *) bfd_zalloc (abfd, sizeof (Elf32_hppa_Stub_description));
+  stub->this_bfd = abfd;
+  stub->stub_sec = stub_sec;
+  stub->real_size = 0;
+  stub->allocated_size = 0;
+  stub->stub_contents = NULL;
+  stub->stub_secp = NULL;
+
+  return stub;
+}
+
+static void
+add_stub (stub)
+     Elf32_hppa_Stub_description *stub;
+{
+  Elf32_hppa_Stub_list *new_entry;
+
+  new_entry = (Elf32_hppa_Stub_list *) bfd_zalloc (stub->this_bfd, sizeof (Elf32_hppa_Stub_list));
+
+  if (new_entry)
+    {
+      new_entry->stub = stub;
+
+      if (elf_hppa_stub_rootP)
+       {
+         new_entry->next = elf_hppa_stub_rootP;
+         elf_hppa_stub_rootP = new_entry;
        }
+      else
+       {
+         new_entry->next = (Elf32_hppa_Stub_list *) NULL;
+         elf_hppa_stub_rootP = new_entry;
+       }
+    }
+  else
+    {
+      bfd_error = no_memory;
+      bfd_perror ("add_stub");
+    }
+}
+
+#define ARGUMENTS      0
+#define RETURN_VALUE   1
+
+#define        NO_ARG_RELOC    0
+#define R_TO_FR                1
+#define FR_TO_R                2
+#define        ARG_RELOC_ERR   3
 
-       if ( symbol_in && symbol_in->section == &bfd_und_section )
-               return bfd_reloc_undefined;
+#define ARG0   0
+#define ARG1   1
+#define ARG2   2
+#define ARG3   3
+#define RETVAL 4
 
-       sym_value = get_symbol_value(symbol_in);
+#define AR_NO  0
+#define AR_GR  1
+#define AR_FR  2
+#define AR_FU  3
 
-       /* compute value of $global$ if it is there. */
+static CONST char *CONST reloc_type_strings[] =
+{
+  "NONE", "GR->FR", "FR->GR", "ERROR"
+};
 
-       if ( global_symbol == (asymbol *)NULL ) {
-               struct elf_backend_data * bed
-                       = (struct elf_backend_data *)abfd->xvec->backend_data;
+static CONST char mismatches[4][4] =
+{                              /*      CALLEE NONE     CALLEE GR       CALLEE FR       CALLEE FU       */
+  /* CALLER NONE       */
+ {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC},
+ /* CALLER GR  */
+ {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR},
+ /* CALLER FR  */
+ {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+ /* CALLER FU  */
+ {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+};
 
-               if ( bed && bed->global_sym ) {
-                       asymbol *gsym = &bed->global_sym->symbol;
-                       global_value
-                               = gsym->value
-                                       + gsym->section->output_section->vma
-                                               + gsym->section->output_offset;
-                       GOT_value = global_value;   /* XXX: For HP-UX, GOT==DP */
-                       global_symbol = gsym;
+static CONST char retval_mismatches[4][4] =
+{                              /*      CALLEE NONE     CALLEE GR       CALLEE FR       CALLEE FU       */
+  /* CALLER NONE       */
+ {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC},
+ /* CALLER GR  */
+ {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR},
+ /* CALLER FR  */
+ {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+ /* CALLER FU  */
+ {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
+};
+
+static int
+type_of_mismatch (caller_bits, callee_bits, type)
+     int caller_bits;
+     int callee_bits;
+     int type;
+{
+  switch (type)
+    {
+    case ARGUMENTS:
+      return mismatches[caller_bits][callee_bits];
+    case RETURN_VALUE:
+      return retval_mismatches[caller_bits][callee_bits];
+    }
+
+  return 0;
+}
+
+#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);
+
+void
+hppa_elf_stub_finish (output_bfd)
+     bfd *output_bfd;
+{
+  extern bfd_error_vector_type bfd_error_vector;
+  Elf32_hppa_Stub_list *stub_list = elf_hppa_stub_rootP;
+  /* All the stubs have been built.  Finish up building        */
+  /* stub section.  Apply relocations to the section.  */
+
+  for (; stub_list; stub_list = stub_list->next)
+    {
+      if (stub_list->stub->real_size)
+       {
+         bfd *stub_bfd = stub_list->stub->this_bfd;
+         asection *stub_sec = bfd_get_section_by_name (stub_bfd, ".hppa_linker_stubs");
+         bfd_size_type reloc_size;
+         arelent **reloc_vector;
+
+         BFD_ASSERT (stub_sec == stub_list->stub->stub_sec);
+         reloc_size = bfd_get_reloc_upper_bound (stub_bfd, stub_sec);
+         reloc_vector = (arelent **) alloca (reloc_size);
+
+         BFD_ASSERT (stub_sec);
+
+         /* We are not relaxing the section, so just copy the size info */
+         stub_sec->_cooked_size = stub_sec->_raw_size;
+         stub_sec->reloc_done = true;
+
+
+         if (bfd_canonicalize_reloc (stub_bfd,
+                                     stub_sec,
+                                     reloc_vector,
+                                     output_bfd->outsymbols))
+           {
+             arelent **parent;
+             for (parent = reloc_vector; *parent != (arelent *) NULL;
+                  parent++)
+               {
+                 bfd_reloc_status_type r =
+                 bfd_perform_relocation (stub_bfd,
+                                         *parent,
+                                         stub_list->stub->stub_contents,
+                                         stub_sec, 0);
+
+
+                 if (r != bfd_reloc_ok)
+                   {
+                     switch (r)
+                       {
+                       case bfd_reloc_undefined:
+                         bfd_error_vector.undefined_symbol (*parent, NULL);
+                         break;
+                       case bfd_reloc_dangerous:
+                         bfd_error_vector.reloc_dangerous (*parent, NULL);
+                         break;
+                       case bfd_reloc_outofrange:
+                       case bfd_reloc_overflow:
+                         bfd_error_vector.reloc_value_truncated (*parent, NULL);
+                         break;
+                       default:
+                         abort ();
+                         break;
+                       }
+                   }
+               }
+           }
+
+         bfd_set_section_contents (output_bfd,
+                                   stub_sec,
+                                   stub_list->stub->stub_contents,
+                                   0,
+                                   stub_list->stub->real_size);
+
+         free (reloc_vector);
+       }
+    }
+}
+
+void
+hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */
+                           output_bfd, /* the output bfd */
+                           stub_sym,   /* the stub symbol */
+                           offset)     /* the offset within the stub buffer (pre-calculated) */
+     Elf32_hppa_Stub_description *stub_desc;
+     bfd *output_bfd;
+     asymbol *stub_sym;
+     int offset;
+{
+  /* Allocate a new relocation entry. */
+  arelent relent;
+  int size;
+
+  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);
+       }
+    }
+
+  /* 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] = stub_sym;
+  relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_ABS_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));
+}
+
+asymbol *
+hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
+     bfd *abfd;
+     bfd *output_bfd;
+     arelent *reloc_entry;
+     int stub_types[5];
+{
+  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;
+  asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
+  int i;
+  char stub_sym_name[128];
+
+  if (!stub_sec)
+    {
+      BFD_ASSERT (stub_desc == NULL);
+      stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
+      bfd_set_section_flags (output_bfd,
+                            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);
+      stub_desc = new_stub (abfd, stub_sec);
+      add_stub (stub_desc);
+    }
+
+  /* make sure we have a stub descriptor structure */
+
+  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,
+          "_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);
+  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;
+
+  /* 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;
+
+  /* generate the beginning common section for all stubs */
+
+  NEW_INSTRUCTION (stub_desc, ADDI_8_SP);
+
+  /* generate the code to move the arguments around */
+  for (i = ARG0; i < ARG3; i++)
+    {
+      if (stub_types[i] != NO_ARG_RELOC)
+       {
+         /* A stub is needed */
+         switch (stub_types[i])
+           {
+           case R_TO_FR:
+             switch (i)
+               {
+               case ARG0:
+                 NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG0);
+                 NEW_INSTRUCTION (stub_desc, FSTWS_FARG0_M8SP);
+                 break;
+               case ARG1:
+                 NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
+                 NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
+                 break;
+               case ARG2:
+                 NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
+                 NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
+                 break;
+               case ARG3:
+                 NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
+                 NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
+                 break;
+               }
+             break;
+
+           case FR_TO_R:
+             switch (i)
+               {
+               case ARG0:
+                 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG0);
+                 NEW_INSTRUCTION (stub_desc, STWS_ARG0_M8SP);
+                 break;
+               case ARG1:
+                 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
+                 NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
+                 break;
+               case ARG2:
+                 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
+                 NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
+                 break;
+               case ARG3:
+                 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
+                 NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
+                 break;
+               }
+             break;
+
+           }
+       }
+    }
+
+  /* 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);
+
+  /* generate the code to move the return value around */
+  i = RETVAL;
+  if (stub_types[i] != NO_ARG_RELOC)
+    {
+      /* A stub is needed */
+      switch (stub_types[i])
+       {
+       case R_TO_FR:
+         NEW_INSTRUCTION (stub_desc, LDWS_M8SP_RET0);
+         NEW_INSTRUCTION (stub_desc, FSTWS_FRET0_M8SP);
+         break;
+
+       case FR_TO_R:
+         NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FRET0);
+         NEW_INSTRUCTION (stub_desc, STWS_RET0_M8SP);
+         break;
+       }
+    }
+
+  /* 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);
+
+  return stub_sym;
+}
+
+int
+hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
+     bfd *abfd;
+     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.     */
+
+  if (reloc_entry->sym_ptr_ptr[0] && reloc_entry->sym_ptr_ptr[0]->section != &bfd_und_section)
+    {
+      symext_entryS caller_ar = (symext_entryS) ELF32_HPPA_R_ARG_RELOC (reloc_entry->addend);
+      symext_entryS callee_ar = elf32_hppa_get_sym_extn (abfd,
+                                               reloc_entry->sym_ptr_ptr[0],
+                                                        HPPA_SXT_ARG_RELOC);
+
+      /* Now, determine if a stub is */
+      /* required.  A stub is required if they the callee and caller   */
+      /* argument relocation bits are both nonzero and not equal.      */
+
+      if (caller_ar && callee_ar)
+       {
+         /* Both are non-zero, we need to do further checking. */
+         /* First, check if there is a return value relocation to be done */
+         int caller_loc[5];
+         int callee_loc[5];
+
+         callee_loc[RETVAL] = EXTRACT_ARBITS (callee_ar, RETVAL);
+         caller_loc[RETVAL] = EXTRACT_ARBITS (caller_ar, RETVAL);
+         callee_loc[ARG0] = EXTRACT_ARBITS (callee_ar, ARG0);
+         caller_loc[ARG0] = EXTRACT_ARBITS (caller_ar, ARG0);
+         callee_loc[ARG1] = EXTRACT_ARBITS (callee_ar, ARG1);
+         caller_loc[ARG1] = EXTRACT_ARBITS (caller_ar, ARG1);
+         callee_loc[ARG2] = EXTRACT_ARBITS (callee_ar, ARG2);
+         caller_loc[ARG2] = EXTRACT_ARBITS (caller_ar, ARG2);
+         callee_loc[ARG3] = EXTRACT_ARBITS (callee_ar, ARG3);
+         caller_loc[ARG3] = EXTRACT_ARBITS (caller_ar, ARG3);
+
+         /* Check some special combinations.  For */
+         /* example, if FU appears in ARG1 or ARG3, we */
+         /* can move it to ARG0 or ARG2, respectively. */
+
+         if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
+           {
+             caller_loc[ARG0] = AR_FU;
+             caller_loc[ARG1] = AR_NO;
+           }
+         if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
+           {
+             caller_loc[ARG2] = AR_FU;
+             caller_loc[ARG3] = AR_NO;
+           }
+         if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
+           {
+             callee_loc[ARG0] = AR_FU;
+             callee_loc[ARG1] = AR_NO;
+           }
+         if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
+           {
+             callee_loc[ARG2] = AR_FU;
+             callee_loc[ARG3] = AR_NO;
+           }
+
+         stub_types[ARG0] = type_of_mismatch (caller_loc[ARG0], callee_loc[ARG0], ARGUMENTS);
+         stub_types[ARG1] = type_of_mismatch (caller_loc[ARG1], callee_loc[ARG1], ARGUMENTS);
+         stub_types[ARG2] = type_of_mismatch (caller_loc[ARG2], callee_loc[ARG2], ARGUMENTS);
+         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: */
+         /* 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. */
+         /*    This section should never appear in an object file.  It is */
+         /*    only used internally.  The output_section of the */
+         /*    .hppa_linker_stubs section is the .text section of the */
+         /*    executable.     */
+         /* 3. Build a symbol that is used (internally only) as the entry */
+         /*    point of the stub. */
+         /* 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. */
+
+
+         if (stub_types[0]
+             || stub_types[1]
+             || stub_types[2]
+             || stub_types[3]
+             || stub_types[4])
+           {
+#ifdef DETECT_STUBS
+             fprintf (stderr, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
+                      reloc_entry->sym_ptr_ptr[0]->name,
+                      abfd->filename, reloc_entry->address,
+                      callee_ar, caller_ar);
+             for (i = ARG0; i < RETVAL; i++)
+               {
+                 if (stub_types[i] != NO_ARG_RELOC)
+                   {
+                     fprintf (stderr, "%s%d: %s ",
+                              i == RETVAL ? "ret" : "arg",
+                              i == RETVAL ? 0 : i,
+                              reloc_type_strings[stub_types[i]]);
+                   }
                }
+             fprintf (stderr, "\n");
+#endif
+             return 1;
+           }
+
+       }
+    }
+  return 0;
+}
+
+asymbol *
+hppa_elf_stub_check (abfd, output_bfd, reloc_entry)
+     bfd *abfd;
+     bfd *output_bfd;
+     arelent *reloc_entry;
+{
+  int stub_types[5];
+
+  switch (reloc_entry->howto->type)
+    {
+    case R_HPPA_ABS_CALL_11:   /*      Symbol + Addend         11      */
+    case R_HPPA_ABS_CALL_14:   /*      Symbol + Addend         14      */
+    case R_HPPA_ABS_CALL_17:   /*      Symbol + Addend         17      */
+    case R_HPPA_ABS_CALL_L21:  /*      L (Symbol, Addend)      21      */
+    case R_HPPA_ABS_CALL_R11:  /*      R (Symbol, Addend)      11      */
+    case R_HPPA_ABS_CALL_R14:  /*      R (Symbol, Addend)      14      */
+    case R_HPPA_ABS_CALL_R17:  /*      R (Symbol, Addend)      17      */
+    case R_HPPA_ABS_CALL_LS21: /*      LS(Symbol, Addend)      21      */
+    case R_HPPA_ABS_CALL_RS11: /*      RS(Symbol, Addend)      11      */
+    case R_HPPA_ABS_CALL_RS14: /*      RS(Symbol, Addend)      14      */
+    case R_HPPA_ABS_CALL_RS17: /*      RS(Symbol, Addend)      17      */
+    case R_HPPA_ABS_CALL_LD21: /*      LD(Symbol, Addend)      21      */
+    case R_HPPA_ABS_CALL_RD11: /*      RD(Symbol, Addend)      11      */
+    case R_HPPA_ABS_CALL_RD14: /*      RD(Symbol, Addend)      14      */
+    case R_HPPA_ABS_CALL_RD17: /*      RD(Symbol, Addend)      17      */
+    case R_HPPA_ABS_CALL_LR21: /*      LR(Symbol, Addend)      21      */
+    case R_HPPA_ABS_CALL_RR14: /*      RR(Symbol, Addend)      14      */
+    case R_HPPA_ABS_CALL_RR17: /*      RR(Symbol, Addend)      17      */
+
+    case R_HPPA_PCREL_CALL_11: /*      Symbol - PC + Addend    11      */
+    case R_HPPA_PCREL_CALL_14: /*      Symbol - PC + Addend    14      */
+    case R_HPPA_PCREL_CALL_17: /*      Symbol - PC + Addend    17      */
+    case R_HPPA_PCREL_CALL_12: /*      Symbol - PC + Addend    12      */
+    case R_HPPA_PCREL_CALL_L21:/*      L (Symbol - PC, Addend) 21      */
+    case R_HPPA_PCREL_CALL_R11:/*      R (Symbol - PC, Addend) 11      */
+    case R_HPPA_PCREL_CALL_R14:/*      R (Symbol - PC, Addend) 14      */
+    case R_HPPA_PCREL_CALL_R17:/*      R (Symbol - PC, Addend) 17      */
+    case R_HPPA_PCREL_CALL_LS21:       /*      LS(Symbol - PC, Addend) 21      */
+    case R_HPPA_PCREL_CALL_RS11:       /*      RS(Symbol - PC, Addend) 11      */
+    case R_HPPA_PCREL_CALL_RS14:       /*      RS(Symbol - PC, Addend) 14      */
+    case R_HPPA_PCREL_CALL_RS17:       /*      RS(Symbol - PC, Addend) 17      */
+    case R_HPPA_PCREL_CALL_LD21:       /*      LD(Symbol - PC, Addend) 21      */
+    case R_HPPA_PCREL_CALL_RD11:       /*      RD(Symbol - PC, Addend) 11      */
+    case R_HPPA_PCREL_CALL_RD14:       /*      RD(Symbol - PC, Addend) 14      */
+    case R_HPPA_PCREL_CALL_RD17:       /*      RD(Symbol - PC, Addend) 17      */
+    case R_HPPA_PCREL_CALL_LR21:       /*      LR(Symbol - PC, Addend) 21      */
+    case R_HPPA_PCREL_CALL_RR14:       /*      RR(Symbol - PC, Addend) 14      */
+    case R_HPPA_PCREL_CALL_RR17:       /*      RR(Symbol - PC, Addend) 17      */
+      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);
        }
+      break;
+
+    default:
+      break;
+
+    }
+  return reloc_entry->sym_ptr_ptr[0];
+}
+
+#define STUB_SYM_BUFFER_INC    5
+
+asymbol *
+hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt)
+     bfd *abfd;
+     bfd *output_bfd;
+     asection *asec;
+     asymbol **syms;
+     int *new_sym_cnt;
+{
+  int i;
+  int stub_types[5];
+  asymbol *new_syms = (asymbol *) NULL;
+  int new_cnt = 0;
+  int new_max = 0;
+
+  /* Relocations are in different places depending on whether this is  */
+  /* an output section or an input section.  Also, the relocations are */
+  /* in different forms.  Sigh.        */
+  /* Luckily, we have bfd_canonicalize_reloc() to straighten this out for us. */
+
+  /* if ( asec->orelocation || asec->relocation ) { */
+  if (asec->reloc_count > 0)
+    {
+      arelent **reloc_vector = (arelent **) alloca (asec->reloc_count * (sizeof (arelent *) + 1));
+
+      bfd_canonicalize_reloc (abfd, asec, reloc_vector, syms);
+      for (i = 0; i < asec->reloc_count; i++)
+       {
+#if 0
+         arelent *rle;
+
+         if ( asec->orelocation )
+           rle = asec->orelocation[i];
+         else
+           rle = asec->relocation+i;
+#endif
 
-       /* get the instruction word */
-       insn = bfd_get_32(abfd, hit_data);
-
-       /* relocate the value based on the relocation type */
-
-       /* basic_type_1:        relocation is relative to $global$              */
-       /* basic_type_2:        relocation is relative to the current GOT       */
-       /* basic_type_3:        relocation is an absolute call                  */
-       /* basic_type_4:        relocation is an PC-relative call               */
-       /* basic_type_5:        relocation is plabel reference                  */
-       /* basic_type_6:        relocation is an unwind table relocation        */
-       /* extended_type:       unimplemented                                   */
-       
-       switch ( r_type ) {
-           case R_HPPA_NONE:
-               break;
-           case R_HPPA_32:     /*              Symbol + Addend         32      */
-               
-               r_field = e_fsel;
-               goto do_basic_type_1;
-           case R_HPPA_L21:    /*              L (Symbol, Addend)      21      */
-               r_field = e_lsel;
-               goto do_basic_type_1;
-           case R_HPPA_R11:    /*              R (Symbol, Addend)      11      */
-               r_field = e_rsel;
-               goto do_basic_type_1;
-           case R_HPPA_R14:    /*              R (Symbol, Addend)      14      */
-               r_field = e_rsel;
-               goto do_basic_type_1;
-           case R_HPPA_R17:    /*              R (Symbol, Addend)      17      */
-               r_field = e_rsel;
-               goto do_basic_type_1;
-           case R_HPPA_LS21:   /*              LS(Symbol, Addend)      21      */
-               r_field = e_lssel;
-               goto do_basic_type_1;
-           case R_HPPA_RS11:   /*              RS(Symbol, Addend)      11      */
-               r_field = e_rssel;
-               goto do_basic_type_1;
-           case R_HPPA_RS14:   /*              RS(Symbol, Addend)      14      */
-               r_field = e_rssel;
-               goto do_basic_type_1;
-           case R_HPPA_RS17:   /*              RS(Symbol, Addend)      17      */
-               r_field = e_ldsel;
-               goto do_basic_type_1;
-           case R_HPPA_LD21:   /*              LD(Symbol, Addend)      21      */
-               r_field = e_ldsel;
-               goto do_basic_type_1;
-           case R_HPPA_RD11:   /*              RD(Symbol, Addend)      11      */
-               r_field = e_rdsel;
-               goto do_basic_type_1;
-           case R_HPPA_RD14:   /*              RD(Symbol, Addend)      14      */
-               r_field = e_rdsel;
-               goto do_basic_type_1;
-           case R_HPPA_RD17:   /*              RD(Symbol, Addend)      17      */
-               r_field = e_rdsel;
-               goto do_basic_type_1;
-           case R_HPPA_LR21:   /*              LR(Symbol, Addend)      21      */
-               r_field = e_lrsel;
-               goto do_basic_type_1;
-           case R_HPPA_RR14:   /*              RR(Symbol, Addend)      14      */
-               r_field = e_rrsel;
-               goto do_basic_type_1;
-           case R_HPPA_RR17:   /*              RR(Symbol, Addend)      17      */
-               r_field = e_rrsel;
-               
-           do_basic_type_1:
-               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;
-               
-           case R_HPPA_GOTOFF_11:              /*      Symbol - GOT + Addend   11      */
-               r_field = e_fsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_14:              /*      Symbol - GOT + Addend   14      */
-               r_field = e_fsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_L21:             /*      L (Sym - GOT, Addend)   21      */
-               r_field = e_lsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_R11:             /*      R (Sym - GOT, Addend)   11      */
-               r_field = e_rsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_R14:             /*      R (Sym - GOT, Addend)   14      */
-               r_field = e_rsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_LS21:    /*      LS(Sym - GOT, Addend)   21      */
-               r_field = e_lssel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_RS11:    /*      RS(Sym - GOT, Addend)   11      */
-               r_field = e_rssel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_RS14:    /*      RS(Sym - GOT, Addend)   14      */
-               r_field = e_rssel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_LD21:    /*      LD(Sym - GOT, Addend)   21      */
-               r_field = e_ldsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_RD11:    /*      RD(Sym - GOT, Addend)   11      */
-               r_field = e_rdsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_RD14:    /*      RD(Sym - GOT, Addend)   14      */
-               r_field = e_rdsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_LR21:    /*      LR(Sym - GOT, Addend)   21      */
-               r_field = e_lrsel;
-               goto do_basic_type_2;
-           case R_HPPA_GOTOFF_RR14:    /*      RR(Sym - GOT, Addend)   14      */
-               r_field = e_rrsel;
-           do_basic_type_2:
-               sym_value -= GOT_value;
-               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;
-               
+         arelent *rle = reloc_vector[i];
+
+         switch (rle->howto->type)
+           {
            case R_HPPA_ABS_CALL_11:    /*      Symbol + Addend         11      */
-               r_field = e_fsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_14:    /*      Symbol + Addend         14      */
-               r_field = e_fsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_17:    /*      Symbol + Addend         17      */
-               r_field = e_fsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_L21:   /*      L (Symbol, Addend)      21      */
-               r_field = e_lsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_R11:   /*      R (Symbol, Addend)      11      */
-               r_field = e_rsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_R14:   /*      R (Symbol, Addend)      14      */
-               r_field = e_rsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_R17:   /*      R (Symbol, Addend)      17      */
-               r_field = e_rsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_LS21:  /*      LS(Symbol, Addend)      21      */
-               r_field = e_lssel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RS11:  /*      RS(Symbol, Addend)      11      */
-               r_field = e_lssel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RS14:  /*      RS(Symbol, Addend)      14      */
-               r_field = e_rssel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RS17:  /*      RS(Symbol, Addend)      17      */
-               r_field = e_rssel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_LD21:  /*      LD(Symbol, Addend)      21      */
-               r_field = e_ldsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RD11:  /*      RD(Symbol, Addend)      11      */
-               r_field = e_rdsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RD14:  /*      RD(Symbol, Addend)      14      */
-               r_field = e_rdsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RD17:  /*      RD(Symbol, Addend)      17      */
-               r_field = e_rdsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_LR21:  /*      LR(Symbol, Addend)      21      */
-               r_field = e_lrsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RR14:  /*      RR(Symbol, Addend)      14      */
-               r_field = e_rrsel;
-               goto do_basic_type_3;
            case R_HPPA_ABS_CALL_RR17:  /*      RR(Symbol, Addend)      17      */
-               r_field = e_rrsel;
-           do_basic_type_3:
-               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;
-               
+
            case R_HPPA_PCREL_CALL_11:  /*      Symbol - PC + Addend    11      */
-               r_field = e_fsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_14:  /*      Symbol - PC + Addend    14      */
-               r_field = e_fsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_17:  /*      Symbol - PC + Addend    17      */
-               r_field = e_fsel;
-               goto do_basic_type_4;
+           case R_HPPA_PCREL_CALL_12:  /*      Symbol - PC + Addend    12      */
            case R_HPPA_PCREL_CALL_L21: /*      L (Symbol - PC, Addend) 21      */
-               r_field = e_lsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_R11: /*      R (Symbol - PC, Addend) 11      */
-               r_field = e_rsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_R14: /*      R (Symbol - PC, Addend) 14      */
-               r_field = e_rsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_R17: /*      R (Symbol - PC, Addend) 17      */
-               r_field = e_rsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_LS21:        /*      LS(Symbol - PC, Addend) 21      */
-               r_field = e_lssel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_RS11:        /*      RS(Symbol - PC, Addend) 11      */
-               r_field = e_rssel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_RS14:        /*      RS(Symbol - PC, Addend) 14      */
-               r_field = e_rssel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_RS17:        /*      RS(Symbol - PC, Addend) 17      */
-               r_field = e_rssel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_LD21:        /*      LD(Symbol - PC, Addend) 21      */
-               r_field = e_ldsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_RD11:        /*      RD(Symbol - PC, Addend) 11      */
-               r_field = e_rdsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_RD14:        /*      RD(Symbol - PC, Addend) 14      */
-               r_field = e_rdsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_RD17:        /*      RD(Symbol - PC, Addend) 17      */
-               r_field = e_rdsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_LR21:        /*      LR(Symbol - PC, Addend) 21      */
-               r_field = e_lrsel;
-               goto do_basic_type_4;
            case R_HPPA_PCREL_CALL_RR14:        /*      RR(Symbol - PC, Addend) 14      */
-               r_field = e_rrsel;
-               goto do_basic_type_4;
-           case R_HPPA_PCREL_CALL_RR17:        /*      RR(Symbol - PC, Addend) 17      */ /* #69 */
-               r_field = e_rrsel;
-           do_basic_type_4:
-               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;
-               
-           case R_HPPA_PLABEL_32:
-           case R_HPPA_PLABEL_11:
-           case R_HPPA_PLABEL_14:
-               r_field = e_fsel;
-               goto do_basic_type_5;
-           case R_HPPA_PLABEL_L21:
-               r_field = e_lsel;
-               goto do_basic_type_5;
-           case R_HPPA_PLABEL_R11:
-           case R_HPPA_PLABEL_R14:
-               r_field = e_rsel;
-           do_basic_type_5:
-               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;
-               
-           case R_HPPA_UNWIND_ENTRY:
-           case R_HPPA_UNWIND_ENTRIES:
-               hppa_elf_relocate_unwind_table(abfd, input_section, data, addr,
-                                              symbol_in, sym_value, r_addend,
-                                              r_type, r_format, r_field, r_pcrel);
-               return (bfd_reloc_ok);
-               
-           case R_HPPA_PUSH_CONST:             /*      push Addend                     -   -   */
-           case R_HPPA_PUSH_SYM:               /*      push Symbol                     -   -   */
-           case R_HPPA_PUSH_GOT:               /*      push GOT                        -   -   */
-           case R_HPPA_PUSH_PC:                /*      push PC                         -   -   */
-           case R_HPPA_PUSH_PROC:              /*      push Symbol                     -   -   */
-           case R_HPPA_PUSH_PLABEL:    /*      [TBD]                           -   -   */
-           case R_HPPA_MAX:            /*      pop A and B, push max(B,A)      -   -   */
-           case R_HPPA_MIN:            /*      pop A and B, push min(B,A)      -   -   */
-           case R_HPPA_ADD:            /*      pop A and B, push B + A         -   -   */
-           case R_HPPA_SUB:            /*      pop A and B, push B - A         -   -   */
-           case R_HPPA_MULT:           /*      pop A and B, push B * A         -   -   */
-           case R_HPPA_DIV:            /*      pop A and B, push B / A         -   -   */
-           case R_HPPA_MOD:            /*      pop A and B, push B % A         -   -   */
-           case R_HPPA_AND:            /*      pop A and B, push B & A         -   -   */
-           case R_HPPA_OR:                     /*      pop A and B, push B | A         -   -   */
-           case R_HPPA_XOR:            /*      pop A and B, push B ^ A         -   -   */
-           case R_HPPA_NOT:            /*      pop A, push ~A                  -   -   */
-           case R_HPPA_LSHIFT:         /*      pop A, push A << Addend         -   -   */
-           case R_HPPA_ARITH_RSHIFT:   /*      pop A, push A >> Addend         -   -   */
-           case R_HPPA_LOGIC_RSHIFT:   /*      pop A, push A >> Addend         -   -   */
-           case R_HPPA_EXPR_F:         /*      pop A, push A + Addend          L   -   */
-           case R_HPPA_EXPR_L:         /*      pop A, push L(A,Addend)         L   -   */
-           case R_HPPA_EXPR_R:         /*      pop A, push R(A,Addend)         R   -   */
-           case R_HPPA_EXPR_LS:                /*      pop A, push LS(A,Addend)        LS  -   */
-           case R_HPPA_EXPR_RS:                /*      pop A, push RS(A,Addend)        RS  -   */
-           case R_HPPA_EXPR_LD:                /*      pop A, push LD(A,Addend)        LD  -   */
-           case R_HPPA_EXPR_RD:                /*      pop A, push RD(A,Addend)        RD  -   */
-           case R_HPPA_EXPR_LR:                /*      pop A, push LR(A,Addend)        LR  -   */
-           case R_HPPA_EXPR_RR:                /*      pop A, push RR(A,Addend)        RR  -   */
-               
-           case R_HPPA_EXPR_32:                /*      pop                             -   32  */
-           case R_HPPA_EXPR_21:                /*      pop                             -   21  */
-           case R_HPPA_EXPR_11:                /*      pop                             -   11  */
-           case R_HPPA_EXPR_14:                /*      pop                             -   14  */
-           case R_HPPA_EXPR_17:                /*      pop                             -   17  */
-           case R_HPPA_EXPR_12:                /*      pop                             -   12  */
-               fprintf(stderr, "Relocation problem: ");
-               fprintf(stderr,"Unimplemented reloc type %d, in module %s\n",
-                       r_type,abfd->filename);
-               return(bfd_reloc_notsupported);
-           default:
-               fprintf(stderr,"Relocation problem : ");
-               fprintf(stderr,"Unrecognized reloc type %d, in module %s\n",
-                       r_type,abfd->filename); 
-               return (bfd_reloc_dangerous);
-       }
-
-       /* update the instruction word */
-       bfd_put_32(abfd, insn ,hit_data);
+           case R_HPPA_PCREL_CALL_RR17:        /*      RR(Symbol - PC, Addend) 17      */
+             if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types))
+               {
+                 /* generate a stub */
+                 /* keep track of the new symbol */
+                 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));
+               }
+             break;
 
-       return (bfd_reloc_ok);
+           default:
+             break;
 
+           }
+       }
+    }
+  *new_sym_cnt = new_cnt;
+  return new_syms;
 }
 
-static reloc_howto_type *
-elf_hppa_reloc_type_lookup (arch, code)
-     bfd_arch_info_type *arch;
-     bfd_reloc_code_real_type code;
+int
+hppa_look_for_stubs (abfd, output_bfd)
+     bfd *abfd;
+     bfd *output_bfd;
 {
-  if (code < R_HPPA_UNIMPLEMENTED)
-    return &elf_hppa_howto_table[code];
+  /* bfd_map_over_sections(abfd,hppa_look_for_stubs_in_section,(PTR)output_bfd,NULL); */
+}
 
-  return (reloc_howto_type *)0;
+boolean
+DEFUN (hppa_elf_get_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)
+{
+  /* if this is the linker stub section, then we have the      */
+  /* section contents in memory rather than on disk.   */
+  if (strcmp (section->name, ".hppa_linker_stubs") == 0)
+    {
+      Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, section);
+
+      if (count == 0)
+       return true;
+      if ((bfd_size_type) (offset + count) > section->_raw_size)
+       return (false);         /* on error */
+      if ((bfd_size_type) (offset + count) > stub_desc->real_size)
+       return (false);         /* on error */
+
+      memcpy (location, stub_desc->stub_contents + offset, count);
+      return (true);
+    }
+  /* if this is the symbol extension section, then we have the */
+  /* section contents in memory rather than on disk.   */
+  else if (strcmp (section->name, ".hppa_symextn") == 0)
+    {
+      if (count == 0)
+       return true;
+      if ((bfd_size_type) (offset + count) > section->_raw_size)
+       return (false);         /* on error */
+      if ((bfd_size_type) (offset + count) > symextn_contents_real_size)
+       return (false);         /* on error */
+
+      memcpy (location, symextn_contents + offset, count);
+      return (true);
+    }
+  else
+    return bfd_generic_get_section_contents (abfd, section, location, offset, count);
 }
-#define elf_bfd_reloc_type_lookup      elf_hppa_reloc_type_lookup
 
 static void
 DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst),
-       bfd *abfd AND
-       arelent *cache_ptr AND
-       Elf_Internal_Rela *dst)
+       bfd * abfd AND
+       arelent * cache_ptr AND
+       Elf32_Internal_Rela * dst)
 {
   abort ();
 }
 
-#define TARGET_BIG_SYM         elf32_hppa_vec
+#define TARGET_BIG_SYM         bfd_elf32_hppa_vec
 #define TARGET_BIG_NAME                "elf32-hppa"
 #define ELF_ARCH               bfd_arch_hppa