home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / gnu / gdb-4.12.tar.gz / gdb-4.12.tar / gdb-4.12 / bfd / elf32-hppa.c < prev    next >
C/C++ Source or Header  |  1994-02-03  |  109KB  |  3,705 lines

  1. /* BFD back-end for HP PA-RISC ELF files.
  2.    Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  3.  
  4.    Written by
  5.  
  6.     Center for Software Science
  7.     Department of Computer Science
  8.     University of Utah
  9.  
  10. This file is part of BFD, the Binary File Descriptor library.
  11.  
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; either version 2 of the License, or
  15. (at your option) any later version.
  16.  
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. GNU General Public License for more details.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with this program; if not, write to the Free Software
  24. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  25.  
  26. #include "bfd.h"
  27. #include "sysdep.h"
  28. #include "libbfd.h"
  29. #include "obstack.h"
  30. #include "bfdlink.h"
  31. #include "libelf.h"
  32.  
  33. /* ELF32/HPPA relocation support
  34.  
  35.     This file contains ELF32/HPPA relocation support as specified
  36.     in the Stratus FTX/Golf Object File Format (SED-1762) dated
  37.     November 19, 1992.
  38. */
  39.  
  40. #include "elf32-hppa.h"
  41. #include "libhppa.h"
  42. #include "aout/aout64.h"
  43. #include "hppa_stubs.h"
  44.  
  45. /* ELF/PA relocation howto entries */
  46.  
  47. static bfd_reloc_status_type hppa_elf_reloc
  48.   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
  49.  
  50. static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
  51. {
  52. /*  'bitpos' and 'abs' are obsolete */
  53. /* type            rs sz bsz pcrel  bpos abs    ovrf  sf           name */
  54. /* 9.3.4. Address relocation types */
  55.   {R_HPPA_NONE, 0, 3, 19, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NONE"},
  56.   {R_HPPA_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_32"},
  57.   {R_HPPA_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_11"},
  58.   {R_HPPA_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_14"},
  59.   {R_HPPA_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_17"},
  60. {R_HPPA_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L21"},
  61. {R_HPPA_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R11"},
  62. {R_HPPA_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R14"},
  63. {R_HPPA_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R17"},
  64.   {R_HPPA_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LS21"},
  65.   {R_HPPA_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS11"},
  66.   {R_HPPA_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS14"},
  67.   {R_HPPA_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS17"},
  68.   {R_HPPA_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LD21"},
  69.   {R_HPPA_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD11"},
  70.   {R_HPPA_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD14"},
  71.   {R_HPPA_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD17"},
  72.   {R_HPPA_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LR21"},
  73.   {R_HPPA_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR14"},
  74.   {R_HPPA_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR17"},
  75. /* 9.3.5. GOTOFF address relocation types        */
  76.   {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_11"},
  77.   {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_14"},
  78.   {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"},
  79.   {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"},
  80.   {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"},
  81.   {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"},
  82.   {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"},
  83.   {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"},
  84.   {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"},
  85.   {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"},
  86.   {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"},
  87.   {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"},
  88.   {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"},
  89. /* 9.3.6. Absolute call relocation types    */
  90.   {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"},
  91.   {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"},
  92.   {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"},
  93.   {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"},
  94.   {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"},
  95.   {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"},
  96.   {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"},
  97.   {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"},
  98.   {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"},
  99.   {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"},
  100.   {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"},
  101.   {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"},
  102.   {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"},
  103.   {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"},
  104.   {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"},
  105.   {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"},
  106.   {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"},
  107.   {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"},
  108. /* 9.3.7. PC-relative call relocation types    */
  109.   {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"},
  110.   {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"},
  111.   {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"},
  112.   {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"},
  113.   {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"},
  114.   {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"},
  115.   {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"},
  116.   {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"},
  117.   {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"},
  118.   {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"},
  119.   {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"},
  120.   {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"},
  121.   {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"},
  122.   {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"},
  123.   {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"},
  124.   {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"},
  125.   {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"},
  126.   {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"},
  127.   {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"},
  128.  
  129. /* 9.3.8. Plabel relocation types */
  130.   {R_HPPA_PLABEL_32, 0, 3, 32, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_32"},
  131.   {R_HPPA_PLABEL_11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_11"},
  132.   {R_HPPA_PLABEL_14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_14"},
  133.   {R_HPPA_PLABEL_L21, 0, 3, 21, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_L21"},
  134.   {R_HPPA_PLABEL_R11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R11"},
  135.   {R_HPPA_PLABEL_R14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R14"},
  136.  
  137. /* 9.3.9. Data linkage table (DLT) relocation types    */
  138.   {R_HPPA_DLT_32, 0, 3, 32, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_32"},
  139.   {R_HPPA_DLT_11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_11"},
  140.   {R_HPPA_DLT_14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_14"},
  141.   {R_HPPA_DLT_L21, 0, 3, 21, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_L21"},
  142.   {R_HPPA_DLT_R11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R11"},
  143.   {R_HPPA_DLT_R14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R14"},
  144.  
  145. /* 9.3.10. Relocations for unwinder tables    */
  146.   {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
  147.   {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"},
  148.  
  149. /*  9.3.11. Relocation types for complex expressions    */
  150.   {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_CONST"},
  151.   {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PC"},
  152.   {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_SYM"},
  153.   {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"},
  154.   {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"},
  155.   {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"},
  156.   {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"},
  157. {R_HPPA_MAX, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MAX"},
  158. {R_HPPA_MIN, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MIN"},
  159. {R_HPPA_ADD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ADD"},
  160. {R_HPPA_SUB, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_SUB"},
  161.   {R_HPPA_MULT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MULT"},
  162. {R_HPPA_DIV, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_DIV"},
  163. {R_HPPA_MOD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MOD"},
  164. {R_HPPA_AND, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_AND"},
  165.   {R_HPPA_OR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_OR"},
  166. {R_HPPA_XOR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_XOR"},
  167. {R_HPPA_NOT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NOT"},
  168.   {R_HPPA_LSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LSHIFT"},
  169.   {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"},
  170.   {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"},
  171. {R_HPPA_EXPR_F, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L"},
  172.   {R_HPPA_EXPR_L, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_L"},
  173.   {R_HPPA_EXPR_R, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_R"},
  174.   {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LS"},
  175.   {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RS"},
  176.   {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LD"},
  177.   {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RD"},
  178.   {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LR"},
  179.   {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RR"},
  180.  
  181.   {R_HPPA_EXPR_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_32"},
  182.   {R_HPPA_EXPR_21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_21"},
  183.   {R_HPPA_EXPR_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_11"},
  184.   {R_HPPA_EXPR_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_14"},
  185.   {R_HPPA_EXPR_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_17"},
  186.   {R_HPPA_EXPR_12, 0, 3, 12, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_12"},
  187.   {R_HPPA_STUB_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_STUB_CALL_17"},
  188.   {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_HPPA_UNIMPLEMENTED"},
  189. };
  190.  
  191. static symext_chainS *symext_rootP;
  192. static symext_chainS *symext_lastP;
  193. static boolean symext_chain_built;
  194.  
  195. static unsigned long
  196. DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format),
  197.        bfd * abfd AND
  198.        unsigned long insn AND
  199.        unsigned long value AND
  200.        unsigned short r_type AND
  201.        unsigned short r_field AND
  202.        unsigned short r_format)
  203. {
  204.   unsigned long const_part;    /* part of the instruction that does not change */
  205.   unsigned long rebuilt_part;
  206.  
  207.   switch (r_format)
  208.     {
  209.     case 11:
  210.       {
  211.     unsigned w1, w;
  212.  
  213.     const_part = insn & 0xffffe002;
  214.     dis_assemble_12 (value, &w1, &w);
  215.     rebuilt_part = (w1 << 2) | w;
  216.     return const_part | rebuilt_part;
  217.       }
  218.  
  219.     case 12:
  220.       {
  221.     unsigned w1, w;
  222.  
  223.     const_part = insn & 0xffffe002;
  224.     dis_assemble_12 (value, &w1, &w);
  225.     rebuilt_part = (w1 << 2) | w;
  226.     return const_part | rebuilt_part;
  227.       }
  228.  
  229.     case 14:
  230.       const_part = insn & 0xffffc000;
  231.       low_sign_unext (value, 14, &rebuilt_part);
  232.       return const_part | rebuilt_part;
  233.  
  234.     case 17:
  235.       {
  236.     unsigned w1, w2, w;
  237.  
  238.     const_part = insn & 0xffe0e002;
  239.     dis_assemble_17 (value, &w1, &w2, &w);
  240.     rebuilt_part = (w2 << 2) | (w1 << 16) | w;
  241.     return const_part | rebuilt_part;
  242.       }
  243.  
  244.     case 21:
  245.       const_part = insn & 0xffe00000;
  246.       dis_assemble_21 (value, &rebuilt_part);
  247.       return const_part | rebuilt_part;
  248.  
  249.     case 32:
  250.       const_part = 0;
  251.       return value;
  252.  
  253.     default:
  254.       fprintf (stderr, "Relocation problem : ");
  255.       fprintf (stderr,
  256.            "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
  257.            r_type, r_format, r_field, abfd->filename);
  258.     }
  259.   return insn;
  260. }
  261.  
  262. static unsigned long
  263. DEFUN (hppa_elf_relocate_insn,
  264.        (abfd, input_sect,
  265.     insn, address, symp, sym_value, r_addend,
  266.     r_type, r_format, r_field, pcrel),
  267.        bfd * abfd AND
  268.        asection * input_sect AND
  269.        unsigned long insn AND
  270.        unsigned long address AND
  271.        asymbol * symp AND
  272.        long sym_value AND
  273.        long r_addend AND
  274.        unsigned short r_type AND
  275.        unsigned short r_format AND
  276.        unsigned short r_field AND
  277.        unsigned char pcrel)
  278. {
  279.   unsigned char opcode = get_opcode (insn);
  280.   long constant_value;
  281.   unsigned arg_reloc;
  282.  
  283.   switch (opcode)
  284.     {
  285.     case LDO:
  286.     case LDB:
  287.     case LDH:
  288.     case LDW:
  289.     case LDWM:
  290.     case STB:
  291.     case STH:
  292.     case STW:
  293.     case STWM:
  294.       constant_value = HPPA_R_CONSTANT (r_addend);
  295.       BFD_ASSERT (r_format == 14);
  296.  
  297.       if (pcrel)
  298.     sym_value -= address;
  299.       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
  300.       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
  301.  
  302.     case COMICLR:
  303.     case SUBI:            /* case SUBIO: */
  304.     case ADDIT:        /* case ADDITO: */
  305.     case ADDI:            /* case ADDIO: */
  306.       BFD_ASSERT (r_format == 11);
  307.  
  308.       constant_value = HPPA_R_CONSTANT(r_addend);
  309.       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
  310.       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
  311.  
  312.     case LDIL:
  313.     case ADDIL:
  314.       BFD_ASSERT (r_format == 21);
  315.  
  316.       constant_value = HPPA_R_CONSTANT (r_addend);
  317.       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
  318.       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
  319.  
  320.     case BL:
  321.     case BE:
  322.     case BLE:
  323.       arg_reloc = HPPA_R_ARG_RELOC (r_addend);
  324.  
  325.       BFD_ASSERT (r_format == 17);
  326.  
  327.       /* XXX computing constant_value is not needed??? */
  328.       constant_value = assemble_17 ((insn & 0x001f0000) >> 16,
  329.                     (insn & 0x00001ffc) >> 2,
  330.                     insn & 1);
  331.       /* @@ Assumes only 32 bits.  */
  332.       constant_value = (constant_value << 15) >> 15;
  333.       if (pcrel)
  334.     {
  335.       sym_value -=
  336.         address + input_sect->output_offset
  337.         + input_sect->output_section->vma;
  338.       sym_value = hppa_field_adjust (sym_value, -8, r_field);
  339.     }
  340.       else
  341.     sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
  342.  
  343.       return hppa_elf_rebuild_insn (abfd, insn, sym_value >> 2, r_type, r_field, r_format);
  344.  
  345.     default:
  346.       if (opcode == 0)
  347.     {
  348.       BFD_ASSERT (r_format == 32);
  349.       constant_value = HPPA_R_CONSTANT (r_addend);
  350.  
  351.       return hppa_field_adjust (sym_value, constant_value, r_field);
  352.     }
  353.       else
  354.     {
  355.       fprintf (stderr,
  356.            "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
  357.            opcode, r_format, r_field);
  358.       return insn;
  359.     }
  360.     }
  361. }
  362.  
  363. static void
  364. DEFUN (hppa_elf_relocate_unwind_table,
  365.        (abfd, input_sect,
  366.     data, address, symp, sym_value, r_addend,
  367.     r_type, r_format, r_field, pcrel),
  368.        bfd * abfd AND
  369.        asection * input_sect AND
  370.        PTR data AND
  371.        unsigned long address AND
  372.        asymbol * symp AND
  373.        long sym_value AND
  374.        long r_addend AND
  375.        unsigned short r_type AND
  376.        unsigned short r_format AND
  377.        unsigned short r_field AND
  378.        unsigned char pcrel)
  379. {
  380.   bfd_byte *hit_data = address + (bfd_byte *) (data);
  381.   long start_offset;
  382.   long end_offset;
  383.   long relocated_value;
  384.   int i;
  385.  
  386.   BFD_ASSERT (r_format == 32);
  387.   BFD_ASSERT (r_field == e_fsel);
  388.   switch (r_type)
  389.     {
  390.     case R_HPPA_UNWIND_ENTRY:
  391.       start_offset = bfd_get_32 (abfd, hit_data);
  392.       relocated_value = hppa_field_adjust (sym_value, start_offset, r_field);
  393.       bfd_put_32 (abfd, relocated_value, hit_data);
  394.  
  395.       hit_data += sizeof (unsigned long);
  396.       end_offset = bfd_get_32 (abfd, hit_data);
  397.       relocated_value = hppa_field_adjust (sym_value, end_offset, r_field);
  398.       bfd_put_32 (abfd, relocated_value, hit_data);
  399.       break;
  400.  
  401.     case R_HPPA_UNWIND_ENTRIES:
  402.       for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long))
  403.     {
  404.       unsigned int adjustment;
  405.       start_offset = bfd_get_32 (abfd, hit_data);
  406.       /* Stuff the symbol value into the first word */
  407.       /* of the  unwind descriptor */
  408.       bfd_put_32 (abfd, sym_value, hit_data);
  409.       adjustment = sym_value - start_offset;
  410.  
  411.       hit_data += sizeof (unsigned long);
  412.       end_offset = adjustment + bfd_get_32 (abfd, hit_data);
  413.       bfd_put_32 (abfd, end_offset, hit_data);
  414.  
  415.       /* If this is not the last unwind entry, */
  416.       /* adjust the symbol value. */
  417.       if (i + 1 < r_addend)
  418.         {
  419.           start_offset = bfd_get_32 (abfd, hit_data + 3 * sizeof (unsigned long));
  420.               sym_value = start_offset + adjustment;
  421.         }
  422.     }
  423.       break;
  424.  
  425.     default:
  426.       fprintf (stderr,
  427.            "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
  428.            r_type, r_format, r_field);
  429.     }
  430. }
  431.  
  432. /* Provided the symbol, returns the value reffed */
  433. static long
  434. get_symbol_value (symbol)
  435.      asymbol *symbol;
  436. {
  437.   long relocation = 0;
  438.  
  439.   if (symbol == (asymbol *) NULL)
  440.     relocation = 0;
  441.   else if (symbol->section == &bfd_com_section)
  442.     {
  443.       relocation = 0;
  444.     }
  445.   else
  446.     {
  447.       relocation = symbol->value +
  448.     symbol->section->output_section->vma +
  449.     symbol->section->output_offset;
  450.     }
  451.  
  452.   return (relocation);
  453. }
  454.  
  455. /* This function provides a pretty straight-forward mapping between a */
  456. /* base relocation type, format and field into the relocation type */
  457. /* that will be emitted in an object file.  The only wrinkle in the */
  458. /* mapping is that when the T, TR, TL, P, PR, or PL expression */
  459. /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
  460. /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
  461. /* (in the case of P, PR, and PL).    */
  462.  
  463. /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
  464. /* handled yet. */
  465.  
  466. static void
  467. hppa_elf_gen_reloc_error (base_type, fmt, field)
  468.      elf32_hppa_reloc_type base_type;
  469.      int fmt;
  470.      int field;
  471. {
  472.   fprintf (stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
  473.        base_type, fmt, field);
  474. }
  475.  
  476. elf32_hppa_reloc_type **
  477. hppa_elf_gen_reloc_type (abfd, base_type, format, field)
  478.      bfd *abfd;
  479.      elf32_hppa_reloc_type base_type;
  480.      int format;
  481.      int field;
  482. {
  483. #define UNDEFINED    hppa_elf_gen_reloc_error(base_type,format,field)
  484.  
  485.   elf32_hppa_reloc_type *finaltype;
  486.   elf32_hppa_reloc_type **final_types;
  487.   int i;
  488.  
  489.   final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2);
  490.   BFD_ASSERT (final_types != 0);
  491.  
  492.   finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type));
  493.   BFD_ASSERT (finaltype != 0);
  494.  
  495.   final_types[0] = finaltype;
  496.   final_types[1] = NULL;
  497.  
  498. #define final_type finaltype[0]
  499.  
  500.   final_type = base_type;
  501.  
  502.   switch (base_type)
  503.     {
  504.     case R_HPPA:
  505.       switch (format)
  506.     {
  507.     case 11:
  508.       switch (field)
  509.         {
  510.         case e_fsel:
  511.           final_type = R_HPPA_11;
  512.           break;
  513.         case e_rsel:
  514.           final_type = R_HPPA_R11;
  515.           break;
  516.         case e_rssel:
  517.           final_type = R_HPPA_RS11;
  518.           break;
  519.         case e_rdsel:
  520.           final_type = R_HPPA_RD11;
  521.           break;
  522.  
  523.         case e_psel:
  524.           final_type = R_HPPA_PLABEL_11;
  525.           break;
  526.         case e_rpsel:
  527.           final_type = R_HPPA_PLABEL_R11;
  528.           break;
  529.         case e_tsel:
  530.           final_type = R_HPPA_DLT_11;
  531.           break;
  532.         case e_rtsel:
  533.           final_type = R_HPPA_DLT_R11;
  534.           break;
  535.  
  536.         case e_lpsel:
  537.         case e_ltsel:
  538.         case e_lsel:
  539.         case e_lrsel:
  540.         case e_lssel:
  541.         case e_rrsel:
  542.         default:
  543.           UNDEFINED;
  544.           final_type = base_type;
  545.           break;
  546.         }
  547.       break;
  548.     case 12:
  549.       UNDEFINED;
  550.       break;
  551.     case 14:
  552.       switch (field)
  553.         {
  554.         case e_rsel:
  555.           final_type = R_HPPA_R14;
  556.           break;
  557.         case e_rssel:
  558.           final_type = R_HPPA_RS14;
  559.           break;
  560.         case e_rdsel:
  561.           final_type = R_HPPA_RD14;
  562.           break;
  563.         case e_rrsel:
  564.           final_type = R_HPPA_RR14;
  565.           break;
  566.  
  567.         case e_psel:
  568.           final_type = R_HPPA_PLABEL_14;
  569.           break;
  570.         case e_rpsel:
  571.           final_type = R_HPPA_PLABEL_R14;
  572.           break;
  573.         case e_tsel:
  574.           final_type = R_HPPA_DLT_14;
  575.           break;
  576.         case e_rtsel:
  577.           final_type = R_HPPA_DLT_R14;
  578.           break;
  579.  
  580.         case e_lpsel:
  581.         case e_ltsel:
  582.  
  583.         case e_fsel:
  584.         case e_lsel:
  585.         case e_lssel:
  586.         case e_ldsel:
  587.         case e_lrsel:
  588.         default:
  589.           UNDEFINED;
  590.           final_type = base_type;
  591.           break;
  592.         }
  593.       break;
  594.     case 17:
  595.       switch (field)
  596.         {
  597.         case e_fsel:
  598.           final_type = R_HPPA_17;
  599.           break;
  600.         case e_rsel:
  601.           final_type = R_HPPA_R17;
  602.           break;
  603.         case e_rssel:
  604.           final_type = R_HPPA_RS17;
  605.           break;
  606.         case e_rdsel:
  607.           final_type = R_HPPA_RD17;
  608.           break;
  609.         case e_rrsel:
  610.           final_type = R_HPPA_RR17;
  611.           break;
  612.         case e_lsel:
  613.         case e_lssel:
  614.         case e_ldsel:
  615.         case e_lrsel:
  616.         default:
  617.           UNDEFINED;
  618.           final_type = base_type;
  619.           break;
  620.         }
  621.       break;
  622.     case 21:
  623.       switch (field)
  624.         {
  625.         case e_lsel:
  626.           final_type = R_HPPA_L21;
  627.           break;
  628.         case e_lssel:
  629.           final_type = R_HPPA_LS21;
  630.           break;
  631.         case e_ldsel:
  632.           final_type = R_HPPA_LD21;
  633.           break;
  634.         case e_lrsel:
  635.           final_type = R_HPPA_LR21;
  636.           break;
  637.         case e_lpsel:
  638.           final_type = R_HPPA_PLABEL_L21;
  639.           break;
  640.         case e_ltsel:
  641.           final_type = R_HPPA_PLABEL_L21;
  642.           break;
  643.         case e_rsel:
  644.         case e_rssel:
  645.         case e_rdsel:
  646.         case e_rrsel:
  647.         case e_fsel:
  648.         default:
  649.           UNDEFINED;
  650.           final_type = base_type;
  651.           break;
  652.         }
  653.       break;
  654.     case 32:
  655.       switch (field)
  656.         {
  657.         case e_fsel:
  658.           final_type = R_HPPA_32;
  659.           break;
  660.         case e_psel:
  661.           final_type = R_HPPA_PLABEL_32;
  662.           break;
  663.         case e_tsel:
  664.           final_type == R_HPPA_DLT_32;
  665.           break;
  666.         default:
  667.           UNDEFINED;
  668.           final_type = base_type;
  669.           break;
  670.         }
  671.       break;
  672.     default:
  673.       UNDEFINED;
  674.       final_type = base_type;
  675.       break;
  676.     }
  677.       break;
  678.     case R_HPPA_GOTOFF:
  679.       switch (format)
  680.     {
  681.     case 11:
  682.       switch (field)
  683.         {
  684.         case e_rsel:
  685.           final_type = R_HPPA_GOTOFF_R11;
  686.           break;
  687.         case e_rssel:
  688.           final_type = R_HPPA_GOTOFF_RS11;
  689.           break;
  690.         case e_rdsel:
  691.           final_type = R_HPPA_GOTOFF_RD11;
  692.           break;
  693.         case e_fsel:
  694.           final_type = R_HPPA_GOTOFF_11;
  695.           break;
  696.         case e_lsel:
  697.         case e_lrsel:
  698.         case e_lssel:
  699.         case e_rrsel:
  700.         default:
  701.           UNDEFINED;
  702.           final_type = base_type;
  703.           break;
  704.         }
  705.       break;
  706.     case 12:
  707.       UNDEFINED;
  708.       final_type = base_type;
  709.       break;
  710.     case 14:
  711.       switch (field)
  712.         {
  713.         case e_rsel:
  714.           final_type = R_HPPA_GOTOFF_R14;
  715.           break;
  716.         case e_rssel:
  717.           final_type = R_HPPA_GOTOFF_RS14;
  718.           break;
  719.         case e_rdsel:
  720.           final_type = R_HPPA_GOTOFF_RD14;
  721.           break;
  722.         case e_rrsel:
  723.           final_type = R_HPPA_GOTOFF_RR14;
  724.           break;
  725.         case e_fsel:
  726.           final_type = R_HPPA_GOTOFF_14;
  727.           break;
  728.         case e_lsel:
  729.         case e_lssel:
  730.         case e_ldsel:
  731.         case e_lrsel:
  732.         default:
  733.           UNDEFINED;
  734.           final_type = base_type;
  735.           break;
  736.         }
  737.       break;
  738.     case 17:
  739.       UNDEFINED;
  740.       final_type = base_type;
  741.       break;
  742.     case 21:
  743.       switch (field)
  744.         {
  745.         case e_lsel:
  746.           final_type = R_HPPA_GOTOFF_L21;
  747.           break;
  748.         case e_lssel:
  749.           final_type = R_HPPA_GOTOFF_LS21;
  750.           break;
  751.         case e_ldsel:
  752.           final_type = R_HPPA_GOTOFF_LD21;
  753.           break;
  754.         case e_lrsel:
  755.           final_type = R_HPPA_GOTOFF_LR21;
  756.           break;
  757.         case e_rsel:
  758.         case e_rssel:
  759.         case e_rdsel:
  760.         case e_rrsel:
  761.         case e_fsel:
  762.         default:
  763.           UNDEFINED;
  764.           final_type = base_type;
  765.           break;
  766.         }
  767.       break;
  768.     case 32:
  769.       UNDEFINED;
  770.       final_type = base_type;
  771.       break;
  772.     default:
  773.       UNDEFINED;
  774.       final_type = base_type;
  775.       break;
  776.     }
  777.       break;
  778.     case R_HPPA_PCREL_CALL:
  779.       switch (format)
  780.     {
  781.     case 11:
  782.       switch (field)
  783.         {
  784.         case e_rsel:
  785.           final_type = R_HPPA_PCREL_CALL_R11;
  786.           break;
  787.         case e_rssel:
  788.           final_type = R_HPPA_PCREL_CALL_RS11;
  789.           break;
  790.         case e_rdsel:
  791.           final_type = R_HPPA_PCREL_CALL_RD11;
  792.           break;
  793.         case e_fsel:
  794.           final_type = R_HPPA_PCREL_CALL_11;
  795.           break;
  796.         case e_lsel:
  797.         case e_lrsel:
  798.         case e_lssel:
  799.         case e_rrsel:
  800.         default:
  801.           UNDEFINED;
  802.           final_type = base_type;
  803.           break;
  804.         }
  805.       break;
  806.     case 12:
  807.       UNDEFINED;
  808.       final_type = base_type;
  809.       break;
  810.     case 14:
  811.       switch (field)
  812.         {
  813.         case e_rsel:
  814.           final_type = R_HPPA_PCREL_CALL_R14;
  815.           break;
  816.         case e_rssel:
  817.           final_type = R_HPPA_PCREL_CALL_RS14;
  818.           break;
  819.         case e_rdsel:
  820.           final_type = R_HPPA_PCREL_CALL_RD14;
  821.           break;
  822.         case e_rrsel:
  823.           final_type = R_HPPA_PCREL_CALL_RR14;
  824.           break;
  825.         case e_fsel:
  826.           final_type = R_HPPA_PCREL_CALL_14;
  827.           break;
  828.         case e_lsel:
  829.         case e_lssel:
  830.         case e_ldsel:
  831.         case e_lrsel:
  832.         default:
  833.           UNDEFINED;
  834.           final_type = base_type;
  835.           break;
  836.         }
  837.       break;
  838.     case 17:
  839.       switch (field)
  840.         {
  841.         case e_rsel:
  842.           final_type = R_HPPA_PCREL_CALL_R17;
  843.           break;
  844.         case e_rssel:
  845.           final_type = R_HPPA_PCREL_CALL_RS17;
  846.           break;
  847.         case e_rdsel:
  848.           final_type = R_HPPA_PCREL_CALL_RD17;
  849.           break;
  850.         case e_rrsel:
  851.           final_type = R_HPPA_PCREL_CALL_RR17;
  852.           break;
  853.         case e_fsel:
  854.           final_type = R_HPPA_PCREL_CALL_17;
  855.           break;
  856.         case e_lsel:
  857.         case e_lssel:
  858.         case e_ldsel:
  859.         case e_lrsel:
  860.         default:
  861.           UNDEFINED;
  862.           final_type = base_type;
  863.           break;
  864.         }
  865.       break;
  866.     case 21:
  867.       switch (field)
  868.         {
  869.         case e_lsel:
  870.           final_type = R_HPPA_PCREL_CALL_L21;
  871.           break;
  872.         case e_lssel:
  873.           final_type = R_HPPA_PCREL_CALL_LS21;
  874.           break;
  875.         case e_ldsel:
  876.           final_type = R_HPPA_PCREL_CALL_LD21;
  877.           break;
  878.         case e_lrsel:
  879.           final_type = R_HPPA_PCREL_CALL_LR21;
  880.           break;
  881.         case e_rsel:
  882.         case e_rssel:
  883.         case e_rdsel:
  884.         case e_rrsel:
  885.         case e_fsel:
  886.         default:
  887.           UNDEFINED;
  888.           final_type = base_type;
  889.           break;
  890.         }
  891.       break;
  892.     case 32:
  893.       UNDEFINED;
  894.       final_type = base_type;
  895.       break;
  896.     default:
  897.       UNDEFINED;
  898.       final_type = base_type;
  899.       break;
  900.     }
  901.       break;
  902.     case R_HPPA_PLABEL:
  903.       switch (format)
  904.     {
  905.     case 11:
  906.       switch (field)
  907.         {
  908.         case e_fsel:
  909.           final_type = R_HPPA_PLABEL_11;
  910.           break;
  911.         case e_rsel:
  912.           final_type = R_HPPA_PLABEL_R11;
  913.           break;
  914.         default:
  915.           UNDEFINED;
  916.           final_type = base_type;
  917.           break;
  918.         }
  919.       break;
  920.     case 14:
  921.       switch (field)
  922.         {
  923.         case e_fsel:
  924.           final_type = R_HPPA_PLABEL_14;
  925.           break;
  926.         case e_rsel:
  927.           final_type = R_HPPA_PLABEL_R14;
  928.           break;
  929.         default:
  930.           UNDEFINED;
  931.           final_type = base_type;
  932.           break;
  933.         }
  934.       break;
  935.     case 21:
  936.       switch (field)
  937.         {
  938.         case e_lsel:
  939.           final_type = R_HPPA_PLABEL_L21;
  940.           break;
  941.         default:
  942.           UNDEFINED;
  943.           final_type = base_type;
  944.           break;
  945.         }
  946.       break;
  947.     case 32:
  948.       switch (field)
  949.         {
  950.         case e_fsel:
  951.           final_type = R_HPPA_PLABEL_32;
  952.           break;
  953.         default:
  954.           UNDEFINED;
  955.           final_type = base_type;
  956.           break;
  957.         }
  958.       break;
  959.     default:
  960.       UNDEFINED;
  961.       final_type = base_type;
  962.       break;
  963.     }
  964.     case R_HPPA_ABS_CALL:
  965.       switch (format)
  966.     {
  967.     case 11:
  968.       switch (field)
  969.         {
  970.         case e_rsel:
  971.           final_type = R_HPPA_ABS_CALL_R11;
  972.           break;
  973.         case e_rssel:
  974.           final_type = R_HPPA_ABS_CALL_RS11;
  975.           break;
  976.         case e_rdsel:
  977.           final_type = R_HPPA_ABS_CALL_RD11;
  978.           break;
  979.         case e_fsel:
  980.           final_type = R_HPPA_ABS_CALL_11;
  981.           break;
  982.         case e_lsel:
  983.         case e_lrsel:
  984.         case e_lssel:
  985.         case e_rrsel:
  986.         default:
  987.           UNDEFINED;
  988.           final_type = base_type;
  989.           break;
  990.         }
  991.       break;
  992.     case 12:
  993.       UNDEFINED;
  994.       final_type = base_type;
  995.       break;
  996.     case 14:
  997.       switch (field)
  998.         {
  999.         case e_rsel:
  1000.           final_type = R_HPPA_ABS_CALL_R14;
  1001.           break;
  1002.         case e_rssel:
  1003.           final_type = R_HPPA_ABS_CALL_RS14;
  1004.           break;
  1005.         case e_rdsel:
  1006.           final_type = R_HPPA_ABS_CALL_RD14;
  1007.           break;
  1008.         case e_rrsel:
  1009.           final_type = R_HPPA_ABS_CALL_RR14;
  1010.           break;
  1011.         case e_fsel:
  1012.           final_type = R_HPPA_ABS_CALL_14;
  1013.           break;
  1014.         case e_lsel:
  1015.         case e_lssel:
  1016.         case e_ldsel:
  1017.         case e_lrsel:
  1018.         default:
  1019.           UNDEFINED;
  1020.           final_type = base_type;
  1021.           break;
  1022.         }
  1023.       break;
  1024.     case 17:
  1025.       switch (field)
  1026.         {
  1027.         case e_rsel:
  1028.           final_type = R_HPPA_ABS_CALL_R17;
  1029.           break;
  1030.         case e_rssel:
  1031.           final_type = R_HPPA_ABS_CALL_RS17;
  1032.           break;
  1033.         case e_rdsel:
  1034.           final_type = R_HPPA_ABS_CALL_RD17;
  1035.           break;
  1036.         case e_rrsel:
  1037.           final_type = R_HPPA_ABS_CALL_RR17;
  1038.           break;
  1039.         case e_fsel:
  1040.           final_type = R_HPPA_ABS_CALL_17;
  1041.           break;
  1042.         case e_lsel:
  1043.         case e_lssel:
  1044.         case e_ldsel:
  1045.         case e_lrsel:
  1046.         default:
  1047.           UNDEFINED;
  1048.           final_type = base_type;
  1049.           break;
  1050.         }
  1051.       break;
  1052.     case 21:
  1053.       switch (field)
  1054.         {
  1055.         case e_lsel:
  1056.           final_type = R_HPPA_ABS_CALL_L21;
  1057.           break;
  1058.         case e_lssel:
  1059.           final_type = R_HPPA_ABS_CALL_LS21;
  1060.           break;
  1061.         case e_ldsel:
  1062.           final_type = R_HPPA_ABS_CALL_LD21;
  1063.           break;
  1064.         case e_lrsel:
  1065.           final_type = R_HPPA_ABS_CALL_LR21;
  1066.           break;
  1067.         case e_rsel:
  1068.         case e_rssel:
  1069.         case e_rdsel:
  1070.         case e_rrsel:
  1071.         case e_fsel:
  1072.         default:
  1073.           UNDEFINED;
  1074.           final_type = base_type;
  1075.           break;
  1076.         }
  1077.       break;
  1078.     case 32:
  1079.       UNDEFINED;
  1080.       final_type = base_type;
  1081.       break;
  1082.     default:
  1083.       UNDEFINED;
  1084.       final_type = base_type;
  1085.       break;
  1086.     }
  1087.       break;
  1088.     case R_HPPA_UNWIND:
  1089.       final_type = R_HPPA_UNWIND_ENTRY;
  1090.       break;
  1091.     case R_HPPA_COMPLEX:
  1092.     case R_HPPA_COMPLEX_PCREL_CALL:
  1093.     case R_HPPA_COMPLEX_ABS_CALL:
  1094.       final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 6);
  1095.       BFD_ASSERT (final_types != 0);
  1096.  
  1097.       finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type) * 5);
  1098.       BFD_ASSERT (finaltype != 0);
  1099.  
  1100.       for (i = 0; i < 5; i++)
  1101.     final_types[i] = &finaltype[i];
  1102.  
  1103.       final_types[5] = NULL;
  1104.  
  1105.       finaltype[0] = R_HPPA_PUSH_SYM;
  1106.  
  1107.       if (base_type == R_HPPA_COMPLEX)
  1108.     finaltype[1] = R_HPPA_PUSH_SYM;
  1109.       else if (base_type == R_HPPA_COMPLEX_PCREL_CALL)
  1110.     finaltype[1] = R_HPPA_PUSH_PCREL_CALL;
  1111.       else            /* base_type == R_HPPA_COMPLEX_ABS_CALL */
  1112.     finaltype[1] = R_HPPA_PUSH_ABS_CALL;
  1113.  
  1114.       finaltype[2] = R_HPPA_SUB;
  1115.  
  1116.       switch (field)
  1117.     {
  1118.     case e_fsel:
  1119.       finaltype[3] = R_HPPA_EXPR_F;
  1120.       break;
  1121.     case e_lsel:
  1122.       finaltype[3] = R_HPPA_EXPR_L;
  1123.       break;
  1124.     case e_rsel:
  1125.       finaltype[3] = R_HPPA_EXPR_R;
  1126.       break;
  1127.     case e_lssel:
  1128.       finaltype[3] = R_HPPA_EXPR_LS;
  1129.       break;
  1130.     case e_rssel:
  1131.       finaltype[3] = R_HPPA_EXPR_RS;
  1132.       break;
  1133.     case e_ldsel:
  1134.       finaltype[3] = R_HPPA_EXPR_LD;
  1135.       break;
  1136.     case e_rdsel:
  1137.       finaltype[3] = R_HPPA_EXPR_RD;
  1138.       break;
  1139.     case e_lrsel:
  1140.       finaltype[3] = R_HPPA_EXPR_LR;
  1141.       break;
  1142.     case e_rrsel:
  1143.       finaltype[3] = R_HPPA_EXPR_RR;
  1144.       break;
  1145.     }
  1146.  
  1147.       switch (format)
  1148.     {
  1149.     case 11:
  1150.       finaltype[4] = R_HPPA_EXPR_11;
  1151.       break;
  1152.     case 12:
  1153.       finaltype[4] = R_HPPA_EXPR_12;
  1154.       break;
  1155.     case 14:
  1156.       finaltype[4] = R_HPPA_EXPR_14;
  1157.       break;
  1158.     case 17:
  1159.       finaltype[4] = R_HPPA_EXPR_17;
  1160.       break;
  1161.     case 21:
  1162.       finaltype[4] = R_HPPA_EXPR_21;
  1163.       break;
  1164.     case 32:
  1165.       finaltype[4] = R_HPPA_EXPR_32;
  1166.       break;
  1167.     }
  1168.  
  1169.       break;
  1170.  
  1171.     default:
  1172.       final_type = base_type;
  1173.       break;
  1174.     }
  1175.  
  1176.   return final_types;
  1177. }
  1178.  
  1179. #undef final_type
  1180.  
  1181.  
  1182. /* this function is in charge of performing all the HP PA relocations */
  1183. static long global_value;
  1184. static long GOT_value;    /* XXX:  need to calculate this! For HPUX, GOT == DP */
  1185. static asymbol *global_symbol;
  1186. static int global_sym_defined;
  1187.  
  1188. static bfd_reloc_status_type
  1189. hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
  1190.         error_message)
  1191.      bfd *abfd;
  1192.      arelent *reloc_entry;
  1193.      asymbol *symbol_in;
  1194.      PTR data;
  1195.      asection *input_section;
  1196.      bfd *output_bfd;
  1197.      char **error_message;
  1198. {
  1199.   unsigned long insn;
  1200.   long sym_value = 0;
  1201.   unsigned long addr = reloc_entry->address;
  1202.   bfd_byte *hit_data = addr + (bfd_byte *) (data);
  1203.   unsigned short r_type = reloc_entry->howto->type & 0xFF;
  1204.   unsigned short r_field = e_fsel;
  1205.   boolean r_pcrel = reloc_entry->howto->pc_relative;
  1206.   unsigned r_format = reloc_entry->howto->bitsize;
  1207.   long r_addend = reloc_entry->addend;
  1208.  
  1209.   if (output_bfd)
  1210.     {
  1211.       /* Partial linking - do nothing */
  1212.       reloc_entry->address += input_section->output_offset;
  1213.       return bfd_reloc_ok;
  1214.     }
  1215.  
  1216.   /* If performing final link and the symbol we're relocating against
  1217.      is undefined, then return an error.  */ 
  1218.   if (symbol_in && symbol_in->section == &bfd_und_section)
  1219.     return bfd_reloc_undefined;
  1220.  
  1221.   sym_value = get_symbol_value (symbol_in);
  1222.  
  1223.   /* Compute the value of $global$.  */
  1224.   if (!global_sym_defined)
  1225.     {
  1226.       if (global_symbol)
  1227.     {
  1228.       global_value = (global_symbol->value
  1229.               + global_symbol->section->output_section->vma
  1230.               + global_symbol->section->output_offset);
  1231.       GOT_value = global_value;
  1232.       global_sym_defined++;
  1233.     }
  1234.     }
  1235.  
  1236.   /* Get the instruction word.  */
  1237.   insn = bfd_get_32 (abfd, hit_data);
  1238.  
  1239.   /* Relocate the value based on one of the basic relocation types
  1240.  
  1241.    basic_type_1:    relocation is relative to $global$
  1242.    basic_type_2:    relocation is relative to the current GOT
  1243.    basic_type_3:    relocation is an absolute call
  1244.    basic_type_4:    relocation is an PC-relative call
  1245.    basic_type_5:    relocation is plabel reference
  1246.    basic_type_6:    relocation is an unwind table relocation
  1247.    extended_type:    unimplemented  */
  1248.  
  1249.   switch (r_type)
  1250.     {
  1251.     case R_HPPA_NONE:
  1252.       break;
  1253.  
  1254.     /* Handle all the basic type 1 relocations.  */
  1255.     case R_HPPA_32:
  1256.       r_field = e_fsel;
  1257.       goto do_basic_type_1;
  1258.     case R_HPPA_11:
  1259.       r_field = e_fsel;
  1260.       goto do_basic_type_1;
  1261.     case R_HPPA_14:
  1262.       r_field = e_fsel;
  1263.       goto do_basic_type_1;
  1264.     case R_HPPA_17:
  1265.       r_field = e_fsel;
  1266.       goto do_basic_type_1;
  1267.     case R_HPPA_L21:
  1268.       r_field = e_lsel;
  1269.       goto do_basic_type_1;
  1270.     case R_HPPA_R11:
  1271.       r_field = e_rsel;
  1272.       goto do_basic_type_1;
  1273.     case R_HPPA_R14:
  1274.       r_field = e_rsel;
  1275.       goto do_basic_type_1;
  1276.     case R_HPPA_R17:
  1277.       r_field = e_rsel;
  1278.       goto do_basic_type_1;
  1279.     case R_HPPA_LS21:
  1280.       r_field = e_lssel;
  1281.       goto do_basic_type_1;
  1282.     case R_HPPA_RS11:
  1283.       r_field = e_rssel;
  1284.       goto do_basic_type_1;
  1285.     case R_HPPA_RS14:
  1286.       r_field = e_rssel;
  1287.       goto do_basic_type_1;
  1288.     case R_HPPA_RS17:
  1289.       r_field = e_ldsel;
  1290.       goto do_basic_type_1;
  1291.     case R_HPPA_LD21:
  1292.       r_field = e_ldsel;
  1293.       goto do_basic_type_1;
  1294.     case R_HPPA_RD11:
  1295.       r_field = e_rdsel;
  1296.       goto do_basic_type_1;
  1297.     case R_HPPA_RD14:
  1298.       r_field = e_rdsel;
  1299.       goto do_basic_type_1;
  1300.     case R_HPPA_RD17:
  1301.       r_field = e_rdsel;
  1302.       goto do_basic_type_1;
  1303.     case R_HPPA_LR21:
  1304.       r_field = e_lrsel;
  1305.       goto do_basic_type_1;
  1306.     case R_HPPA_RR14:
  1307.       r_field = e_rrsel;
  1308.       goto do_basic_type_1;
  1309.     case R_HPPA_RR17:
  1310.       r_field = e_rrsel;
  1311.  
  1312.     do_basic_type_1:
  1313.       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
  1314.                      symbol_in, sym_value, r_addend,
  1315.                      r_type, r_format, r_field, r_pcrel);
  1316.       break;
  1317.  
  1318.     /* Handle all the basic type 2 relocations.  */
  1319.     case R_HPPA_GOTOFF_11:
  1320.       r_field = e_fsel;
  1321.       goto do_basic_type_2;
  1322.     case R_HPPA_GOTOFF_14:
  1323.       r_field = e_fsel;
  1324.       goto do_basic_type_2;
  1325.     case R_HPPA_GOTOFF_L21:
  1326.       r_field = e_lsel;
  1327.       goto do_basic_type_2;
  1328.     case R_HPPA_GOTOFF_R11:
  1329.       r_field = e_rsel;
  1330.       goto do_basic_type_2;
  1331.     case R_HPPA_GOTOFF_R14:
  1332.       r_field = e_rsel;
  1333.       goto do_basic_type_2;
  1334.     case R_HPPA_GOTOFF_LS21:
  1335.       r_field = e_lssel;
  1336.       goto do_basic_type_2;
  1337.     case R_HPPA_GOTOFF_RS11:
  1338.       r_field = e_rssel;
  1339.       goto do_basic_type_2;
  1340.     case R_HPPA_GOTOFF_RS14:
  1341.       r_field = e_rssel;
  1342.       goto do_basic_type_2;
  1343.     case R_HPPA_GOTOFF_LD21:
  1344.       r_field = e_ldsel;
  1345.       goto do_basic_type_2;
  1346.     case R_HPPA_GOTOFF_RD11:
  1347.       r_field = e_rdsel;
  1348.       goto do_basic_type_2;
  1349.     case R_HPPA_GOTOFF_RD14:
  1350.       r_field = e_rdsel;
  1351.       goto do_basic_type_2;
  1352.     case R_HPPA_GOTOFF_LR21:
  1353.       r_field = e_lrsel;
  1354.       goto do_basic_type_2;
  1355.     case R_HPPA_GOTOFF_RR14:
  1356.       r_field = e_rrsel;
  1357.  
  1358.     do_basic_type_2:
  1359.       sym_value -= GOT_value;
  1360.       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
  1361.                      symbol_in, sym_value, r_addend,
  1362.                      r_type, r_format, r_field, r_pcrel);
  1363.       break;
  1364.  
  1365.     /* Handle all the basic type 3 relocations.  */
  1366.     case R_HPPA_ABS_CALL_11:
  1367.       r_field = e_fsel;
  1368.       goto do_basic_type_3;
  1369.     case R_HPPA_ABS_CALL_14:
  1370.       r_field = e_fsel;
  1371.       goto do_basic_type_3;
  1372.     case R_HPPA_ABS_CALL_17:
  1373.       r_field = e_fsel;
  1374.       goto do_basic_type_3;
  1375.     case R_HPPA_ABS_CALL_L21:
  1376.       r_field = e_lsel;
  1377.       goto do_basic_type_3;
  1378.     case R_HPPA_ABS_CALL_R11:
  1379.       r_field = e_rsel;
  1380.       goto do_basic_type_3;
  1381.     case R_HPPA_ABS_CALL_R14:
  1382.       r_field = e_rsel;
  1383.       goto do_basic_type_3;
  1384.     case R_HPPA_ABS_CALL_R17:
  1385.       r_field = e_rsel;
  1386.       goto do_basic_type_3;
  1387.     case R_HPPA_ABS_CALL_LS21:
  1388.       r_field = e_lssel;
  1389.       goto do_basic_type_3;
  1390.     case R_HPPA_ABS_CALL_RS11:
  1391.       r_field = e_lssel;
  1392.       goto do_basic_type_3;
  1393.     case R_HPPA_ABS_CALL_RS14:
  1394.       r_field = e_rssel;
  1395.       goto do_basic_type_3;
  1396.     case R_HPPA_ABS_CALL_RS17:
  1397.       r_field = e_rssel;
  1398.       goto do_basic_type_3;
  1399.     case R_HPPA_ABS_CALL_LD21:
  1400.       r_field = e_ldsel;
  1401.       goto do_basic_type_3;
  1402.     case R_HPPA_ABS_CALL_RD11:
  1403.       r_field = e_rdsel;
  1404.       goto do_basic_type_3;
  1405.     case R_HPPA_ABS_CALL_RD14:
  1406.       r_field = e_rdsel;
  1407.       goto do_basic_type_3;
  1408.     case R_HPPA_ABS_CALL_RD17:
  1409.       r_field = e_rdsel;
  1410.       goto do_basic_type_3;
  1411.     case R_HPPA_ABS_CALL_LR21:
  1412.       r_field = e_lrsel;
  1413.       goto do_basic_type_3;
  1414.     case R_HPPA_ABS_CALL_RR14:
  1415.       r_field = e_rrsel;
  1416.       goto do_basic_type_3;
  1417.     case R_HPPA_ABS_CALL_RR17:
  1418.       r_field = e_rrsel;
  1419.  
  1420.     do_basic_type_3:
  1421.       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
  1422.                      symbol_in, sym_value, r_addend,
  1423.                      r_type, r_format, r_field, r_pcrel);
  1424.       break;
  1425.  
  1426.     /* Handle all the basic type 4 relocations.  */  
  1427.     case R_HPPA_PCREL_CALL_11:
  1428.       r_field = e_fsel;
  1429.       goto do_basic_type_4;
  1430.     case R_HPPA_PCREL_CALL_14:
  1431.       r_field = e_fsel;
  1432.       goto do_basic_type_4;
  1433.     case R_HPPA_PCREL_CALL_17:
  1434.       r_field = e_fsel;
  1435.       goto do_basic_type_4;
  1436.     case R_HPPA_PCREL_CALL_L21:
  1437.       r_field = e_lsel;
  1438.       goto do_basic_type_4;
  1439.     case R_HPPA_PCREL_CALL_R11:
  1440.       r_field = e_rsel;
  1441.       goto do_basic_type_4;
  1442.     case R_HPPA_PCREL_CALL_R14:
  1443.       r_field = e_rsel;
  1444.       goto do_basic_type_4;
  1445.     case R_HPPA_PCREL_CALL_R17:
  1446.       r_field = e_rsel;
  1447.       goto do_basic_type_4;
  1448.     case R_HPPA_PCREL_CALL_LS21:
  1449.       r_field = e_lssel;
  1450.       goto do_basic_type_4;
  1451.     case R_HPPA_PCREL_CALL_RS11:
  1452.       r_field = e_rssel;
  1453.       goto do_basic_type_4;
  1454.     case R_HPPA_PCREL_CALL_RS14:
  1455.       r_field = e_rssel;
  1456.       goto do_basic_type_4;
  1457.     case R_HPPA_PCREL_CALL_RS17:
  1458.       r_field = e_rssel;
  1459.       goto do_basic_type_4;
  1460.     case R_HPPA_PCREL_CALL_LD21:
  1461.       r_field = e_ldsel;
  1462.       goto do_basic_type_4;
  1463.     case R_HPPA_PCREL_CALL_RD11:
  1464.       r_field = e_rdsel;
  1465.       goto do_basic_type_4;
  1466.     case R_HPPA_PCREL_CALL_RD14:
  1467.       r_field = e_rdsel;
  1468.       goto do_basic_type_4;
  1469.     case R_HPPA_PCREL_CALL_RD17:
  1470.       r_field = e_rdsel;
  1471.       goto do_basic_type_4;
  1472.     case R_HPPA_PCREL_CALL_LR21:
  1473.       r_field = e_lrsel;
  1474.       goto do_basic_type_4;
  1475.     case R_HPPA_PCREL_CALL_RR14:
  1476.       r_field = e_rrsel;
  1477.       goto do_basic_type_4;
  1478.     case R_HPPA_PCREL_CALL_RR17:
  1479.       r_field = e_rrsel;
  1480.  
  1481.     do_basic_type_4:
  1482.       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
  1483.                      symbol_in, sym_value, r_addend,
  1484.                      r_type, r_format, r_field, r_pcrel);
  1485.       break;
  1486.  
  1487.     /* Handle all the basic type 5 relocations.  */  
  1488.     case R_HPPA_PLABEL_32:
  1489.     case R_HPPA_PLABEL_11:
  1490.     case R_HPPA_PLABEL_14:
  1491.       r_field = e_fsel;
  1492.       goto do_basic_type_5;
  1493.     case R_HPPA_PLABEL_L21:
  1494.       r_field = e_lsel;
  1495.       goto do_basic_type_5;
  1496.     case R_HPPA_PLABEL_R11:
  1497.     case R_HPPA_PLABEL_R14:
  1498.       r_field = e_rsel;
  1499.     do_basic_type_5:
  1500.       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
  1501.                      symbol_in, sym_value, r_addend,
  1502.                      r_type, r_format, r_field, r_pcrel);
  1503.       break;
  1504.  
  1505.     /* Handle all basic type 6 relocations.  */
  1506.     case R_HPPA_UNWIND_ENTRY:
  1507.     case R_HPPA_UNWIND_ENTRIES:
  1508.       hppa_elf_relocate_unwind_table (abfd, input_section, data, addr,
  1509.                       symbol_in, sym_value, r_addend,
  1510.                       r_type, r_format, r_field, r_pcrel);
  1511.       return bfd_reloc_ok;
  1512.  
  1513.     /* Handle the stack operations and similar braindamage.  */
  1514.     case R_HPPA_PUSH_CONST:
  1515.     case R_HPPA_PUSH_PC:
  1516.     case R_HPPA_PUSH_SYM:
  1517.     case R_HPPA_PUSH_GOTOFF:
  1518.     case R_HPPA_PUSH_ABS_CALL:
  1519.     case R_HPPA_PUSH_PCREL_CALL:
  1520.     case R_HPPA_PUSH_PLABEL:
  1521.     case R_HPPA_MAX:
  1522.     case R_HPPA_MIN:
  1523.     case R_HPPA_ADD:
  1524.     case R_HPPA_SUB:
  1525.     case R_HPPA_MULT:
  1526.     case R_HPPA_DIV:
  1527.     case R_HPPA_MOD:
  1528.     case R_HPPA_AND:
  1529.     case R_HPPA_OR:
  1530.     case R_HPPA_XOR:
  1531.     case R_HPPA_NOT:
  1532.     case R_HPPA_LSHIFT:
  1533.     case R_HPPA_ARITH_RSHIFT:
  1534.     case R_HPPA_LOGIC_RSHIFT:
  1535.     case R_HPPA_EXPR_F:
  1536.     case R_HPPA_EXPR_L:
  1537.     case R_HPPA_EXPR_R:
  1538.     case R_HPPA_EXPR_LS:
  1539.     case R_HPPA_EXPR_RS:
  1540.     case R_HPPA_EXPR_LD:
  1541.     case R_HPPA_EXPR_RD:
  1542.     case R_HPPA_EXPR_LR:
  1543.     case R_HPPA_EXPR_RR:
  1544.     case R_HPPA_EXPR_32:
  1545.     case R_HPPA_EXPR_21:
  1546.     case R_HPPA_EXPR_11:
  1547.     case R_HPPA_EXPR_14:
  1548.     case R_HPPA_EXPR_17:
  1549.     case R_HPPA_EXPR_12:
  1550.       fprintf (stderr, "Relocation problem: ");
  1551.       fprintf (stderr, "Unimplemented reloc type %d, in module %s\n",
  1552.            r_type, abfd->filename);
  1553.       return bfd_reloc_notsupported;
  1554.  
  1555.     /* This is a linker internal relocation.  */
  1556.     case R_HPPA_STUB_CALL_17:
  1557.       /* This relocation is for a branch to a long branch stub.
  1558.      Change instruction to a BLE,N.  It may also be necessary
  1559.      to change interchange the branch and its delay slot.
  1560.      The original instruction stream is
  1561.  
  1562.         bl <foo>,r        ; call foo using register r as
  1563.                 ; the return pointer
  1564.         XXX            ; delay slot instruction
  1565.  
  1566.      The new instruction stream will be:
  1567.  
  1568.         XXX            ; delay slot instruction
  1569.         ble <foo_stub>    ; call the long call stub for foo
  1570.                 ; using r31 as the return pointer
  1571.  
  1572.      This braindamage is necessary because the compiler may put
  1573.      an instruction which uses %r31 in the delay slot of the original
  1574.      call.  By changing the call instruction from a "bl" to a "ble"
  1575.      %r31 gets clobbered before the delay slot executes.
  1576.  
  1577.      We do not interchange the branch and delay slot if the delay
  1578.      slot was already nullified, or if the instruction in the delay
  1579.      slot modifies the return pointer to avoid an unconditional
  1580.      jump after the call returns (GCC optimization).  */
  1581.      
  1582.       if (insn & 2)
  1583.         {
  1584.       insn = BLE_N_XXX_0_0;
  1585.       bfd_put_32 (abfd, insn, hit_data);
  1586.       r_type = R_HPPA_ABS_CALL_17;
  1587.       r_pcrel = 0;
  1588.       insn = hppa_elf_relocate_insn (abfd, input_section, insn,
  1589.                      addr, symbol_in, sym_value,
  1590.                      r_addend, r_type, r_format,
  1591.                      r_field, r_pcrel);
  1592.         }
  1593.       else
  1594.     {
  1595.       unsigned long old_delay_slot_insn = bfd_get_32 (abfd, hit_data + 4);
  1596.       unsigned rtn_reg = (insn & 0x03e00000) >> 21;
  1597.  
  1598.       if (get_opcode (old_delay_slot_insn) == LDO)
  1599.         {
  1600.           unsigned ldo_src_reg = (old_delay_slot_insn & 0x03e00000) >> 21;
  1601.           unsigned ldo_target_reg = (old_delay_slot_insn & 0x001f0000) >> 16;
  1602.  
  1603.           /* If the target of the LDO is the same as the return
  1604.          register then there is no reordering.  We can leave the
  1605.          instuction as a non-nullified BLE in this case.  */
  1606.           if (ldo_target_reg == rtn_reg)
  1607.         {
  1608.           unsigned long new_delay_slot_insn = old_delay_slot_insn;
  1609.  
  1610.           BFD_ASSERT(ldo_src_reg == ldo_target_reg);
  1611.           new_delay_slot_insn &= 0xfc00ffff;
  1612.           new_delay_slot_insn |= ((31 << 21) | (31 << 16));
  1613.           bfd_put_32 (abfd, new_delay_slot_insn, hit_data + 4);
  1614.           insn = BLE_XXX_0_0;
  1615.           r_type = R_HPPA_ABS_CALL_17;
  1616.           r_pcrel = 0;
  1617.           insn = hppa_elf_relocate_insn (abfd, input_section, insn,
  1618.                          addr, symbol_in, sym_value,
  1619.                          r_addend, r_type, r_format,
  1620.                          r_field, r_pcrel);
  1621.           bfd_put_32 (abfd, insn, hit_data);
  1622.           return bfd_reloc_ok;
  1623.         }
  1624.               else if (rtn_reg == 31)
  1625.                 {
  1626.                   /* The return register is r31, so this is a millicode
  1627.              call.  Do not perform any instruction reordering.  */
  1628.               insn = BLE_XXX_0_0;
  1629.               r_type = R_HPPA_ABS_CALL_17;
  1630.               r_pcrel = 0;
  1631.               insn = hppa_elf_relocate_insn (abfd, input_section, insn,
  1632.                              addr, symbol_in, sym_value,
  1633.                              r_addend, r_type, r_format,
  1634.                              r_field, r_pcrel);
  1635.               bfd_put_32 (abfd, insn, hit_data);
  1636.               return bfd_reloc_ok;
  1637.                 }
  1638.           else
  1639.         {
  1640.           /* Check to see if the delay slot instruction has a
  1641.              relocation.  If so, we need to change the address
  1642.              field of it, because the instruction it relocates
  1643.              is going to be moved.  */
  1644.           arelent * next_reloc_entry = reloc_entry+1;
  1645.  
  1646.           if (next_reloc_entry->address == reloc_entry->address + 4)
  1647.             next_reloc_entry->address -= 4;
  1648.  
  1649.           insn = old_delay_slot_insn;
  1650.           bfd_put_32 (abfd, insn, hit_data);
  1651.           insn = BLE_N_XXX_0_0;
  1652.           bfd_put_32 (abfd, insn, hit_data + 4);
  1653.           r_type = R_HPPA_ABS_CALL_17;
  1654.           r_pcrel = 0;
  1655.           insn = hppa_elf_relocate_insn (abfd, input_section, insn,
  1656.                          addr + 4, symbol_in, 
  1657.                          sym_value, r_addend, r_type,
  1658.                          r_format, r_field, r_pcrel);
  1659.           bfd_put_32 (abfd, insn, hit_data + 4);
  1660.           return bfd_reloc_ok;
  1661.         }
  1662.         }
  1663.           else if (rtn_reg == 31)
  1664.             {
  1665.               /* The return register is r31, so this is a millicode call.
  1666.          Perform no instruction reordering in this case.  */
  1667.           insn = BLE_XXX_0_0;
  1668.           r_type = R_HPPA_ABS_CALL_17;
  1669.           r_pcrel = 0;
  1670.           insn = hppa_elf_relocate_insn (abfd, input_section, insn,
  1671.                          addr, symbol_in, sym_value,
  1672.                          r_addend, r_type, r_format,
  1673.                          r_field, r_pcrel);
  1674.           bfd_put_32 (abfd, insn, hit_data);
  1675.           return bfd_reloc_ok;
  1676.             }
  1677.       else
  1678.         {
  1679.           /* Check to see if the delay slot instruction has a
  1680.          relocation.  If so, we need to change its address
  1681.          field  because the instruction it relocates is going
  1682.          to be moved.  */
  1683.           arelent * next_reloc_entry = reloc_entry+1;
  1684.  
  1685.           if (next_reloc_entry->address == reloc_entry->address + 4)
  1686.         next_reloc_entry->address -= 4;
  1687.  
  1688.           insn = old_delay_slot_insn;
  1689.           bfd_put_32 (abfd, insn, hit_data);
  1690.           insn = BLE_N_XXX_0_0;
  1691.           bfd_put_32 (abfd, insn, hit_data + 4);
  1692.           r_type = R_HPPA_ABS_CALL_17;
  1693.           r_pcrel = 0;
  1694.           insn = hppa_elf_relocate_insn (abfd, input_section, insn,
  1695.                          addr + 4, symbol_in, sym_value,
  1696.                          r_addend, r_type, r_format,
  1697.                          r_field, r_pcrel);
  1698.           bfd_put_32 (abfd, insn, hit_data + 4);
  1699.           return bfd_reloc_ok;
  1700.         }
  1701.     }
  1702.       break;
  1703.       
  1704.     default:
  1705.       *error_message = (char *) "Unrecognized reloc";
  1706.       return bfd_reloc_dangerous;
  1707.     }
  1708.  
  1709.   /* Update the instruction word.  */
  1710.   bfd_put_32 (abfd, insn, hit_data);
  1711.   return (bfd_reloc_ok);
  1712. }
  1713.  
  1714. static const reloc_howto_type *
  1715. elf_hppa_reloc_type_lookup (arch, code)
  1716.      bfd_arch_info_type *arch;
  1717.      bfd_reloc_code_real_type code;
  1718. {
  1719.   if ((int) code < (int) R_HPPA_UNIMPLEMENTED)
  1720.     {
  1721.       BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
  1722.       return &elf_hppa_howto_table[(int) code];
  1723.     }
  1724.  
  1725.   return (reloc_howto_type *) 0;
  1726. }
  1727.  
  1728. #define bfd_elf32_bfd_reloc_type_lookup    elf_hppa_reloc_type_lookup
  1729.  
  1730.  
  1731. void
  1732. DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx),
  1733.        bfd * abfd AND
  1734.        elf_symbol_type * symbolP AND
  1735.        int sym_idx)
  1736. {
  1737.   symext_chainS *symextP;
  1738.   unsigned int arg_reloc;
  1739.  
  1740.   /* Only functions can have argument relocations.  */
  1741.   if (!(symbolP->symbol.flags & BSF_FUNCTION))
  1742.     return;
  1743.  
  1744.   arg_reloc = symbolP->tc_data.hppa_arg_reloc;
  1745.  
  1746.   /* If there are no argument relocation bits, then no relocation is
  1747.      necessary.  Do not add this to the symextn section.  */
  1748.   if (arg_reloc == 0)
  1749.     return;
  1750.  
  1751.   symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
  1752.  
  1753.   symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
  1754.   symextP[0].next = &symextP[1];
  1755.  
  1756.   symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
  1757.   symextP[1].next = NULL;
  1758.  
  1759.   if (symext_rootP == NULL)
  1760.     {
  1761.       symext_rootP = &symextP[0];
  1762.       symext_lastP = &symextP[1];
  1763.     }
  1764.   else
  1765.     {
  1766.       symext_lastP->next = &symextP[0];
  1767.       symext_lastP = &symextP[1];
  1768.     }
  1769. }
  1770.  
  1771. /* Accessor function for the list of symbol extension records. */
  1772. symext_chainS *elf32_hppa_get_symextn_chain()
  1773. {
  1774.   return symext_rootP;
  1775. }
  1776.  
  1777. static symext_entryS *symextn_contents;
  1778. static unsigned int symextn_contents_real_size;
  1779.  
  1780. void
  1781. DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
  1782.        bfd * abfd AND
  1783.        PTR ignored)
  1784. {
  1785.   symext_chainS *symextP;
  1786.   int size;
  1787.   int n;
  1788.   int i;
  1789.   void hppa_elf_stub_finish ();    /* forward declaration */
  1790.   asection *symextn_sec;
  1791.  
  1792.   hppa_elf_stub_finish (abfd);
  1793.  
  1794.   if (symext_rootP == NULL)
  1795.     return;
  1796.  
  1797.   for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
  1798.     ;
  1799.  
  1800.   size = sizeof (symext_entryS) * n;
  1801.   symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
  1802.   if (symextn_sec == (asection *) 0)
  1803.     {
  1804.       symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
  1805.       bfd_set_section_flags (abfd,
  1806.                  symextn_sec,
  1807.      SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE | SEC_READONLY);
  1808.       symextn_sec->output_section = symextn_sec;
  1809.       symextn_sec->output_offset = 0;
  1810.       bfd_set_section_alignment (abfd, symextn_sec, 2);
  1811.     }
  1812.   symextn_contents = (symext_entryS *) bfd_alloc (abfd, size);
  1813.  
  1814.   for (i = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++i)
  1815.     symextn_contents[i] = symextP->entry;
  1816.   symextn_contents_real_size = size;
  1817.   bfd_set_section_size (abfd, symextn_sec, symextn_contents_real_size);
  1818.  
  1819.   return;
  1820. }
  1821.  
  1822. /* Support for HP PA-RISC stub generation.
  1823.  
  1824.    Written by
  1825.  
  1826.     Center for Software Science
  1827.     Department of Computer Science
  1828.     University of Utah
  1829.  
  1830.     */
  1831.  
  1832. /*
  1833.     HP-PA calling conventions state:
  1834.  
  1835.     1. an argument relocation stub is required whenever the callee and
  1836.     caller argument relocation bits do not match exactly.  The exception
  1837.     to this rule is if either the caller or callee argument relocation
  1838.     bit are 00 (do not relocate).
  1839.  
  1840.     2. The linker can optionally add a symbol record for the stub so that
  1841.     the stub can be reused.  The symbol record will be the same as the
  1842.     original export symbol record, except that the relocation bits will
  1843.     reflect the input of the stub, the type would be STUB and the symbol
  1844.     value will be the location of the relocation stub.
  1845.  
  1846.     Other notes:
  1847.  
  1848.     Stubs can be inserted *before* the section of the caller.  The stubs
  1849.     can be treated as calls to code that manipulates the arguments.
  1850.  
  1851.  */
  1852.  
  1853. typedef enum
  1854.   {
  1855.     HPPA_STUB_ILLEGAL,
  1856.     HPPA_STUB_ARG_RELOC,
  1857.     HPPA_STUB_LONG_BRANCH
  1858.   } hppa_stub_type;
  1859.  
  1860. symext_entryS
  1861. elf32_hppa_get_sym_extn (abfd, sym, type)
  1862.      bfd *abfd;
  1863.      asymbol *sym;
  1864.      int type;
  1865. {
  1866.   /* This function finds the symbol extension record of the */
  1867.   /* specified type for the specified symbol.  It returns the */
  1868.   /* value of the symbol extension record.    */
  1869.   symext_entryS retval;
  1870.  
  1871.   switch (type)
  1872.     {
  1873.     case HPPA_SXT_NULL:
  1874.       retval = (symext_entryS) 0;
  1875.       break;
  1876.     case HPPA_SXT_SYMNDX:
  1877.       retval = (symext_entryS) 0;    /* XXX: need to fix this */
  1878.       break;
  1879.     case HPPA_SXT_ARG_RELOC:
  1880.       {
  1881.     elf_symbol_type *esymP = (elf_symbol_type *) sym;
  1882.  
  1883.     retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
  1884.     break;
  1885.       }
  1886.     /* This should never happen.  */
  1887.     default:
  1888.       abort();
  1889.     }
  1890.   return retval;
  1891. }
  1892.  
  1893. typedef struct elf32_hppa_stub_name_list_struct
  1894. {
  1895.   /* name of this stub  */
  1896.   asymbol *sym;
  1897.   /* stub description for this stub  */
  1898.   struct elf32_hppa_stub_description_struct *stub_desc;
  1899.   /* pointer into stub contents  */
  1900.   int *stub_secp;
  1901.   /* size of this stub  */
  1902.   unsigned size;
  1903.   /* next stub name entry  */
  1904.   struct elf32_hppa_stub_name_list_struct *next;
  1905. } elf32_hppa_stub_name_list;
  1906.  
  1907. typedef struct elf32_hppa_stub_description_struct
  1908.   {
  1909.     struct elf32_hppa_stub_description_struct *next;
  1910.     bfd *this_bfd;        /* bfd to which this stub applies */
  1911.     asection *stub_sec;        /* stub section for this bfd */
  1912.     unsigned relocs_allocated_cnt; /* count of relocations for this stub section */
  1913.     unsigned real_size;
  1914.     unsigned allocated_size;
  1915.     int *stub_secp;        /* pointer to the next available location in the buffer */
  1916.     char *stub_contents;    /* contents of the stubs for this bfd */
  1917.     elf32_hppa_stub_name_list *stub_listP;
  1918.     struct bfd_link_info *link_info;
  1919.   }
  1920. elf32_hppa_stub_description;
  1921.  
  1922. static elf32_hppa_stub_description *elf_hppa_stub_rootP;
  1923.  
  1924. /* Locate the stub section information for the given bfd. */
  1925. static elf32_hppa_stub_description *
  1926. find_stubs (abfd, stub_sec)
  1927.      bfd *abfd;
  1928.      asection *stub_sec;
  1929. {
  1930.   elf32_hppa_stub_description *stubP;
  1931.  
  1932.   for (stubP = elf_hppa_stub_rootP; stubP; stubP = stubP->next)
  1933.     {
  1934.       if (stubP->this_bfd == abfd
  1935.       && stubP->stub_sec == stub_sec)
  1936.     return stubP;
  1937.     }
  1938.  
  1939.   return (elf32_hppa_stub_description *) NULL;
  1940. }
  1941.  
  1942. static elf32_hppa_stub_description *
  1943. new_stub (abfd, stub_sec, link_info)
  1944.      bfd *abfd;
  1945.      asection *stub_sec;
  1946.      struct bfd_link_info *link_info;
  1947. {
  1948.   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
  1949.  
  1950.   if (stub)
  1951.     return stub;
  1952.  
  1953.   stub = (elf32_hppa_stub_description *) bfd_zalloc (abfd, sizeof (elf32_hppa_stub_description));
  1954.   if (stub)
  1955.     {
  1956.       stub->this_bfd = abfd;
  1957.       stub->stub_sec = stub_sec;
  1958.       stub->real_size = 0;
  1959.       stub->allocated_size = 0;
  1960.       stub->stub_contents = NULL;
  1961.       stub->stub_secp = NULL;
  1962.       stub->link_info = link_info;
  1963.  
  1964.       stub->next = elf_hppa_stub_rootP;
  1965.       elf_hppa_stub_rootP = stub;
  1966.     }
  1967.   else
  1968.     {
  1969.       bfd_error = no_memory;
  1970.       bfd_perror ("new_stub");
  1971.     }
  1972.  
  1973.   return stub;
  1974. }
  1975.  
  1976. /* Locate the stub by the given name.  */
  1977. static elf32_hppa_stub_name_list *
  1978. find_stub_by_name (abfd, stub_sec, name)
  1979.      bfd *abfd;
  1980.      asection *stub_sec;
  1981.      char *name;
  1982. {
  1983.   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
  1984.  
  1985.   if (stub)
  1986.     {
  1987.       elf32_hppa_stub_name_list *name_listP;
  1988.  
  1989.       for (name_listP = stub->stub_listP; name_listP; name_listP = name_listP->next)
  1990.     {
  1991.       if (!strcmp (name_listP->sym->name, name))
  1992.         return name_listP;
  1993.     }
  1994.     }
  1995.  
  1996.   return 0;
  1997. }
  1998.  
  1999. /* Locate the stub by the given name.  */
  2000. static elf32_hppa_stub_name_list *
  2001. add_stub_by_name(abfd, stub_sec, sym, link_info)
  2002.      bfd *abfd;
  2003.      asection *stub_sec;
  2004.      asymbol *sym;
  2005.      struct bfd_link_info *link_info;
  2006. {
  2007.   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
  2008.   elf32_hppa_stub_name_list *stub_entry;
  2009.  
  2010.   if (!stub)
  2011.     stub = new_stub(abfd, stub_sec, link_info);
  2012.  
  2013.   if (stub)
  2014.     {
  2015.       stub_entry = (elf32_hppa_stub_name_list *)
  2016.     bfd_zalloc (abfd, sizeof (elf32_hppa_stub_name_list));
  2017.  
  2018.       if (stub_entry)
  2019.     {
  2020.       stub_entry->size = 0;
  2021.       stub_entry->sym = sym;
  2022.       stub_entry->stub_desc = stub;
  2023.       /* First byte of this stub is the pointer to
  2024.          the next available location in the stub buffer.  */
  2025.       stub_entry->stub_secp = stub->stub_secp;
  2026.       if (stub->stub_listP)
  2027.         stub_entry->next = stub->stub_listP;
  2028.       else
  2029.         stub_entry->next = NULL;
  2030.       stub->stub_listP = stub_entry;
  2031.       return stub_entry;
  2032.     }
  2033.       else
  2034.     {
  2035.       bfd_error = no_memory;
  2036.       bfd_perror("add_stub_by_name");
  2037.     }
  2038.     }
  2039.  
  2040.   return (elf32_hppa_stub_name_list *)NULL;
  2041. }
  2042.  
  2043. #define ARGUMENTS    0
  2044. #define RETURN_VALUE    1
  2045.  
  2046. #define    NO_ARG_RELOC    0
  2047. #define R_TO_FR        1
  2048. #define R01_TO_FR    2
  2049. #define R23_TO_FR    3
  2050. #define FR_TO_R        4
  2051. #define FR_TO_R01    5
  2052. #define FR_TO_R23    6
  2053. #define    ARG_RELOC_ERR    7
  2054.  
  2055. #define ARG0    0
  2056. #define ARG1    1
  2057. #define ARG2    2
  2058. #define ARG3    3
  2059. #define RETVAL    4
  2060.  
  2061. #define AR_NO    0
  2062. #define AR_GR    1
  2063. #define AR_FR    2
  2064. #define AR_FU    3
  2065. /* FP register in arg0/arg1.  This value can only appear in the arg0 location. */
  2066. #define AR_DBL01    4
  2067. /* FP register in arg2/arg3.  This value can only appear in the arg2 location. */
  2068. #define AR_DBL23    5
  2069.  
  2070. #define AR_WARN(type,loc) \
  2071.   fprintf(stderr,"WARNING:  Illegal argument relocation: %s for %s\n", \
  2072.       reloc_type_strings[type],reloc_loc_strings[loc])
  2073.  
  2074. static CONST char *CONST reloc_type_strings[] =
  2075. {
  2076.   "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
  2077. };
  2078.  
  2079. static CONST char *CONST reloc_loc_strings[] =
  2080. {
  2081.   "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
  2082. };
  2083.  
  2084. static CONST char mismatches[6][6] =
  2085. {                /*     CALLEE NONE    CALLEE GR    CALLEE FR    CALLEE FU    CALLEE DBL01    CALLEE DBL23    */
  2086.   /* CALLER NONE    */
  2087.  {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
  2088.  /* CALLER GR    */
  2089.  {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
  2090.  /* CALLER FR    */
  2091.  {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR},
  2092.  /* CALLER FU    */
  2093.  {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
  2094.  /* CALLER DBL01    */
  2095.  {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
  2096.  /* CALLER DBL23    */
  2097.  {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
  2098. };
  2099.  
  2100. static CONST char retval_mismatches[6][6] =
  2101. {    /*     CALLEE NONE    CALLEE GR    CALLEE FR    CALLEE FU    CALLEE DBL01    CALLEE DBL23    */
  2102.   /* CALLER NONE    */
  2103.  {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
  2104.  /* CALLER GR    */
  2105.  {NO_ARG_RELOC, NO_ARG_RELOC, FR_TO_R, ARG_RELOC_ERR, FR_TO_R01, ARG_RELOC_ERR},
  2106.  /* CALLER FR    */
  2107.  {NO_ARG_RELOC, R_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
  2108.  /* CALLER FU    */
  2109.  {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
  2110.  /* CALLER DBL01    */
  2111.  {NO_ARG_RELOC, R01_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
  2112.  /* CALLER DBL23    */
  2113.  {NO_ARG_RELOC, R23_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
  2114. };
  2115.  
  2116. static int
  2117. type_of_mismatch (caller_bits, callee_bits, type)
  2118.      int caller_bits;
  2119.      int callee_bits;
  2120.      int type;
  2121. {
  2122.   switch (type)
  2123.     {
  2124.     case ARGUMENTS:
  2125.       return mismatches[caller_bits][callee_bits];
  2126.     case RETURN_VALUE:
  2127.       return retval_mismatches[caller_bits][callee_bits];
  2128.     }
  2129.  
  2130.   return 0;
  2131. }
  2132.  
  2133. #define EXTRACT_ARBITS(ar,which)    ((ar) >> (8-(which*2))) & 3
  2134.  
  2135. #define NEW_INSTRUCTION(entry,insn)    \
  2136. { \
  2137.   *((entry)->stub_desc->stub_secp)++ = (insn);    \
  2138.   (entry)->stub_desc->real_size += sizeof(int);    \
  2139.   (entry)->size += sizeof(int);    \
  2140.   bfd_set_section_size((entry)->stub_desc->this_bfd,    \
  2141.                (entry)->stub_desc->stub_sec,    \
  2142.                (entry)->stub_desc->real_size);    \
  2143. }
  2144.  
  2145. #define CURRENT_STUB_OFFSET(entry)    \
  2146.   ((int)(entry)->stub_desc->stub_secp \
  2147.    - (int)(entry)->stub_desc->stub_contents - 4)
  2148.  
  2149. static boolean stubs_finished = false;
  2150.  
  2151. void
  2152. hppa_elf_stub_finish (output_bfd)
  2153.      bfd *output_bfd;
  2154. {
  2155.   elf32_hppa_stub_description *stub_list = elf_hppa_stub_rootP;
  2156.   /* All the stubs have been built.  Finish up building    */
  2157.   /* stub section.  Apply relocations to the section.    */
  2158.  
  2159.   if ( stubs_finished )
  2160.     return;
  2161.  
  2162.   for (; stub_list; stub_list = stub_list->next)
  2163.     {
  2164.       if (stub_list->real_size)
  2165.     {
  2166.       bfd *stub_bfd = stub_list->this_bfd;
  2167.       asection *stub_sec = bfd_get_section_by_name (stub_bfd, ".hppa_linker_stubs");
  2168.       bfd_size_type reloc_size;
  2169.       arelent **reloc_vector;
  2170.  
  2171.       BFD_ASSERT (stub_sec == stub_list->stub_sec);
  2172.       reloc_size = bfd_get_reloc_upper_bound (stub_bfd, stub_sec);
  2173.       reloc_vector = (arelent **) alloca (reloc_size);
  2174.  
  2175.       BFD_ASSERT (stub_sec);
  2176.  
  2177.       /* We are not relaxing the section, so just copy the size info */
  2178.       stub_sec->_cooked_size = stub_sec->_raw_size;
  2179.       stub_sec->reloc_done = true;
  2180.  
  2181.  
  2182.       if (bfd_canonicalize_reloc (stub_bfd,
  2183.                       stub_sec,
  2184.                       reloc_vector,
  2185.                       output_bfd->outsymbols))
  2186.         {
  2187.           arelent **parent;
  2188.           for (parent = reloc_vector; *parent != (arelent *) NULL;
  2189.            parent++)
  2190.         {
  2191.           char *err = (char *) NULL;
  2192.           bfd_reloc_status_type r =
  2193.             bfd_perform_relocation (stub_bfd,
  2194.                         *parent,
  2195.                         stub_list->stub_contents,
  2196.                         stub_sec, (bfd *) NULL, &err);
  2197.  
  2198.  
  2199.           if (r != bfd_reloc_ok)
  2200.             {
  2201.               struct bfd_link_info *link_info = stub_list->link_info;
  2202.  
  2203.               switch (r)
  2204.             {
  2205.             case bfd_reloc_undefined:
  2206.               if (! ((*link_info->callbacks->undefined_symbol)
  2207.                  (link_info,
  2208.                   bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
  2209.                   stub_bfd, stub_sec, (*parent)->address)))
  2210.                 abort ();
  2211.               break;
  2212.             case bfd_reloc_dangerous:
  2213.               if (! ((*link_info->callbacks->reloc_dangerous)
  2214.                  (link_info, err, stub_bfd, stub_sec,
  2215.                   (*parent)->address)))
  2216.                 abort ();
  2217.               break;
  2218.             case bfd_reloc_overflow:
  2219.               if (! ((*link_info->callbacks->reloc_overflow)
  2220.                  (link_info, stub_bfd, stub_sec,
  2221.                   (*parent)->address)))
  2222.                 abort ();
  2223.               break;
  2224.             case bfd_reloc_outofrange:
  2225.             default:
  2226.               abort ();
  2227.               break;
  2228.             }
  2229.             }
  2230.         }
  2231.         }
  2232.  
  2233.       bfd_set_section_contents (output_bfd,
  2234.                     stub_sec,
  2235.                     stub_list->stub_contents,
  2236.                     0,
  2237.                     stub_list->real_size);
  2238.  
  2239.       free (reloc_vector);
  2240.     }
  2241.     }
  2242.   stubs_finished = true;
  2243. }
  2244.  
  2245. void
  2246. hppa_elf_stub_branch_reloc (stub_desc,    /* the bfd */
  2247.                 output_bfd,    /* the output bfd */
  2248.                 target_sym,    /* the target symbol */
  2249.                 offset)    /* the offset within the stub buffer (pre-calculated) */
  2250.      elf32_hppa_stub_description *stub_desc;
  2251.      bfd *output_bfd;
  2252.      asymbol *target_sym;
  2253.      int offset;
  2254. {
  2255.   /* Allocate a new relocation entry. */
  2256.   arelent relent;
  2257.   int size;
  2258.  
  2259.   if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
  2260.     {
  2261.       if (stub_desc->stub_sec->relocation == NULL)
  2262.     {
  2263.       stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
  2264.       size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
  2265.       stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
  2266.     }
  2267.       else
  2268.     {
  2269.       stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
  2270.       size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
  2271.       stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
  2272.                                  size);
  2273.     }
  2274.     }
  2275.  
  2276.   /* Fill in the details. */
  2277.   relent.address = offset;
  2278.   relent.addend = 0;
  2279.   relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
  2280.   BFD_ASSERT (relent.sym_ptr_ptr);
  2281.  
  2282.   relent.sym_ptr_ptr[0] = target_sym;
  2283.   relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_PCREL_CALL_17);
  2284.  
  2285.   /* Save it in the array of relocations for the stub section. */
  2286.  
  2287.   memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
  2288.       &relent,
  2289.       sizeof (arelent));
  2290. }
  2291.  
  2292. void
  2293. hppa_elf_stub_reloc (stub_desc,    /* the bfd */
  2294.              output_bfd,    /* the output bfd */
  2295.              target_sym,    /* the target symbol */
  2296.              offset,    /* the offset within the stub buffer (pre-calculated) */
  2297.              type)
  2298. elf32_hppa_stub_description *stub_desc;
  2299. bfd *output_bfd;
  2300. asymbol *target_sym;
  2301. int offset;
  2302. elf32_hppa_reloc_type type;
  2303. {
  2304.   /* Allocate a new relocation entry. */
  2305.   arelent relent;
  2306.   int size;
  2307.   Elf_Internal_Shdr *rela_hdr;
  2308.  
  2309.   if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
  2310.     {
  2311.       if (stub_desc->stub_sec->relocation == NULL)
  2312.     {
  2313.       stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
  2314.       size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
  2315.       stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
  2316.     }
  2317.       else
  2318.     {
  2319.       stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
  2320.       size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
  2321.       stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
  2322.                                  size);
  2323.     }
  2324.     }
  2325.  
  2326.   rela_hdr = &elf_section_data(stub_desc->stub_sec)->rel_hdr;
  2327.   rela_hdr->sh_size += sizeof(Elf32_External_Rela);
  2328.  
  2329.   /* Fill in the details. */
  2330.   relent.address = offset;
  2331.   relent.addend = 0;
  2332.   relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
  2333.   BFD_ASSERT (relent.sym_ptr_ptr);
  2334.  
  2335.   relent.sym_ptr_ptr[0] = target_sym;
  2336.   relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, type);
  2337.  
  2338.   /* Save it in the array of relocations for the stub section. */
  2339.  
  2340.   memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
  2341.       &relent,
  2342.       sizeof (arelent));
  2343. }
  2344.  
  2345. asymbol *
  2346. hppa_elf_build_arg_reloc_stub (abfd, output_bfd, link_info, reloc_entry,
  2347.                    stub_types, rtn_adjust, data)
  2348.      bfd *abfd;
  2349.      bfd *output_bfd;
  2350.      struct bfd_link_info *link_info;
  2351.      arelent *reloc_entry;
  2352.      int stub_types[5];
  2353.      int rtn_adjust;
  2354.      unsigned *data;
  2355. {
  2356.   asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
  2357.   elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
  2358.   asymbol *stub_sym = NULL;
  2359.   asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
  2360.   asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
  2361.   int i;
  2362.   char stub_sym_name[128];
  2363.   elf32_hppa_stub_name_list *stub_entry;
  2364.   unsigned insn = data[0];
  2365.  
  2366.   /* Perform some additional checks on whether we should really do the
  2367.      return adjustment.  For example, if the instruction is nullified
  2368.      or if the delay slot contains an instruction that modifies the return
  2369.      pointer, then the branch instructions should not be rearranged
  2370.      (rtn_adjust is false).  */
  2371.   if (insn & 2 || insn == 0)
  2372.     rtn_adjust = false;
  2373.   else
  2374.     {
  2375.       unsigned delay_insn = data[1];
  2376.  
  2377.       if (get_opcode (delay_insn) == LDO
  2378.       && (((insn & 0x03e00000) >> 21) == ((delay_insn & 0x001f0000) >> 16)))
  2379.     rtn_adjust = false;
  2380.     }
  2381.  
  2382.   /* See if the proper stub entry has already been made.  */
  2383.   if (!stub_sec)
  2384.     {
  2385.       BFD_ASSERT (stub_desc == NULL);
  2386.       stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
  2387.       bfd_set_section_flags (abfd,
  2388.                  stub_sec,
  2389.                  SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
  2390.                  | SEC_RELOC | SEC_CODE | SEC_READONLY);
  2391.       stub_sec->output_section = output_text_section->output_section;
  2392.       stub_sec->output_offset = 0;
  2393.       bfd_set_section_alignment (abfd, stub_sec, 2);
  2394.       stub_desc = new_stub (abfd, stub_sec, link_info);
  2395.     }
  2396.  
  2397.   /* Make the stub if we did not find one already.  */
  2398.   if (!stub_desc)
  2399.     stub_desc = new_stub (abfd, stub_sec, link_info);
  2400.  
  2401.   /* Allocate space to write the stub.
  2402.      FIXME.  Why using realloc?!?  */
  2403.   if (!stub_desc->stub_contents)
  2404.     {
  2405.       stub_desc->allocated_size = STUB_BUFFER_INCR;
  2406.       stub_desc->stub_contents = (char *) bfd_xmalloc (STUB_BUFFER_INCR);
  2407.     }
  2408.   else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
  2409.     {
  2410.       stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
  2411.       stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
  2412.                            stub_desc->allocated_size);
  2413.     }
  2414.  
  2415.   stub_desc->stub_secp
  2416.     = (int *) (stub_desc->stub_contents + stub_desc->real_size);
  2417.  
  2418.   sprintf (stub_sym_name,
  2419.        "_stub_%s_%02d_%02d_%02d_%02d_%02d_%s",
  2420.        reloc_entry->sym_ptr_ptr[0]->name,
  2421.        stub_types[0], stub_types[1], stub_types[2],
  2422.        stub_types[3], stub_types[4],
  2423.        rtn_adjust ? "RA" : "");
  2424.   stub_entry = find_stub_by_name (abfd, stub_sec, stub_sym_name);
  2425.  
  2426.   if (stub_entry)
  2427.     {
  2428.       stub_sym = stub_entry->sym;
  2429.       /* Redirect the original relocation from the old symbol (a function)
  2430.      to the stub (the stub calls the function).  Should we need to
  2431.      change the relocation type?  */
  2432.       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
  2433.                               sizeof (asymbol *));
  2434.       reloc_entry->sym_ptr_ptr[0] = stub_sym;
  2435.       if (reloc_entry->howto->type != R_HPPA_PLABEL_32
  2436.       && (get_opcode(insn) == BLE
  2437.           || get_opcode (insn) == BE
  2438.           || get_opcode (insn) == BL))
  2439.     reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
  2440.     }
  2441.   else
  2442.     {
  2443.       /* Create a new symbol to point to this stub.  */
  2444.       stub_sym = bfd_make_empty_symbol (abfd);
  2445.       stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
  2446.       strcpy ((char *) stub_sym->name, stub_sym_name);
  2447.       stub_sym->value
  2448.     = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
  2449.       stub_sym->section = stub_sec;
  2450.       stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
  2451.       stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
  2452.  
  2453.       /* Redirect the original relocation from the old symbol (a function)
  2454.      to the stub (the stub calls the function).  Change the type of
  2455.      relocation to be the internal use only stub R_HPPA_STUB_CALL_17.  */
  2456.       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
  2457.                               sizeof (asymbol *));
  2458.       reloc_entry->sym_ptr_ptr[0] = stub_sym;
  2459.       if (reloc_entry->howto->type != R_HPPA_PLABEL_32
  2460.       && (get_opcode (insn) == BLE
  2461.           || get_opcode (insn) == BE
  2462.           || get_opcode (insn) == BL))
  2463.     reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
  2464.  
  2465.       /* Generate common code for all stubs.  */
  2466.  
  2467.       NEW_INSTRUCTION (stub_entry, LDSID_31_1);
  2468.       NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
  2469.       NEW_INSTRUCTION (stub_entry, ADDI_8_SP);
  2470.  
  2471.       /* Generate code to move the arguments around.  */
  2472.       for (i = ARG0; i < ARG3; i++)
  2473.     {
  2474.       if (stub_types[i] != NO_ARG_RELOC)
  2475.         {
  2476.           switch (stub_types[i])
  2477.         {
  2478.         case R_TO_FR:
  2479.           switch (i)
  2480.             {
  2481.             case ARG0:
  2482.               NEW_INSTRUCTION (stub_entry, STWS_ARG0_M8SP);
  2483.               NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG0);
  2484.               break;
  2485.             case ARG1:
  2486.               NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
  2487.               NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG1);
  2488.               break;
  2489.             case ARG2:
  2490.               NEW_INSTRUCTION (stub_entry, STWS_ARG2_M8SP);
  2491.               NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG2);
  2492.               break;
  2493.             case ARG3:
  2494.               NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
  2495.               NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG3);
  2496.               break;
  2497.             }
  2498.           continue;
  2499.           
  2500.         case R01_TO_FR:
  2501.           switch (i)
  2502.             {
  2503.             case ARG0:
  2504.               NEW_INSTRUCTION (stub_entry, STWS_ARG0_M4SP);
  2505.               NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
  2506.               NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG1);
  2507.               break;
  2508.             default:
  2509.               AR_WARN (stub_types[i],i);
  2510.               break;
  2511.             }
  2512.           continue;
  2513.           
  2514.         case R23_TO_FR:
  2515.           switch (i)
  2516.             {
  2517.             case ARG2:
  2518.               NEW_INSTRUCTION (stub_entry, STWS_ARG2_M4SP);
  2519.               NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
  2520.               NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG3);
  2521.               break;
  2522.             default:
  2523.               AR_WARN (stub_types[i],i);
  2524.               break;
  2525.             }
  2526.           continue;
  2527.           
  2528.         case FR_TO_R:
  2529.           switch (i)
  2530.             {
  2531.             case ARG0:
  2532.               NEW_INSTRUCTION (stub_entry, FSTWS_FARG0_M8SP);
  2533.               NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
  2534.               break;
  2535.             case ARG1:
  2536.               NEW_INSTRUCTION (stub_entry, FSTWS_FARG1_M8SP);
  2537.               NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG1);
  2538.               break;
  2539.             case ARG2:
  2540.               NEW_INSTRUCTION (stub_entry, FSTWS_FARG2_M8SP);
  2541.               NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
  2542.               break;
  2543.             case ARG3:
  2544.               NEW_INSTRUCTION (stub_entry, FSTWS_FARG3_M8SP);
  2545.               NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG3);
  2546.               break;
  2547.             }
  2548.           continue;
  2549.           
  2550.         case FR_TO_R01:
  2551.           switch (i)
  2552.             {
  2553.             case ARG0:
  2554.               NEW_INSTRUCTION (stub_entry, FSTDS_FARG1_M8SP);
  2555.               NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
  2556.               NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG1);
  2557.               break;
  2558.             default:
  2559.               AR_WARN (stub_types[i],i);
  2560.               break;
  2561.             }
  2562.           continue;
  2563.           
  2564.         case FR_TO_R23:
  2565.           switch (i)
  2566.             {
  2567.             case ARG2:
  2568.               NEW_INSTRUCTION (stub_entry, FSTDS_FARG3_M8SP);
  2569.               NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
  2570.               NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG3);
  2571.               break;
  2572.             default:
  2573.               AR_WARN (stub_types[i],i);
  2574.               break;
  2575.             }
  2576.           continue;
  2577.           
  2578.         }
  2579.         }
  2580.     }
  2581.  
  2582.       NEW_INSTRUCTION (stub_entry, ADDI_M8_SP_SP);
  2583.  
  2584.       /* Adjust the return address if necessary.  */
  2585.       if (rtn_adjust)
  2586.     {
  2587.       NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
  2588.     }
  2589.       else
  2590.     NEW_INSTRUCTION (stub_entry, COPY_31_2);
  2591.  
  2592.       /* Save the return address.  */
  2593.       NEW_INSTRUCTION (stub_entry, STW_RP_M8SP);
  2594.  
  2595.       /* Long branch to the target function.  */
  2596.       NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
  2597.       hppa_elf_stub_reloc (stub_entry->stub_desc,
  2598.                abfd,
  2599.                target_sym,
  2600.                CURRENT_STUB_OFFSET (stub_entry),
  2601.                R_HPPA_L21);
  2602.       NEW_INSTRUCTION (stub_entry, BLE_XXX_0_31);
  2603.       hppa_elf_stub_reloc (stub_entry->stub_desc,
  2604.                abfd,
  2605.                target_sym,
  2606.                CURRENT_STUB_OFFSET (stub_entry),
  2607.                R_HPPA_ABS_CALL_R17);
  2608.       NEW_INSTRUCTION (stub_entry, COPY_31_2);
  2609.       
  2610.  
  2611.       /* Restore the return address.  */
  2612.       NEW_INSTRUCTION (stub_entry, LDW_M8SP_RP);
  2613.       
  2614.       /* Generate the code to move the return value around.  */
  2615.       i = RETVAL;
  2616.       if (stub_types[i] != NO_ARG_RELOC)
  2617.     {
  2618.       switch (stub_types[i])
  2619.         {
  2620.         case R_TO_FR:
  2621.           NEW_INSTRUCTION (stub_entry, STWS_RET0_M8SP);
  2622.           NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FRET0);
  2623.           break;
  2624.           
  2625.         case FR_TO_R:
  2626.           NEW_INSTRUCTION (stub_entry, FSTWS_FRET0_M8SP);
  2627.           NEW_INSTRUCTION (stub_entry, LDWS_M4SP_RET0);
  2628.           break;
  2629.         }
  2630.     }
  2631.       NEW_INSTRUCTION (stub_entry, BV_N_0_RP);
  2632.     }
  2633.  
  2634.   return stub_sym;
  2635. }
  2636.  
  2637. int
  2638. hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types, caller_ar)
  2639.      bfd *abfd;
  2640.      arelent *reloc_entry;
  2641.      int stub_types[5];
  2642.      symext_entryS caller_ar;
  2643. {
  2644.   /* If the symbol is still undefined, there is    */
  2645.   /* no way to know if a stub is required.    */
  2646.  
  2647.   if (reloc_entry->sym_ptr_ptr[0] && reloc_entry->sym_ptr_ptr[0]->section != &bfd_und_section)
  2648.     {
  2649.       symext_entryS callee_ar = elf32_hppa_get_sym_extn (abfd,
  2650.                         reloc_entry->sym_ptr_ptr[0],
  2651.                              HPPA_SXT_ARG_RELOC);
  2652.  
  2653.       /* Now, determine if a stub is */
  2654.       /* required.  A stub is required if they the callee and caller    */
  2655.       /* argument relocation bits are both nonzero and not equal.    */
  2656.  
  2657.       if (caller_ar && callee_ar)
  2658.     {
  2659.       /* Both are non-zero, we need to do further checking. */
  2660.       /* First, check if there is a return value relocation to be done */
  2661.       int caller_loc[5];
  2662.       int callee_loc[5];
  2663.  
  2664.       callee_loc[RETVAL] = EXTRACT_ARBITS (callee_ar, RETVAL);
  2665.       caller_loc[RETVAL] = EXTRACT_ARBITS (caller_ar, RETVAL);
  2666.       callee_loc[ARG0] = EXTRACT_ARBITS (callee_ar, ARG0);
  2667.       caller_loc[ARG0] = EXTRACT_ARBITS (caller_ar, ARG0);
  2668.       callee_loc[ARG1] = EXTRACT_ARBITS (callee_ar, ARG1);
  2669.       caller_loc[ARG1] = EXTRACT_ARBITS (caller_ar, ARG1);
  2670.       callee_loc[ARG2] = EXTRACT_ARBITS (callee_ar, ARG2);
  2671.       caller_loc[ARG2] = EXTRACT_ARBITS (caller_ar, ARG2);
  2672.       callee_loc[ARG3] = EXTRACT_ARBITS (callee_ar, ARG3);
  2673.       caller_loc[ARG3] = EXTRACT_ARBITS (caller_ar, ARG3);
  2674.  
  2675.       /* Check some special combinations.  For */
  2676.       /* example, if FU appears in ARG1 or ARG3, we */
  2677.       /* can move it to ARG0 or ARG2, respectively. */
  2678.  
  2679.       if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
  2680.         {
  2681.           caller_loc[ARG0] = AR_DBL01;
  2682.           caller_loc[ARG1] = AR_NO;
  2683.         }
  2684.       if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
  2685.         {
  2686.           caller_loc[ARG2] = AR_DBL23;
  2687.           caller_loc[ARG3] = AR_NO;
  2688.         }
  2689.       if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
  2690.         {
  2691.           callee_loc[ARG0] = AR_DBL01;
  2692.           callee_loc[ARG1] = AR_NO;
  2693.         }
  2694.       if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
  2695.         {
  2696.           callee_loc[ARG2] = AR_DBL23;
  2697.           callee_loc[ARG3] = AR_NO;
  2698.         }
  2699.  
  2700.       stub_types[ARG0] = type_of_mismatch (caller_loc[ARG0], callee_loc[ARG0], ARGUMENTS);
  2701.       stub_types[ARG1] = type_of_mismatch (caller_loc[ARG1], callee_loc[ARG1], ARGUMENTS);
  2702.       stub_types[ARG2] = type_of_mismatch (caller_loc[ARG2], callee_loc[ARG2], ARGUMENTS);
  2703.       stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS);
  2704.       stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE);
  2705.  
  2706.       /* Steps involved in building stubs: */
  2707.       /* 1. Determine what argument registers need to relocated.  This */
  2708.       /*     step is already done here. */
  2709.       /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
  2710.       /*     This section should never appear in an object file.  It is */
  2711.       /*     only used internally.  The output_section of the */
  2712.       /*     .hppa_linker_stubs section is the .text section of the */
  2713.       /*     executable.    */
  2714.       /* 3. Build a symbol that is used (internally only) as the entry */
  2715.       /*    point of the stub. */
  2716.       /* 4. Change the instruction of the original branch into a branch to */
  2717.       /*     the stub routine. */
  2718.       /* 5. Build a relocation entry for the instruction of the original */
  2719.       /*    branch to be R_HPPA_PCREL_CALL to the stub routine. */
  2720.  
  2721.  
  2722.       if (stub_types[0]
  2723.           || stub_types[1]
  2724.           || stub_types[2]
  2725.           || stub_types[3]
  2726.           || stub_types[4])
  2727.         {
  2728. #ifdef DETECT_STUBS
  2729.           int i;
  2730.  
  2731.           fprintf (stderr, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
  2732.                reloc_entry->sym_ptr_ptr[0]->name,
  2733.                abfd->filename, reloc_entry->address,
  2734.                callee_ar, caller_ar);
  2735.           for (i = ARG0; i < RETVAL; i++)
  2736.         {
  2737.           if (stub_types[i] != NO_ARG_RELOC)
  2738.             {
  2739.               fprintf (stderr, "%s%d: %s ",
  2740.                    i == RETVAL ? "ret" : "arg",
  2741.                    i == RETVAL ? 0 : i,
  2742.                    reloc_type_strings[stub_types[i]]);
  2743.             }
  2744.         }
  2745.           fprintf (stderr, "\n");
  2746. #endif
  2747.           return 1;
  2748.         }
  2749.  
  2750.     }
  2751.     }
  2752.   return 0;
  2753. }
  2754.  
  2755. asymbol *
  2756. hppa_elf_build_long_branch_stub (abfd, output_bfd, link_info, reloc_entry,
  2757.                  symbol, data)
  2758.      bfd *abfd;
  2759.      bfd *output_bfd;
  2760.      struct bfd_link_info *link_info;
  2761.      arelent *reloc_entry;
  2762.      asymbol *symbol;
  2763.      unsigned *data;
  2764. {
  2765.   asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
  2766.   elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
  2767.   asymbol *stub_sym = NULL;
  2768.   asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
  2769.   asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
  2770.   char stub_sym_name[128];
  2771.   int milli = false;
  2772.   int dyncall = false;
  2773.   elf32_hppa_stub_name_list *stub_entry;
  2774.   int rtn_adjust = true;
  2775.   int rtn_reg;
  2776.   unsigned insn;
  2777.  
  2778.   /* Create the stub section if it does not already exist.  */
  2779.   if (!stub_sec)
  2780.     {
  2781.       BFD_ASSERT (stub_desc == NULL);
  2782.       stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
  2783.       bfd_set_section_flags (abfd,
  2784.                  stub_sec,
  2785.                  SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
  2786.                  | SEC_RELOC | SEC_CODE | SEC_READONLY);
  2787.       stub_sec->output_section = output_text_section->output_section;
  2788.       stub_sec->output_offset = 0;
  2789.  
  2790.       /* Set up the ELF section header for this new section.  This
  2791.      is basically the same processing as elf_make_sections().  
  2792.      elf_make_sections is static and therefore not accessable
  2793.      here.  */
  2794.       {
  2795.     Elf_Internal_Shdr *this_hdr;
  2796.     this_hdr = &elf_section_data (stub_sec)->this_hdr;
  2797.     
  2798.     /* Set the sizes of this section.  The contents have already
  2799.        been set up ?!?  */
  2800.     this_hdr->sh_addr = stub_sec->vma;
  2801.     this_hdr->sh_size = stub_sec->_raw_size;
  2802.     
  2803.     /* Set appropriate flags for sections with relocations.  */
  2804.     if (stub_sec->flags & SEC_RELOC)
  2805.       {
  2806.         Elf_Internal_Shdr *rela_hdr;
  2807.         int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
  2808.         
  2809.         rela_hdr = &elf_section_data (stub_sec)->rel_hdr;
  2810.         
  2811.         if (use_rela_p)
  2812.           {
  2813.         rela_hdr->sh_type = SHT_RELA;
  2814.         rela_hdr->sh_entsize = sizeof (Elf32_External_Rela);
  2815.           }
  2816.         else
  2817.           {
  2818.         rela_hdr->sh_type = SHT_REL;
  2819.         rela_hdr->sh_entsize = sizeof (Elf32_External_Rel);
  2820.           }
  2821.         rela_hdr->sh_flags = 0;
  2822.         rela_hdr->sh_addr = 0;
  2823.         rela_hdr->sh_offset = 0;
  2824.         rela_hdr->sh_addralign = 0;
  2825.         rela_hdr->size = 0;
  2826.       }
  2827.  
  2828.     if (stub_sec->flags & SEC_ALLOC)
  2829.       {
  2830.         this_hdr->sh_flags |= SHF_ALLOC;
  2831.         /* FIXME.  If SEC_LOAD is true should we do something with
  2832.            with sh_type?  */
  2833.       }
  2834.  
  2835.     if (!(stub_sec->flags & SEC_READONLY))
  2836.       this_hdr->sh_flags |= SHF_WRITE;
  2837.     
  2838.     if (stub_sec->flags & SEC_CODE)
  2839.       this_hdr->sh_flags |= SHF_EXECINSTR;
  2840.       }
  2841.       
  2842.       bfd_set_section_alignment (abfd, stub_sec, 2);
  2843.       stub_desc = new_stub (abfd, stub_sec, link_info);
  2844.     }
  2845.   
  2846.   if (!stub_desc)
  2847.     stub_desc = new_stub (abfd, stub_sec, link_info);
  2848.   
  2849.   /* Allocate memory to contain the stub.  FIXME.  Why isn't this using
  2850.      the BFD memory allocation routines?  */
  2851.   if (!stub_desc->stub_contents)
  2852.     {
  2853.       stub_desc->allocated_size = STUB_BUFFER_INCR;
  2854.       stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR);
  2855.     }
  2856.   else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
  2857.     {
  2858.       stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
  2859.       stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
  2860.                            stub_desc->allocated_size);
  2861.     }
  2862.   
  2863.   stub_desc->stub_secp
  2864.     = (int *) (stub_desc->stub_contents + stub_desc->real_size);
  2865.   
  2866.   /* Is this a millicode call?  If so, the return address
  2867.      comes in on r31 rather than r2 (rp) so a slightly
  2868.      different code sequence is needed.  */
  2869.   
  2870.   insn = data[0];
  2871.   rtn_reg = (insn & 0x03e00000) >> 21;
  2872.   if (rtn_reg == 31)
  2873.     milli = true;
  2874.   
  2875.   if (strcmp (symbol->name, "$$dyncall") == 0)
  2876.     dyncall = true;
  2877.  
  2878.   /* If we are creating a call from a stub to another stub, then
  2879.      never do the instruction reordering.  We can tell if we are
  2880.      going to be calling one stub from another by the fact that
  2881.      the symbol name has '_stub_' (arg. reloc. stub) or '_lb_stub_'
  2882.      prepended to the name.  Alternatively, the section of the
  2883.      symbol will be '.hppa_linker_stubs'.  */
  2884.  
  2885.   if ((strncmp (symbol->name, "_stub_", 6) == 0)
  2886.       || (strncmp (symbol->name, "_lb_stub_", 9) == 0))
  2887.     {
  2888.       BFD_ASSERT (strcmp (symbol->section->name, ".hppa_linker_stubs") == 0);
  2889.       rtn_adjust = false;
  2890.     }
  2891.   
  2892.   /* Check to see if we modify the return pointer
  2893.      in the delay slot of the branch.  */
  2894.   {
  2895.     unsigned delay_insn = data[1];
  2896.     
  2897.     /* If we nullify the delay slot, or if the delay slot contains an
  2898.        instruction that modifies the return pointer, then no additional
  2899.        modification of the return pointer is necessary.  */
  2900.     if (insn & 2 || insn == 0)
  2901.       rtn_adjust = false;
  2902.     else
  2903.       {
  2904.     if (get_opcode (delay_insn) == LDO
  2905.         && (((delay_insn & 0x001f0000) >> 16) == rtn_reg))
  2906.       rtn_adjust = false;
  2907.         if (milli)
  2908.           rtn_adjust = false;
  2909.       }
  2910.   }
  2911.   
  2912.   sprintf (stub_sym_name,
  2913.        "_lb_stub_%s_%s", reloc_entry->sym_ptr_ptr[0]->name,
  2914.        rtn_adjust ? "RA" : "");
  2915.   stub_entry = find_stub_by_name(abfd, stub_sec, stub_sym_name);
  2916.  
  2917.   /* If a copy of this stub already exists re-use it.  */
  2918.   if (stub_entry)
  2919.     {
  2920.       stub_sym = stub_entry->sym;
  2921.  
  2922.       /* Change symbol associated with the original relocation to point
  2923.      to the stub.
  2924.  
  2925.      FIXME.  Is there a need to change the relocation type too?  */
  2926.       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
  2927.                               sizeof (asymbol *));
  2928.       reloc_entry->sym_ptr_ptr[0] = stub_sym;
  2929.       reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
  2930.     }
  2931.   else
  2932.     {
  2933.       /* We will need to allocate a new stub.  */
  2934.       stub_sym = bfd_make_empty_symbol (abfd);
  2935.       stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
  2936.       strcpy ((char *) stub_sym->name, stub_sym_name);
  2937.       stub_sym->value
  2938.     = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
  2939.       stub_sym->section = stub_sec;
  2940.       stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
  2941.       stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
  2942.       
  2943.       /* Change symbol associated with the original relocation to point
  2944.      to the stub.
  2945.  
  2946.      FIXME.  Is there a need to change the relocation type too?  */
  2947.       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
  2948.                               sizeof (asymbol *));
  2949.       reloc_entry->sym_ptr_ptr[0] = stub_sym;
  2950.       reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
  2951.       
  2952.       /* Build the stub.  */
  2953.       
  2954.       /* 1. initialization for the call. */
  2955.       NEW_INSTRUCTION (stub_entry, LDSID_31_1);
  2956.       NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
  2957.       
  2958.       if (!dyncall)
  2959.     {
  2960.       if (!milli)
  2961.         {
  2962.           if (rtn_adjust)
  2963.         {
  2964.           NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
  2965.         }
  2966.           else
  2967.         {
  2968.           NEW_INSTRUCTION (stub_entry, COPY_31_2);
  2969.         }
  2970.         }
  2971.       else
  2972.         {
  2973.           if (rtn_adjust)
  2974.         {
  2975.           NEW_INSTRUCTION (stub_entry, ADDI_M4_31_1);
  2976.         }
  2977.           else
  2978.         {
  2979.           NEW_INSTRUCTION (stub_entry, COPY_31_1);
  2980.         }
  2981.         }
  2982.       
  2983.       NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
  2984.       hppa_elf_stub_reloc (stub_desc,
  2985.                    abfd,
  2986.                    target_sym,
  2987.                    CURRENT_STUB_OFFSET (stub_entry),
  2988.                    R_HPPA_L21);
  2989.       
  2990.       /* 2. Make the call. */
  2991.       if (!milli)
  2992.         {
  2993.           NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
  2994.           hppa_elf_stub_reloc (stub_desc,
  2995.                    abfd,
  2996.                    target_sym,
  2997.                    CURRENT_STUB_OFFSET (stub_entry),
  2998.                    R_HPPA_ABS_CALL_R17);
  2999.           NEW_INSTRUCTION (stub_entry, COPY_2_31);
  3000.         }
  3001.       else
  3002.         {
  3003.           NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
  3004.           hppa_elf_stub_reloc (stub_desc,
  3005.                    abfd,
  3006.                    target_sym,
  3007.                    CURRENT_STUB_OFFSET (stub_entry),
  3008.                    R_HPPA_ABS_CALL_R17);
  3009.           NEW_INSTRUCTION (stub_entry, COPY_1_31);
  3010.         }
  3011.     }
  3012.       else
  3013.     {
  3014.       /* 3. Branch back to the original location.
  3015.          (For non-millicode calls, this is accomplished with the
  3016.          COPY_31_2 instruction.  For millicode calls, the return
  3017.          location is already in r2.)  */
  3018.       if (rtn_adjust)
  3019.         {
  3020.           NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
  3021.         }
  3022.       NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
  3023.       hppa_elf_stub_reloc (stub_desc,
  3024.                    abfd,
  3025.                    target_sym,
  3026.                    CURRENT_STUB_OFFSET (stub_entry),
  3027.                    R_HPPA_L21);
  3028.       
  3029.       NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
  3030.       hppa_elf_stub_reloc (stub_desc,
  3031.                    abfd,
  3032.                    target_sym,
  3033.                    CURRENT_STUB_OFFSET (stub_entry),
  3034.                    R_HPPA_ABS_CALL_R17);
  3035.       NEW_INSTRUCTION (stub_entry, COPY_2_31);
  3036.     }
  3037.     }
  3038.   return stub_sym;
  3039. }
  3040.  
  3041. int
  3042. hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
  3043.      bfd *abfd;
  3044.      asection *asec;
  3045.      arelent *reloc_entry;
  3046.      asymbol *symbol;
  3047.      unsigned insn;
  3048. {
  3049.   long sym_value = get_symbol_value(symbol);
  3050.   int fmt = reloc_entry->howto->bitsize;
  3051.   unsigned char op = get_opcode(insn);
  3052.   unsigned raddr;
  3053.  
  3054. #define too_far(val,num_bits)    ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
  3055.  
  3056.   switch (op)
  3057.     {
  3058.     case BL:
  3059.       raddr =
  3060.     reloc_entry->address + asec->output_offset + asec->output_section->vma;
  3061.       if ( too_far(sym_value - raddr,fmt+1) )
  3062.     {
  3063. #ifdef DETECT_STUBS
  3064.       fprintf(stderr,"long_branch needed on BL insn: abfd=%s,sym=%s,distance=0x%x\n",abfd->filename,symbol->name,sym_value - reloc_entry->address);
  3065. #endif
  3066.       return 1;
  3067.     }
  3068.       break;
  3069.     }  
  3070.   return 0;
  3071. }
  3072.  
  3073. #define STUB_SYM_BUFFER_INC    5
  3074.  
  3075. asymbol *
  3076. hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
  3077.                 syms, new_sym_cnt, link_info)
  3078.      bfd *stub_bfd;
  3079.      bfd *abfd;
  3080.      bfd *output_bfd;
  3081.      asection *asec;
  3082.      asymbol **syms;
  3083.      int *new_sym_cnt;
  3084.      struct bfd_link_info *link_info;
  3085. {
  3086.   int i;
  3087.   int stub_types[5];
  3088.   asymbol *new_syms = (asymbol *) NULL;
  3089.   int new_cnt = 0;
  3090.   int new_max = 0;
  3091.  
  3092.   /* Relocations are in different places depending on whether this is
  3093.      an output section or an input section.  Also, the relocations are
  3094.      in different forms.  Sigh.  Luckily, we have
  3095.      bfd_canonicalize_reloc() to straighten this out for us . */
  3096.  
  3097.   if (asec->reloc_count > 0)
  3098.     {
  3099.       arelent **reloc_vector
  3100.     = (arelent **) alloca (asec->reloc_count * (sizeof (arelent *) + 1));
  3101.  
  3102.       bfd_canonicalize_reloc (abfd, asec, reloc_vector, syms);
  3103.       for (i = 0; i < asec->reloc_count; i++)
  3104.     {
  3105.       arelent *rle = reloc_vector[i];
  3106.  
  3107.       switch (rle->howto->type)
  3108.         {
  3109.         case R_HPPA_ABS_CALL_11:
  3110.         case R_HPPA_ABS_CALL_14:
  3111.         case R_HPPA_ABS_CALL_17:
  3112.         case R_HPPA_ABS_CALL_L21:
  3113.         case R_HPPA_ABS_CALL_R11:
  3114.         case R_HPPA_ABS_CALL_R14:
  3115.         case R_HPPA_ABS_CALL_R17:
  3116.         case R_HPPA_ABS_CALL_LS21:
  3117.         case R_HPPA_ABS_CALL_RS11:
  3118.         case R_HPPA_ABS_CALL_RS14:
  3119.         case R_HPPA_ABS_CALL_RS17:
  3120.         case R_HPPA_ABS_CALL_LD21:
  3121.         case R_HPPA_ABS_CALL_RD11:
  3122.         case R_HPPA_ABS_CALL_RD14:
  3123.         case R_HPPA_ABS_CALL_RD17:
  3124.         case R_HPPA_ABS_CALL_LR21:
  3125.         case R_HPPA_ABS_CALL_RR14:
  3126.         case R_HPPA_ABS_CALL_RR17:
  3127.         case R_HPPA_PCREL_CALL_11:
  3128.         case R_HPPA_PCREL_CALL_14:
  3129.         case R_HPPA_PCREL_CALL_17:
  3130.         case R_HPPA_PCREL_CALL_12:
  3131.         case R_HPPA_PCREL_CALL_L21:
  3132.         case R_HPPA_PCREL_CALL_R11:
  3133.         case R_HPPA_PCREL_CALL_R14:
  3134.         case R_HPPA_PCREL_CALL_R17:
  3135.         case R_HPPA_PCREL_CALL_LS21:
  3136.         case R_HPPA_PCREL_CALL_RS11:
  3137.         case R_HPPA_PCREL_CALL_RS14:
  3138.         case R_HPPA_PCREL_CALL_RS17:
  3139.         case R_HPPA_PCREL_CALL_LD21:
  3140.         case R_HPPA_PCREL_CALL_RD11:
  3141.         case R_HPPA_PCREL_CALL_RD14:
  3142.         case R_HPPA_PCREL_CALL_RD17:
  3143.         case R_HPPA_PCREL_CALL_LR21:
  3144.         case R_HPPA_PCREL_CALL_RR14:
  3145.         case R_HPPA_PCREL_CALL_RR17:
  3146.           {
  3147.         symext_entryS caller_ar
  3148.           = (symext_entryS) HPPA_R_ARG_RELOC (rle->addend);
  3149.         unsigned insn[2];
  3150.  
  3151.         bfd_get_section_contents (abfd, asec, insn, rle->address,
  3152.                       sizeof(insn));
  3153.         if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
  3154.                          caller_ar))
  3155.           {
  3156.             /* Generate a stub and keep track of the new symbol.  */
  3157.             asymbol *r;
  3158.  
  3159.             if (new_cnt == new_max)
  3160.               {
  3161.             new_max += STUB_SYM_BUFFER_INC;
  3162.             new_syms = (asymbol *)
  3163.               realloc (new_syms, new_max * sizeof (asymbol));
  3164.               }
  3165.  
  3166.             /* The rtn_adjust argument is true here because we
  3167.                know that we have a branch and (with a few exceptions
  3168.                detailed under the relocation code for relocation type
  3169.                R_HPPA_STUB_CALL_17) it will be possible to perform
  3170.                the code reorientation.  */
  3171.             r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
  3172.                                link_info, rle,
  3173.                                stub_types,
  3174.                                true, insn);
  3175.             new_syms[new_cnt++] = *r;
  3176.           }
  3177.  
  3178.         /* We need to retrieve the section contents to check for
  3179.            long branch stubs.  */
  3180.         if (hppa_elf_long_branch_needed_p (abfd, asec, rle,
  3181.                            rle->sym_ptr_ptr[0],
  3182.                            insn[0]))
  3183.           {
  3184.             /* Generate a stub and keep track of the new symbol.  */
  3185.             asymbol *r;
  3186.  
  3187.             if (new_cnt == new_max)
  3188.               {
  3189.             new_max += STUB_SYM_BUFFER_INC;
  3190.             new_syms = (asymbol *)
  3191.               realloc (new_syms, (new_max * sizeof (asymbol)));
  3192.               }
  3193.             r = hppa_elf_build_long_branch_stub (stub_bfd, output_bfd,
  3194.                              link_info, rle,
  3195.                              rle->sym_ptr_ptr[0],
  3196.                              insn);
  3197.             new_syms[new_cnt++] = *r;
  3198.           }
  3199.           }
  3200.           break;
  3201.  
  3202.         case R_HPPA_PLABEL_32:
  3203.         case R_HPPA_PLABEL_11:
  3204.         case R_HPPA_PLABEL_14:
  3205.         case R_HPPA_PLABEL_L21:
  3206.         case R_HPPA_PLABEL_R11:
  3207.         case R_HPPA_PLABEL_R14:
  3208.           {
  3209.         /* On a plabel relocation, assume the arguments of the
  3210.            caller are set up in general registers.
  3211.            NOTE:  0x155 = ARGW0=CR,ARGW1=GR,ARGW2=GR,RETVAL=GR */
  3212.         symext_entryS caller_ar = (symext_entryS) 0x155;
  3213.         unsigned insn[2];
  3214.  
  3215.         bfd_get_section_contents (abfd, asec, insn, rle->address,
  3216.                       sizeof(insn));
  3217.  
  3218.         if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
  3219.                          caller_ar))
  3220.           {
  3221.             /* Generate a plabel stub and keep track of the
  3222.                new symbol.  */
  3223.             asymbol *r;
  3224.             int rtn_adjust;
  3225.  
  3226.             if (new_cnt == new_max)
  3227.               {
  3228.             new_max += STUB_SYM_BUFFER_INC;
  3229.             new_syms = (asymbol *) realloc (new_syms, new_max
  3230.                             * sizeof (asymbol));
  3231.               }
  3232.  
  3233.             /* Determine whether a return adjustment
  3234.                (see the relocation code for relocation type 
  3235.                R_HPPA_STUB_CALL_17) is possible.  Basically,
  3236.                determine whether we are looking at a branch or not.  */
  3237.                                   
  3238.             if (rle->howto->type == R_HPPA_PLABEL_32)
  3239.               rtn_adjust = false;
  3240.             else
  3241.               {
  3242.             switch (get_opcode(insn[0]))
  3243.               {
  3244.               case BLE:
  3245.               case BE:
  3246.                 rtn_adjust = true;
  3247.                 break;
  3248.               default:
  3249.                 rtn_adjust = false;
  3250.               }
  3251.               }
  3252.             r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
  3253.                                link_info, rle,
  3254.                                stub_types,
  3255.                                rtn_adjust, insn);
  3256.             new_syms[new_cnt++] = *r;
  3257.           }
  3258.           }
  3259.           break;
  3260.  
  3261.         default:
  3262.           break;
  3263.  
  3264.         }
  3265.     }
  3266.     }
  3267.   *new_sym_cnt = new_cnt;
  3268.   return new_syms;
  3269. }
  3270.  
  3271.  
  3272. char *linker_stubs = NULL;
  3273. int linker_stubs_size = 0;
  3274. int linker_stubs_max_size = 0;
  3275. #define STUB_ALLOC_INCR    100
  3276.  
  3277. boolean
  3278. DEFUN (hppa_elf_set_section_contents, (abfd, section, location, offset, count),
  3279.        bfd * abfd AND
  3280.        sec_ptr section AND
  3281.        PTR location AND
  3282.        file_ptr offset AND
  3283.        bfd_size_type count)
  3284. {
  3285.   if ( strcmp(section->name, ".hppa_linker_stubs") == 0 )
  3286.     {
  3287.       if ( linker_stubs_max_size < offset + count )
  3288.     {
  3289.       linker_stubs_max_size = offset + count + STUB_ALLOC_INCR;
  3290.       linker_stubs = (char *)realloc(linker_stubs, linker_stubs_max_size);
  3291.     }
  3292.  
  3293.       if ( offset + count > linker_stubs_size )
  3294.     linker_stubs_size = offset + count;
  3295.  
  3296.       memcpy(linker_stubs + offset,location,count);
  3297.       return (true);
  3298.     }
  3299.   else
  3300.     return bfd_elf32_set_section_contents (abfd, section, location,
  3301.                        offset, count);
  3302. }
  3303.  
  3304. /* Get the contents of the given section.
  3305.    
  3306.    This is special for PA ELF because some sections (such as linker stubs)
  3307.    may reside in memory rather than on disk, or in the case of the symbol
  3308.    extension section, the contents may need to be generated from other
  3309.    information contained in the BFD.  */
  3310.  
  3311. boolean
  3312. hppa_elf_get_section_contents (abfd, section, location, offset, count)
  3313.      bfd *abfd;
  3314.      sec_ptr section;
  3315.      PTR location;
  3316.      file_ptr offset;
  3317.      bfd_size_type count;
  3318. {
  3319.   /* If this is the linker stub section, then its contents are contained
  3320.      in memory rather than on disk.  FIXME.  Is that always right?  What
  3321.      about the case where a final executable is read in and a user tries
  3322.      to get the contents of this section?  In that case the contents would
  3323.      be on disk like everything else.  */
  3324.   if (strcmp (section->name, ".hppa_linker_stubs") == 0)
  3325.     {
  3326.       elf32_hppa_stub_description *stub_desc = find_stubs (abfd, section);
  3327.       
  3328.       if (count == 0)
  3329.     return true;
  3330.       
  3331.       /* Sanity check our arguments.  */
  3332.       if ((bfd_size_type) (offset + count) > section->_raw_size
  3333.       || (bfd_size_type) (offset + count) > stub_desc->real_size)
  3334.     return (false);
  3335.       
  3336.       memcpy (location, stub_desc->stub_contents + offset, count);
  3337.       return (true);
  3338.     }
  3339.  
  3340.   /* The symbol extension section also needs special handling.  Its
  3341.      contents might be on the disk, in memory, or still need to
  3342.      be generated. */
  3343.   else if (strcmp (section->name, ".hppa_symextn") == 0)
  3344.     {
  3345.       /* If there are no output sections, then read the contents of the
  3346.      symbol extension section from disk.  */
  3347.       if (section->output_section == NULL
  3348.       && abfd->direction == read_direction)
  3349.     {
  3350.       return bfd_generic_get_section_contents (abfd, section, location,
  3351.                            offset, count);
  3352.     }
  3353.       
  3354.       /* If this is the first time through, and there are output sections,
  3355.      then build the symbol extension section based on other information
  3356.      contained in the BFD.  */
  3357.       else if (! symext_chain_built)
  3358.     {
  3359.       int i;
  3360.       int *symtab_map =
  3361.         (int *) elf_sym_extra(section->output_section->owner);
  3362.       
  3363.       for (i = 0; i < section->output_section->owner->symcount; i++ )
  3364.         {
  3365.           elf_hppa_tc_symbol(section->output_section->owner,
  3366.                  ((elf_symbol_type *)
  3367.                   section->output_section->owner->outsymbols[i]),
  3368.                  symtab_map[i]);
  3369.         }
  3370.       symext_chain_built++;
  3371.       elf_hppa_tc_make_sections (section->output_section->owner, NULL);
  3372.     }
  3373.  
  3374.       /* At this point we know that the symbol extension section has been
  3375.      built.  We just need to copy it into the user's buffer.  */
  3376.       if (count == 0)
  3377.     return true;
  3378.       
  3379.       /* Sanity check our arguments.  */
  3380.       if ((bfd_size_type) (offset + count) > section->_raw_size
  3381.       || (bfd_size_type) (offset + count) > symextn_contents_real_size)
  3382.     return (false);
  3383.       
  3384.       memcpy (location,
  3385.           ((char *)symextn_contents + section->output_offset + offset),
  3386.           count);
  3387.       return (true);
  3388.     }
  3389.   else
  3390.     return bfd_generic_get_section_contents (abfd, section, location,
  3391.                          offset, count);
  3392. }
  3393.  
  3394. static void
  3395. DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst),
  3396.        bfd * abfd AND
  3397.        arelent * cache_ptr AND
  3398.        Elf32_Internal_Rela * dst)
  3399. {
  3400.   BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED);
  3401.   cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)];
  3402. }
  3403.  
  3404. static void
  3405. DEFUN (elf32_hppa_backend_symbol_processing, (abfd, sym),
  3406.        bfd * abfd AND
  3407.        asymbol * sym)
  3408. {
  3409.   /* Is this a definition of $global$?  If so, keep it because it will be
  3410.     needed if any relocations are performed.  */
  3411.  
  3412.   if (!strcmp (sym->name, "$global$")
  3413.       && sym->section != &bfd_und_section)
  3414.     {
  3415.       global_symbol = sym;
  3416.     }
  3417. }
  3418.  
  3419. #define elf_backend_symbol_processing    elf32_hppa_backend_symbol_processing
  3420.  
  3421. struct elf32_hppa_symextn_map_struct
  3422. {
  3423.   int old_index;
  3424.   bfd *bfd;
  3425.   asymbol *sym;
  3426.   int new_index;
  3427. };
  3428.  
  3429. static struct elf32_hppa_symextn_map_struct *elf32_hppa_symextn_map;
  3430. static int elf32_hppa_symextn_map_size;
  3431.  
  3432. static boolean
  3433. DEFUN (elf32_hppa_backend_symbol_table_processing, (abfd, esyms,symcnt),
  3434.        bfd         * abfd AND
  3435.        elf_symbol_type    *esyms AND
  3436.        int        symcnt)
  3437. {
  3438.   Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
  3439.   int i;
  3440.   int current_sym_idx = 0;
  3441.  
  3442.   /* If the symbol extension section does not exist, all the symbol */
  3443.   /* all the symbol extension information is assumed to be zero.    */
  3444.  
  3445.   if ( symextn_hdr == NULL )
  3446.     {
  3447.       for ( i = 0; i < symcnt; i++ )
  3448.     {
  3449.       esyms[i].tc_data.hppa_arg_reloc = 0;
  3450.     }
  3451.       return (true);
  3452.     }
  3453.  
  3454.   /* allocate a buffer of the appropriate size for the symextn section */
  3455.  
  3456.   symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size);
  3457.   symextn_hdr->size = symextn_hdr->sh_size;
  3458.     
  3459.   /* read in the symextn section */
  3460.  
  3461.   if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1)
  3462.     {
  3463.       bfd_error = system_call_error;
  3464.       return (false);
  3465.     }
  3466.   if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->size, abfd) 
  3467.       != symextn_hdr->size)
  3468.     {
  3469.       free ((PTR)symextn_hdr->contents);
  3470.       bfd_error = system_call_error;
  3471.       return (false);
  3472.     }    
  3473.  
  3474.   /* parse the entries, updating the symtab entries as we go */
  3475.  
  3476.   for ( i = 0; i < symextn_hdr->size / sizeof(symext_entryS); i++ )
  3477.     {
  3478.       symext_entryS *seP = ((symext_entryS *)symextn_hdr->contents) + i;
  3479.       int se_value = ELF32_HPPA_SX_VAL(*seP);
  3480.       int se_type = ELF32_HPPA_SX_TYPE(*seP);
  3481.  
  3482.       switch ( se_type )
  3483.     {
  3484.     case HPPA_SXT_NULL:
  3485.       break;
  3486.  
  3487.     case HPPA_SXT_SYMNDX:
  3488.       if ( se_value >= symcnt )
  3489.         {
  3490.           bfd_error = bad_value;
  3491.           bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
  3492.           return (false);
  3493.         }
  3494.       current_sym_idx = se_value - 1;
  3495.       break;
  3496.  
  3497.     case HPPA_SXT_ARG_RELOC:
  3498.       esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value;
  3499.       break;
  3500.  
  3501.     default:
  3502.       bfd_error = bad_value;
  3503.       bfd_perror("elf32_hppa_backend_symbol_table_processing");
  3504.       return (false);
  3505.     }
  3506.     }
  3507.   return (true);
  3508. }
  3509.  
  3510. #define elf_backend_symbol_table_processing    elf32_hppa_backend_symbol_table_processing
  3511.  
  3512. static boolean
  3513. DEFUN (elf32_hppa_backend_section_processing, (abfd, secthdr),
  3514.        bfd         * abfd AND
  3515.        Elf32_Internal_Shdr *secthdr)
  3516. {
  3517.   int i,j,k;
  3518.  
  3519.   if ( secthdr->sh_type == SHT_HPPA_SYMEXTN )
  3520.     {
  3521.       for ( i = 0; i < secthdr->size / sizeof(symext_entryS); i++ )
  3522.     {
  3523.       symext_entryS *seP = ((symext_entryS *)secthdr->contents) + i;
  3524.       int se_value = ELF32_HPPA_SX_VAL(*seP);
  3525.       int se_type = ELF32_HPPA_SX_TYPE(*seP);
  3526.       
  3527.       switch ( se_type )
  3528.         {
  3529.         case HPPA_SXT_NULL:
  3530.           break;
  3531.           
  3532.         case HPPA_SXT_SYMNDX:
  3533.           for ( j = 0; j < abfd->symcount; j++ )
  3534.         {
  3535.           /* locate the map entry for this symbol, if there is one. */
  3536.           /* modify the symbol extension section symbol index entry */
  3537.           /* to reflect the new symbol table index */
  3538.           
  3539.           for ( k = 0; k < elf32_hppa_symextn_map_size; k++ )
  3540.             {
  3541.               if ( elf32_hppa_symextn_map[k].old_index == se_value
  3542.               && elf32_hppa_symextn_map[k].bfd == abfd->outsymbols[j]->the_bfd
  3543.               && elf32_hppa_symextn_map[k].sym == abfd->outsymbols[j] )
  3544.             {
  3545.               bfd_put_32(abfd,
  3546.                      ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, j),
  3547.                      (char *)seP);
  3548.             }
  3549.             }
  3550.         }
  3551.           break;
  3552.           
  3553.         case HPPA_SXT_ARG_RELOC:
  3554.           break;
  3555.           
  3556.         default:
  3557.           bfd_error = bad_value;
  3558.           bfd_perror("elf32_hppa_backend_section_processing");
  3559.           return (false);
  3560.         }
  3561.     }
  3562.     }
  3563.   return true;
  3564. }
  3565.  
  3566. #define elf_backend_section_processing    elf32_hppa_backend_section_processing
  3567.  
  3568. static boolean
  3569. DEFUN (elf32_hppa_backend_section_from_shdr, (abfd, hdr, name),
  3570.        bfd         * abfd AND
  3571.        Elf32_Internal_Shdr *hdr AND
  3572.        char        * name)
  3573. {
  3574.   asection *newsect;
  3575.  
  3576.   if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
  3577.     {
  3578.       BFD_ASSERT ( strcmp(name,".hppa_symextn") == 0 );
  3579.  
  3580.       /* Bits that get saved. This one is real. */
  3581.       if (!hdr->rawdata)
  3582.     {
  3583.       newsect = bfd_make_section (abfd, name);
  3584.       if (newsect != NULL)
  3585.         {
  3586.           newsect->vma = hdr->sh_addr;
  3587.           newsect->_raw_size = hdr->sh_size;
  3588.           newsect->filepos = hdr->sh_offset;    /* so we can read back the bits */
  3589.           newsect->flags |= SEC_HAS_CONTENTS;
  3590.           newsect->alignment_power = hdr->sh_addralign;
  3591.  
  3592.           if (hdr->sh_flags & SHF_ALLOC)
  3593.         {
  3594.           newsect->flags |= SEC_ALLOC;
  3595.           newsect->flags |= SEC_LOAD;
  3596.         }
  3597.  
  3598.           if (!(hdr->sh_flags & SHF_WRITE))
  3599.         newsect->flags |= SEC_READONLY;
  3600.  
  3601.           if (hdr->sh_flags & SHF_EXECINSTR)
  3602.         newsect->flags |= SEC_CODE;    /* FIXME: may only contain SOME code */
  3603.           else
  3604.         newsect->flags |= SEC_DATA;
  3605.  
  3606.           hdr->rawdata = (void *) newsect;
  3607.         }
  3608.     }
  3609.       return true;
  3610.     }
  3611.   return false;
  3612. }
  3613.  
  3614. #define elf_backend_section_from_shdr    elf32_hppa_backend_section_from_shdr
  3615.  
  3616. static boolean
  3617. DEFUN (elf32_hppa_backend_fake_sections, (abfd, secthdr, asect),
  3618.        bfd         * abfd AND
  3619.        Elf_Internal_Shdr *secthdr AND
  3620.        asection        *asect)
  3621. {
  3622.  
  3623.   if ( strcmp(asect->name, ".hppa_symextn") == 0 )
  3624.     {
  3625.       secthdr->sh_type = SHT_HPPA_SYMEXTN;
  3626.       secthdr->sh_flags = 0;
  3627.       secthdr->sh_info = elf_section_data(asect)->rel_hdr.sh_link;
  3628.       secthdr->sh_link = elf_onesymtab(abfd);
  3629.       return true;
  3630.     }
  3631.  
  3632.   if (!strcmp (asect->name, ".hppa_unwind"))
  3633.     {
  3634.       secthdr->sh_type = SHT_PROGBITS;
  3635.       /* Unwind descriptors are not part of the program memory image.  */
  3636.       secthdr->sh_flags = 0;
  3637.       secthdr->sh_info = 0;
  3638.       secthdr->sh_link = 0;
  3639.       secthdr->sh_entsize = 16;
  3640.       return true;
  3641.     }
  3642.  
  3643.   /* @@ Should this be CPU specific??  KR */
  3644.   if (!strcmp (asect->name, ".stabstr"))
  3645.     {
  3646.       secthdr->sh_type = SHT_STRTAB;
  3647.       secthdr->sh_flags = 0;
  3648.       secthdr->sh_info = 0;
  3649.       secthdr->sh_link = 0;
  3650.       secthdr->sh_entsize = 0;
  3651.       return true;
  3652.     }
  3653.  
  3654.   return false;
  3655. }
  3656.  
  3657. #define elf_backend_fake_sections    elf32_hppa_backend_fake_sections
  3658.  
  3659. static boolean
  3660. DEFUN (elf32_hppa_backend_section_from_bfd_section, (abfd, hdr, asect, retval),
  3661.        bfd             *abfd AND
  3662.        Elf32_Internal_Shdr    *hdr AND
  3663.        asection            *asect AND
  3664.        int            *retval)
  3665. {
  3666.  
  3667.   if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
  3668.     {
  3669.       if (hdr->rawdata)
  3670.     {
  3671.       if (((struct sec *) (hdr->rawdata)) == asect)
  3672.         {
  3673.           BFD_ASSERT( strcmp(asect->name, ".hppa_symextn") == 0 );
  3674.           return true;
  3675.         }
  3676.     }
  3677.     }
  3678.   else if ( hdr->sh_type == SHT_STRTAB )
  3679.     {
  3680.       if (hdr->rawdata)
  3681.     {
  3682.       if (((struct sec *) (hdr->rawdata)) == asect)
  3683.         {
  3684.           BFD_ASSERT ( strcmp (asect->name, ".stabstr") == 0);
  3685.           return true;
  3686.         }
  3687.     }
  3688.     }
  3689.  
  3690.   return false;
  3691. }
  3692.  
  3693. #define elf_backend_section_from_bfd_section    elf32_hppa_backend_section_from_bfd_section
  3694.  
  3695. #define bfd_generic_get_section_contents    hppa_elf_get_section_contents
  3696. #define bfd_elf32_set_section_contents        hppa_elf_set_section_contents
  3697.  
  3698. #define TARGET_BIG_SYM        bfd_elf32_hppa_vec
  3699. #define TARGET_BIG_NAME        "elf32-hppa"
  3700. #define ELF_ARCH        bfd_arch_hppa
  3701. #define ELF_MACHINE_CODE    EM_HPPA
  3702. #define ELF_MAXPAGESIZE        0x1000
  3703.  
  3704. #include "elf32-target.h"
  3705.