OSDN Git Service

* elf-hppa.h (elf_hppa_final_link_relocate): Handle PCREL* relocs.
[pf3gnuchains/pf3gnuchains3x.git] / bfd / elf-hppa.h
1 /* Common code for PA ELF implementations.
2    Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #define ELF_HOWTO_TABLE_SIZE       R_PARISC_UNIMPLEMENTED + 1
21
22 /* This file is included by multiple PA ELF BFD backends with different
23    sizes.
24
25    Most of the routines are written to be size independent, but sometimes
26    external constraints require 32 or 64 bit specific code.  We remap
27    the definitions/functions as necessary here.  */
28 #if ARCH_SIZE == 64
29 #define ELF_R_TYPE(X)   ELF64_R_TYPE(X)
30 #define ELF_R_SYM(X)   ELF64_R_SYM(X)
31 #define _bfd_elf_hppa_gen_reloc_type _bfd_elf64_hppa_gen_reloc_type
32 #define elf_hppa_relocate_section elf64_hppa_relocate_section
33 #define bfd_elf_bfd_final_link bfd_elf64_bfd_final_link
34 #define elf_hppa_final_link elf64_hppa_final_link
35 #endif
36 #if ARCH_SIZE == 32
37 #define ELF_R_TYPE(X)   ELF32_R_TYPE(X)
38 #define ELF_R_SYM(X)   ELF32_R_SYM(X)
39 #define _bfd_elf_hppa_gen_reloc_type _bfd_elf32_hppa_gen_reloc_type
40 #define elf_hppa_relocate_section elf32_hppa_relocate_section
41 #define bfd_elf_bfd_final_link bfd_elf32_bfd_final_link
42 #define elf_hppa_final_link elf32_hppa_final_link
43 #endif
44
45 static boolean
46 elf_hppa_relocate_section
47   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
48            bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
49
50 static bfd_reloc_status_type elf_hppa_final_link_relocate
51   PARAMS ((Elf_Internal_Rela *, bfd *, bfd *, asection *,
52            bfd_byte *, bfd_vma, struct bfd_link_info *,
53            asection *, struct elf_link_hash_entry *,
54            struct elf64_hppa_dyn_hash_entry *));
55
56 static unsigned long elf_hppa_relocate_insn
57   PARAMS ((unsigned long, long, unsigned long));
58
59 static boolean elf_hppa_add_symbol_hook
60   PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
61            const char **, flagword *, asection **, bfd_vma *));
62
63 static boolean elf_hppa_final_link
64   PARAMS ((bfd *, struct bfd_link_info *));
65
66 /* ELF/PA relocation howto entries.  */
67
68 static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
69 {
70   {R_PARISC_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_NONE"},
71
72   /* The values in DIR32 are to placate the check in
73      _bfd_stab_section_find_nearest_line.  */
74   {R_PARISC_DIR32, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR32", false, 0, 0xffffffff, false},
75   {R_PARISC_DIR21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR21L"},
76   {R_PARISC_DIR17R, 0, 0, 17, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR17R"},
77   {R_PARISC_DIR17F, 0, 0, 17, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR17F"},
78   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
79   {R_PARISC_DIR14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR14R"},
80   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
81   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
82   {R_PARISC_PCREL32, 0, 0, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL32"},
83
84   {R_PARISC_PCREL21L, 0, 0, 21, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL21L"},
85   {R_PARISC_PCREL17R, 0, 0, 17, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL17R"},
86   {R_PARISC_PCREL17F, 0, 0, 17, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL17F"},
87   {R_PARISC_PCREL17C, 0, 0, 17, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL17C"},
88   {R_PARISC_PCREL14R, 0, 0, 14, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL14R"},
89   {R_PARISC_PCREL14F, 0, 0, 14, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL14F"},
90   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
91   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
92   {R_PARISC_DPREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL21L"},
93   {R_PARISC_DPREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL14WR"},
94
95   {R_PARISC_DPREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL14DR"},
96   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
97   {R_PARISC_DPREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL14R"},
98   {R_PARISC_DPREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL14F"},
99   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
100   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
101   {R_PARISC_DLTREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTREL21L"},
102   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
103   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
104   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
105
106   {R_PARISC_DLTREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTREL14R"},
107   {R_PARISC_DLTREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTREL14F"},
108   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
109   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
110   {R_PARISC_DLTIND21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTIND21L"},
111   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
112   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
113   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
114   {R_PARISC_DLTIND14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTIND14R"},
115   {R_PARISC_DLTIND14F, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTIND14F"},
116
117   {R_PARISC_SETBASE, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SETBASE"},
118   {R_PARISC_SECREL32, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SECREL32"},
119   {R_PARISC_BASEREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL21L"},
120   {R_PARISC_BASEREL17R, 0, 0, 17, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL17R"},
121   {R_PARISC_BASEREL17F, 0, 0, 17, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL17F"},
122   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
123   {R_PARISC_BASEREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL14R"},
124   {R_PARISC_BASEREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL14F"},
125   {R_PARISC_SEGBASE, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SEGBASE"},
126   {R_PARISC_SEGREL32, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SEGREL32"},
127
128   {R_PARISC_PLTOFF21L, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF21L"},
129   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
130   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
131   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
132   {R_PARISC_PLTOFF14R, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14R"},
133   {R_PARISC_PLTOFF14F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14F"},
134   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
135   {R_PARISC_LTOFF_FPTR32, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR32"},
136   {R_PARISC_LTOFF_FPTR21L, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR21L"},
137   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
138
139   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
140   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
141   {R_PARISC_LTOFF_FPTR14R, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14R"},
142   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
143   {R_PARISC_FPTR64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_FPTR64"},
144   {R_PARISC_PLABEL32, 0, 0, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLABEL32"},
145   {R_PARISC_PLABEL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLABEL21L"},
146   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
147   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
148   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
149
150   {R_PARISC_PLABEL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLABEL14R"},
151   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
152   {R_PARISC_PCREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL64"},
153   {R_PARISC_PCREL22C, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL22C"},
154   {R_PARISC_PCREL22F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL22F"},
155   {R_PARISC_PCREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL14WR"},
156   {R_PARISC_PCREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL14DR"},
157   {R_PARISC_PCREL16F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL16F"},
158   {R_PARISC_PCREL16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL16WF"},
159   {R_PARISC_PCREL16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL16DF"},
160
161   {R_PARISC_DIR64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR64"},
162   {R_PARISC_DIR64WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR64WR"},
163   {R_PARISC_DIR64DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR64DR"},
164   {R_PARISC_DIR14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR14WR"},
165   {R_PARISC_DIR14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR14DR"},
166   {R_PARISC_DIR16F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR16F"},
167   {R_PARISC_DIR16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR16WF"},
168   {R_PARISC_DIR16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR16DF"},
169   {R_PARISC_GPREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL64"},
170   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
171
172   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
173   {R_PARISC_DLTREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTREL14WR"},
174   {R_PARISC_DLTREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTREL14DR"},
175   {R_PARISC_GPREL16F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL16F"},
176   {R_PARISC_GPREL16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL16WF"},
177   {R_PARISC_GPREL16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL16DF"},
178   {R_PARISC_LTOFF64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF64"},
179   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
180   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
181   {R_PARISC_DLTIND14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTIND14WR"},
182
183   {R_PARISC_DLTIND14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTIND14DR"},
184   {R_PARISC_LTOFF16F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF16F"},
185   {R_PARISC_LTOFF16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF16DF"},
186   {R_PARISC_SECREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SECREL64"},
187   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
188   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
189   {R_PARISC_BASEREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BSEREL14WR"},
190   {R_PARISC_BASEREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL14DR"},
191   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
192   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
193
194   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
195   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
196   {R_PARISC_SEGREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SEGREL64"},
197   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
198   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
199   {R_PARISC_PLTOFF14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14WR"},
200   {R_PARISC_PLTOFF14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14DR"},
201   {R_PARISC_PLTOFF16F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF16F"},
202   {R_PARISC_PLTOFF16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF16WF"},
203   {R_PARISC_PLTOFF16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF16DF"},
204
205   {R_PARISC_LTOFF_FPTR64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
206   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
207   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
208   {R_PARISC_LTOFF_FPTR14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14WR"},
209   {R_PARISC_LTOFF_FPTR14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14DR"},
210   {R_PARISC_LTOFF_FPTR16F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16F"},
211   {R_PARISC_LTOFF_FPTR16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16WF"},
212   {R_PARISC_LTOFF_FPTR16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
213   {R_PARISC_COPY, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_COPY"},
214   {R_PARISC_IPLT, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_IPLT"},
215
216   {R_PARISC_EPLT, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_EPLT"},
217   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
218   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
219   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
220   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
221   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
222   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
223   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
224   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
225   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
226
227   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
228   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
229   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
230   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
231   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
232   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
233   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
234   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
235   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
236   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
237
238   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
239   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
240   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
241   {R_PARISC_TPREL32, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_TPREL32"},
242   {R_PARISC_TPREL21L, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_TPREL21L"},
243   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
244   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
245   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
246   {R_PARISC_TPREL14R, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_TPREL14R"},
247   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
248
249   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
250   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
251   {R_PARISC_LTOFF_TP21L, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP21L"},
252   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
253   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
254   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
255   {R_PARISC_LTOFF_TP14R, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
256   {R_PARISC_LTOFF_TP14F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14F"},
257   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
258   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
259
260   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
261   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
262   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
263   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
264   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
265   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
266   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
267   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
268   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
269   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
270
271   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
272   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
273   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
274   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
275   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
276   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
277   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
278   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
279   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
280   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
281
282   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
283   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
284   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
285   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
286   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
287   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
288   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
289   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
290   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
291   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
292
293   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
294   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
295   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
296   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
297   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
298   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
299   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
300   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
301   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
302   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
303
304   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
305   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
306   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
307   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
308   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
309   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
310   {R_PARISC_TPREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL64"},
311   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
312   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
313   {R_PARISC_TPREL14WR, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_TPREL14WR"},
314
315   {R_PARISC_TPREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL14DR"},
316   {R_PARISC_TPREL16F, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL16F"},
317   {R_PARISC_TPREL16WF, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_TPREL16WF"},
318   {R_PARISC_TPREL16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL16DF"},
319   {R_PARISC_LTOFF_TP64, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP64"},
320   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
321   {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED"},
322   {R_PARISC_LTOFF_TP14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14WR"},
323   {R_PARISC_LTOFF_TP14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14DR"},
324   {R_PARISC_LTOFF_TP16F, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_LTOFF_TP16F"},
325
326   {R_PARISC_LTOFF_TP16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16WF"},
327   {R_PARISC_LTOFF_TP16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16DF"},
328 };
329
330 #define OFFSET_14R_FROM_21L 4
331 #define OFFSET_14F_FROM_21L 5
332
333 /* Return one (or more) BFD relocations which implement the base
334    relocation with modifications based on format and field.  */
335
336 elf_hppa_reloc_type **
337 _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
338      bfd *abfd;
339      elf_hppa_reloc_type base_type;
340      int format;
341      int field;
342      int ignore;
343      asymbol *sym;
344 {
345   elf_hppa_reloc_type *finaltype;
346   elf_hppa_reloc_type **final_types;
347
348   /* Allocate slots for the BFD relocation.  */
349   final_types = ((elf_hppa_reloc_type **)
350                  bfd_alloc (abfd, sizeof (elf_hppa_reloc_type *) * 2));
351   if (final_types == NULL)
352     return NULL;
353
354   /* Allocate space for the relocation itself.  */
355   finaltype = ((elf_hppa_reloc_type *)
356                bfd_alloc (abfd, sizeof (elf_hppa_reloc_type)));
357   if (finaltype == NULL)
358     return NULL;
359
360   /* Some reasonable defaults.  */
361   final_types[0] = finaltype;
362   final_types[1] = NULL;
363
364 #define final_type finaltype[0]
365
366   final_type = base_type;
367
368   /* Just a tangle of nested switch statements to deal with the braindamage
369      that a different field selector means a completely different relocation
370      for PA ELF.  */
371   switch (base_type)
372     {
373     /* We have been using generic relocation types.  However, that may not
374        really make sense.  Anyway, we need to support both R_PARISC_DIR64
375        and R_PARISC_DIR32 here.  */
376     case R_PARISC_DIR32:
377     case R_PARISC_DIR64:
378     case R_HPPA_ABS_CALL:
379       switch (format)
380         {
381         case 14:
382           switch (field)
383             {
384             case e_rsel:
385             case e_rrsel:
386               final_type = R_PARISC_DIR14R;
387               break;
388             case e_rtsel:
389               final_type = R_PARISC_DLTIND14R;
390               break;
391             case e_rtpsel:
392               final_type = R_PARISC_LTOFF_FPTR14DR;
393               break;
394             case e_tsel:
395               final_type = R_PARISC_DLTIND14F;
396               break;
397             case e_rpsel:
398               final_type = R_PARISC_PLABEL14R;
399               break;
400             default:
401               return NULL;
402             }
403           break;
404
405         case 17:
406           switch (field)
407             {
408             case e_fsel:
409               final_type = R_PARISC_DIR17F;
410               break;
411             case e_rsel:
412             case e_rrsel:
413               final_type = R_PARISC_DIR17R;
414               break;
415             default:
416               return NULL;
417             }
418           break;
419
420         case 21:
421           switch (field)
422             {
423             case e_lsel:
424             case e_lrsel:
425               final_type = R_PARISC_DIR21L;
426               break;
427             case e_ltsel:
428               final_type = R_PARISC_DLTIND21L;
429               break;
430             case e_ltpsel:
431               final_type = R_PARISC_LTOFF_FPTR21L;
432               break;
433             case e_lpsel:
434               final_type = R_PARISC_PLABEL21L;
435               break;
436             default:
437               return NULL;
438             }
439           break;
440
441         case 32:
442           switch (field)
443             {
444             case e_fsel:
445               final_type = R_PARISC_DIR32;
446               /* When in 64bit mode, a 32bit relocation is supposed to
447                  be a section relative relocation.  Dwarf2 (for example)
448                  uses 32bit section relative relocations.  */
449               if (bfd_get_arch_info (abfd)->bits_per_address != 32)
450                 final_type = R_PARISC_SECREL32;
451               break;
452             case e_psel:
453               final_type = R_PARISC_PLABEL32;
454               break;
455             default:
456               return NULL;
457             }
458           break;
459
460         case 64:
461           switch (field)
462             {
463             case e_fsel:
464               final_type = R_PARISC_DIR64;
465               break;
466             case e_psel:
467               final_type = R_PARISC_FPTR64;
468               break;
469             default:
470               return NULL;
471             }
472           break;
473
474         default:
475           return NULL;
476         }
477       break;
478
479
480     case R_HPPA_GOTOFF:
481       switch (format)
482         {
483         case 14:
484           switch (field)
485             {
486             case e_rsel:
487             case e_rrsel:
488               final_type = base_type + OFFSET_14R_FROM_21L;
489               break;
490             case e_fsel:
491               final_type = base_type + OFFSET_14F_FROM_21L;
492               break;
493             default:
494               return NULL;
495             }
496           break;
497
498         case 21:
499           switch (field)
500             {
501             case e_lrsel:
502             case e_lsel:
503               final_type = base_type;
504               break;
505             default:
506               return NULL;
507             }
508           break;
509
510         default:
511           return NULL;
512         }
513       break;
514
515
516     case R_HPPA_PCREL_CALL:
517       switch (format)
518         {
519         case 14:
520           switch (field)
521             {
522             case e_rsel:
523             case e_rrsel:
524               final_type = R_PARISC_PCREL14R;
525               break;
526             case e_fsel:
527               final_type = R_PARISC_PCREL14F;
528               break;
529             default:
530               return NULL;
531             }
532           break;
533
534         case 17:
535           switch (field)
536             {
537             case e_rsel:
538             case e_rrsel:
539               final_type = R_PARISC_PCREL17R;
540               break;
541             case e_fsel:
542               final_type = R_PARISC_PCREL17F;
543               break;
544             default:
545               return NULL;
546             }
547           break;
548
549         case 22:
550           switch (field)
551             {
552             case e_fsel:
553               final_type = R_PARISC_PCREL22F;
554               break;
555             default:
556               return NULL;
557             }
558           break;
559
560         case 21:
561           switch (field)
562             {
563             case e_lsel:
564             case e_lrsel:
565               final_type = R_PARISC_PCREL21L;
566               break;
567             default:
568               return NULL;
569             }
570           break;
571
572         default:
573           return NULL;
574         }
575       break;
576
577     case R_PARISC_SEGREL32:
578     case R_PARISC_SEGBASE:
579       /* The defaults are fine for these cases.  */
580       break;
581
582     default:
583       return NULL;
584     }
585
586   return final_types;
587 }
588
589 /* Translate from an elf into field into a howto relocation pointer.  */
590
591 static void
592 elf_hppa_info_to_howto (abfd, bfd_reloc, elf_reloc)
593      bfd *abfd;
594      arelent *bfd_reloc;
595      Elf_Internal_Rela *elf_reloc;
596 {
597   BFD_ASSERT (ELF_R_TYPE(elf_reloc->r_info)
598               < (unsigned int) R_PARISC_UNIMPLEMENTED);
599   bfd_reloc->howto = &elf_hppa_howto_table[ELF_R_TYPE (elf_reloc->r_info)];
600 }
601
602 /* Translate from an elf into field into a howto relocation pointer.  */
603
604 static void
605 elf_hppa_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
606      bfd *abfd;
607      arelent *bfd_reloc;
608      Elf_Internal_Rel *elf_reloc;
609 {
610   BFD_ASSERT (ELF_R_TYPE(elf_reloc->r_info)
611               < (unsigned int) R_PARISC_UNIMPLEMENTED);
612   bfd_reloc->howto = &elf_hppa_howto_table[ELF_R_TYPE (elf_reloc->r_info)];
613 }
614
615 /* Return the address of the howto table entry to perform the CODE
616    relocation for an ARCH machine.  */
617
618 static reloc_howto_type *
619 elf_hppa_reloc_type_lookup (abfd, code)
620      bfd *abfd;
621      bfd_reloc_code_real_type code;
622 {
623   if ((int) code < (int) R_PARISC_UNIMPLEMENTED)
624     {
625       BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
626       return &elf_hppa_howto_table[(int) code];
627     }
628   return NULL;
629 }
630
631 static void
632 elf_hppa_final_write_processing (abfd, linker)
633      bfd *abfd;
634      boolean linker;
635 {
636   int mach = bfd_get_mach (abfd);
637
638   elf_elfheader (abfd)->e_flags &= ~(EF_PARISC_ARCH | EF_PARISC_TRAPNIL
639                                      | EF_PARISC_EXT | EF_PARISC_LSB
640                                      | EF_PARISC_WIDE | EF_PARISC_NO_KABP
641                                      | EF_PARISC_LAZYSWAP);
642
643   if (mach == 10)
644     elf_elfheader (abfd)->e_flags |= EFA_PARISC_1_0;
645   else if (mach == 11)
646     elf_elfheader (abfd)->e_flags |= EFA_PARISC_1_1;
647   else if (mach == 20)
648     elf_elfheader (abfd)->e_flags |= EFA_PARISC_2_0;
649   else if (mach == 25)
650     elf_elfheader (abfd)->e_flags |= EF_PARISC_WIDE | EFA_PARISC_2_0;
651 }
652
653 /* Return true if SYM represents a local label symbol.  */
654
655 static boolean
656 elf_hppa_is_local_label_name (abfd, name)
657      bfd *abfd ATTRIBUTE_UNUSED;
658      const char *name;
659 {
660   return (name[0] == 'L' && name[1] == '$');
661 }
662
663 /* Set the correct type for an ELF section.  We do this by the
664    section name, which is a hack, but ought to work.  */
665
666 static boolean
667 elf_hppa_fake_sections (abfd, hdr, sec)
668      bfd *abfd;
669      Elf64_Internal_Shdr *hdr;
670      asection *sec;
671 {
672   register const char *name;
673
674   name = bfd_get_section_name (abfd, sec);
675
676   if (strcmp (name, ".PARISC.unwind") == 0)
677     {
678       int indx;
679       asection *sec;
680       hdr->sh_type = SHT_LOPROC + 1;
681       /* ?!? How are unwinds supposed to work for symbols in arbitrary
682          sections?  Or what if we have multiple .text sections in a single
683          .o file?  HP really messed up on this one.
684
685          Ugh.  We can not use elf_section_data (sec)->this_idx at this
686          point because it is not initialized yet.
687
688          So we (gasp) recompute it here.  Hopefully nobody ever changes the
689          way sections are numbered in elf.c!  */
690       for (sec = abfd->sections, indx = 1; sec; sec = sec->next, indx++)
691         {
692           if (sec->name && strcmp (sec->name, ".text") == 0)
693             {
694               hdr->sh_info = indx;
695               break;
696             }
697         }
698
699       /* I have no idea if this is really necessary or what it means.  */
700       hdr->sh_entsize = 4;
701     }
702   return true;
703 }
704
705 /* Hook called by the linker routine which adds symbols from an object
706    file.  HP's libraries define symbols with HP specific section
707    indices, which we have to handle.  */
708
709 static boolean
710 elf_hppa_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
711      bfd *abfd;
712      struct bfd_link_info *info ATTRIBUTE_UNUSED;
713      const Elf_Internal_Sym *sym;
714      const char **namep ATTRIBUTE_UNUSED;
715      flagword *flagsp ATTRIBUTE_UNUSED;
716      asection **secp;
717      bfd_vma *valp;
718 {
719   int index = sym->st_shndx;
720
721   switch (index)
722     {
723     case SHN_PARISC_ANSI_COMMON:
724       *secp = bfd_make_section_old_way (abfd, ".PARISC.ansi.common");
725       (*secp)->flags |= SEC_IS_COMMON;
726       *valp = sym->st_size;
727       break;
728
729     case SHN_PARISC_HUGE_COMMON:
730       *secp = bfd_make_section_old_way (abfd, ".PARISC.huge.common");
731       (*secp)->flags |= SEC_IS_COMMON;
732       *valp = sym->st_size;
733       break;
734     }
735
736   return true;
737 }
738
739 /* Called after we have seen all the input files/sections, but before
740    final symbol resolution and section placement has been determined.
741
742    We use this hook to (possibly) provide a value for __gp, then we
743    fall back to the generic ELF final link routine.  */
744
745 static boolean
746 elf_hppa_final_link (abfd, info)
747      bfd *abfd;
748      struct bfd_link_info *info;
749 {
750   /* Make sure we've got ourselves a suitable __gp value.  */
751   if (!info->relocateable)
752     {
753       bfd_vma min_short_vma = (bfd_vma) -1, max_short_vma = 0;
754       struct elf_link_hash_entry *gp;
755       bfd_vma gp_val = 0;
756       asection *os;
757
758       /* Find the .opd section.  __gp's value should be the same as
759          the start of .PARISC.global section.  */
760       for (os = abfd->sections; os ; os = os->next)
761         {
762           bfd_vma lo, hi;
763
764           /* This would be cleaner if we marked sections with an attribute
765              indicating they are short sections.  */
766           if (strcmp (os->name, ".PARISC.global") == 0)
767             break;
768         }
769
770       BFD_ASSERT (os != NULL)
771
772       gp_val = (os->output_section->vma + os->output_offset);
773                    
774       gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", true,
775                                  true, false);
776       gp->root.type = bfd_link_hash_defined;
777       gp->root.u.def.section = os;
778       gp->root.u.def.value = 0;
779       _bfd_set_gp_value (abfd, gp_val);
780     }
781
782   /* Invoke the regular ELF backend linker to do all the work.  */
783   return bfd_elf_bfd_final_link (abfd, info);
784 }
785
786 /* Relocate an HPPA ELF section.  */
787
788 static boolean
789 elf_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
790                            contents, relocs, local_syms, local_sections)
791      bfd *output_bfd;
792      struct bfd_link_info *info;
793      bfd *input_bfd;
794      asection *input_section;
795      bfd_byte *contents;
796      Elf_Internal_Rela *relocs;
797      Elf_Internal_Sym *local_syms;
798      asection **local_sections;
799 {
800   Elf_Internal_Shdr *symtab_hdr;
801   Elf_Internal_Rela *rel;
802   Elf_Internal_Rela *relend;
803   struct elf64_hppa_link_hash_table *hppa_info = elf64_hppa_hash_table (info);
804
805   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
806
807   rel = relocs;
808   relend = relocs + input_section->reloc_count;
809   for (; rel < relend; rel++)
810     {
811       int r_type;
812       reloc_howto_type *howto;
813       unsigned long r_symndx;
814       struct elf_link_hash_entry *h;
815       Elf_Internal_Sym *sym;
816       asection *sym_sec;
817       bfd_vma relocation;
818       bfd_reloc_status_type r;
819       const char *sym_name;
820       char *dyn_name;
821       char *dynh_buf = NULL;
822       size_t dynh_buflen = 0;
823       struct elf64_hppa_dyn_hash_entry *dyn_h = NULL;
824
825       r_type = ELF_R_TYPE (rel->r_info);
826       if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)
827         {
828           bfd_set_error (bfd_error_bad_value);
829           return false;
830         }
831
832       r_symndx = ELF_R_SYM (rel->r_info);
833
834       if (info->relocateable)
835         {
836           /* This is a relocateable link.  We don't have to change
837              anything, unless the reloc is against a section symbol,
838              in which case we have to adjust according to where the
839              section symbol winds up in the output section.  */
840           if (r_symndx < symtab_hdr->sh_info)
841             {
842               sym = local_syms + r_symndx;
843               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
844                 {
845                   sym_sec = local_sections[r_symndx];
846                   rel->r_addend += sym_sec->output_offset;
847                 }
848             }
849
850           continue;
851         }
852
853       /* This is a final link.  */
854       h = NULL;
855       sym = NULL;
856       sym_sec = NULL;
857       if (r_symndx < symtab_hdr->sh_info)
858         {
859           /* This is a local symbol.  */
860           sym = local_syms + r_symndx;
861           sym_sec = local_sections[r_symndx];
862           relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION
863                            ? 0 : sym->st_value)
864                          + sym_sec->output_offset
865                          + sym_sec->output_section->vma);
866
867           /* If this symbol has an entry in the PA64 dynamic hash
868              table, then get it.  */
869           dyn_name = get_dyn_name (input_bfd, h, rel,
870                                    &dynh_buf, &dynh_buflen);
871           dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
872                                               dyn_name, false, false);
873
874         }
875       else
876         {
877           /* This is not a local symbol.  */
878           long indx;
879
880           indx = r_symndx - symtab_hdr->sh_info;
881           h = elf_sym_hashes (input_bfd)[indx];
882           while (h->root.type == bfd_link_hash_indirect
883                  || h->root.type == bfd_link_hash_warning)
884             h = (struct elf_link_hash_entry *) h->root.u.i.link;
885           if (h->root.type == bfd_link_hash_defined
886               || h->root.type == bfd_link_hash_defweak)
887             {
888               sym_sec = h->root.u.def.section;
889
890
891               /* If this symbol has an entry in the PA64 dynamic hash
892                  table, then get it.  */
893               dyn_name = get_dyn_name (input_bfd, h, rel,
894                                        &dynh_buf, &dynh_buflen);
895               dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
896                                                   dyn_name, false, false);
897
898               /* If we have a relocation against a symbol defined in a
899                  shared library and we have not created an entry in the
900                  PA64 dynamic symbol hash table for it, then we lose.  */
901               if (sym_sec->output_section == NULL && dyn_h == NULL)
902                 {
903                   (*_bfd_error_handler)
904                     (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
905                      bfd_get_filename (input_bfd), h->root.root.string,
906                      bfd_get_section_name (input_bfd, input_section));
907                   relocation = 0;
908                 }
909               else if (sym_sec->output_section)
910                 relocation = (h->root.u.def.value
911                               + sym_sec->output_offset
912                               + sym_sec->output_section->vma);
913               /* Value will be provided via one of the offsets in the
914                  dyn_h hash table entry.  */
915               else
916                 relocation = 0;
917             }
918           else if (h->root.type == bfd_link_hash_undefweak)
919             relocation = 0;
920           else
921             {
922               if (!((*info->callbacks->undefined_symbol)
923                     (info, h->root.root.string, input_bfd,
924                      input_section, rel->r_offset)))
925                 return false;
926               break;
927             }
928         }
929
930       if (h != NULL)
931         sym_name = h->root.root.string;
932       else
933         {
934           sym_name = bfd_elf_string_from_elf_section (input_bfd,
935                                                       symtab_hdr->sh_link,
936                                                       sym->st_name);
937           if (sym_name == NULL)
938             return false;
939           if (*sym_name == '\0')
940             sym_name = bfd_section_name (input_bfd, sym_sec);
941         }
942
943       r = elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
944                                         input_section, contents,
945                                         relocation, info, sym_sec,
946                                         h, dyn_h);
947
948       if (r != bfd_reloc_ok)
949         {
950           switch (r)
951             {
952             default:
953               abort ();
954             case bfd_reloc_overflow:
955               {
956                 if (!((*info->callbacks->reloc_overflow)
957                       (info, sym_name, howto->name, (bfd_vma) 0,
958                         input_bfd, input_section, rel->r_offset)))
959                   return false;
960               }
961               break;
962             }
963         }
964     }
965   return true;
966 }
967
968
969 /* Compute the value for a relocation (REL) during a final link stage,
970    then insert the value into the proper location in CONTENTS. 
971
972    VALUE is a tentative value for the relocation and may be overridden
973    and modified here based on the specific relocation to be performed.
974
975    For example we do conversions for PC-relative branches in this routine
976    or redirection of calls to external routines to stubs. 
977
978    The work of actually applying the relocation is left to a helper
979    routine in an attempt to reduce the complexity and size of this
980    function.  */
981
982 static bfd_reloc_status_type
983 elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
984                               input_section, contents, value,
985                               info, sym_sec, h, dyn_h)
986      Elf_Internal_Rela *rel;
987      bfd *input_bfd;
988      bfd *output_bfd;
989      asection *input_section;
990      bfd_byte *contents;
991      bfd_vma value;
992      struct bfd_link_info *info;
993      asection *sym_sec;
994      struct elf_link_hash_entry *h;
995      struct elf64_hppa_dyn_hash_entry *dyn_h;
996 {
997   unsigned long insn;
998   bfd_vma offset = rel->r_offset;
999   bfd_vma addend = rel->r_addend;
1000   reloc_howto_type *howto = elf_hppa_howto_table + ELF_R_TYPE (rel->r_info);
1001   unsigned long r_type = howto->type;
1002   unsigned long r_format = howto->bitsize;
1003   unsigned long r_field = e_fsel;
1004   bfd_byte *hit_data = contents + offset;
1005   struct elf64_hppa_link_hash_table *hppa_info = elf64_hppa_hash_table (info);
1006
1007   insn = bfd_get_32 (input_bfd, hit_data);
1008
1009 /* For reference here a quick summary of the relocations found in the
1010    HPUX 11.00 PA64 .o and .a files, but not yet implemented.  This is mostly
1011    a guide to help prioritize what relocation support is worked on first.
1012    The list will be deleted eventually.
1013
1014    27210 R_PARISC_SEGREL32
1015    1096 R_PARISC_LTOFF_TP14DR
1016    982 R_PARISC_LTOFF_TP21L
1017    791 R_PARISC_GPREL64
1018    772 R_PARISC_PLTOFF14DR
1019    386 R_PARISC_PLTOFF21L
1020    6 R_PARISC_LTOFF64
1021    5 R_PARISC_SEGREL64  */
1022
1023   switch (r_type)
1024     {
1025     case R_PARISC_NONE:
1026       break;
1027
1028     /* Random PC relative relocs.  */
1029     case R_PARISC_PCREL21L;
1030     case R_PARISC_PCREL14R;
1031     case R_PARISC_PCREL14F;
1032     case R_PARISC_PCREL14WR:
1033     case R_PARISC_PCREL14DR:
1034     case R_PARISC_PCREL16F:
1035     case R_PARISC_PCREL16WF:
1036     case R_PARISC_PCREL16DF:
1037       {
1038         if (r_type == R_PARISC_PCREL21L)
1039           r_field = e_lsel;
1040         else if (r_type == R_PARISC_PCREL14F
1041                  || r_type == R_PARISC_PCREL16F
1042                  || r_type == R_PARISC_PCREL16WF
1043                  || r_type == R_PARISC_PCREL16DF)
1044           r_field = e_fsel;
1045         else
1046           r_field = e_rsel;
1047
1048         /* If this is a call to a function defined in another dynamic
1049            library, then redirect the call to the local stub for this
1050            function.  */
1051         if (sym_sec->output_section == NULL)
1052           value = dyn_h->stub_offset;
1053   
1054         /* Turn VALUE into a proper PC relative address.  */
1055         value -= (offset + input_section->output_offset
1056                   + input_section->output_section->vma);
1057
1058         /* Adjust for any field selectors.  */
1059         value = hppa_field_adjust (value, -8 + addend, r_field);
1060
1061         /* Apply the relocation to the given instruction.  */
1062         insn = elf_hppa_relocate_insn (insn, value, r_type);
1063         break;
1064       }
1065
1066     /* Basic function call support.  I'm not entirely sure if PCREL14F is
1067        actually needed or even handled correctly.
1068
1069        Note for a call to a function defined in another dynamic library
1070        we want to redirect the call to a stub.  */
1071     case R_PARISC_PCREL22F:
1072     case R_PARISC_PCREL17F:
1073     case R_PARISC_PCREL22C:
1074     case R_PARISC_PCREL17C:
1075     case R_PARISC_PCREL17R:
1076       {
1077         if (r_type == R_PARISC_PCREL17R)
1078           r_field = e_rsel;
1079         else
1080           r_field = e_fsel;
1081
1082         /* If this is a call to a function defined in another dynamic
1083            library, then redirect the call to the local stub for this
1084            function.  */
1085         if (sym_sec->output_section == NULL)
1086           value = dyn_h->stub_offset;
1087   
1088         /* Turn VALUE into a proper PC relative address.  */
1089         value -= (offset + input_section->output_offset
1090                   + input_section->output_section->vma);
1091
1092         /* Adjust for any field selectors.  */
1093         value = hppa_field_adjust (value, -8 + addend, e_fsel);
1094
1095         /* All branches are implicitly shifted by 2 places.  */
1096         value >>= 2;
1097
1098         /* Apply the relocation to the given instruction.  */
1099         insn = elf_hppa_relocate_insn (insn, value, r_type);
1100         break;
1101       }
1102
1103     /* Indirect references to data through the DLT.  */
1104     case R_PARISC_DLTIND14R:
1105     case R_PARISC_DLTIND14F:
1106     case R_PARISC_DLTIND14DR:
1107     case R_PARISC_DLTIND14WR:
1108     case R_PARISC_DLTIND21L:
1109     case R_PARISC_LTOFF_FPTR14R:
1110     case R_PARISC_LTOFF_FPTR14DR:
1111     case R_PARISC_LTOFF_FPTR14WR:
1112     case R_PARISC_LTOFF_FPTR21L:
1113     case R_PARISC_LTOFF_FPTR16F:
1114     case R_PARISC_LTOFF_FPTR16WF:
1115     case R_PARISC_LTOFF_FPTR16DF:
1116       {
1117         /* We want the value of the DLT offset for this symbol, not
1118            the symbol's actual address.  */
1119         value = dyn_h->dlt_offset + hppa_info->dlt_sec->output_offset;
1120
1121         /* All DLTIND relocations are basically the same at this point,
1122            except that we need different field selectors for the 21bit
1123            version vs the 14bit versions.  */
1124         if (r_type == R_PARISC_DLTIND21L
1125             || r_type == R_PARISC_LTOFF_FPTR21L)
1126           value = hppa_field_adjust (value, addend, e_lrsel);
1127         else if (r_type == R_PARISC_DLTIND14F
1128                  || r_type == R_PARISC_LTOFF_FPTR16F
1129                  || r_type == R_PARISC_LTOFF_FPTR16WF
1130                  || r_type == R_PARISC_LTOFF_FPTR16DF)
1131           value = hppa_field_adjust (value, addend, e_fsel);
1132         else
1133           value = hppa_field_adjust (value, addend, e_rrsel);
1134
1135         insn = elf_hppa_relocate_insn (insn, value, r_type);
1136         break;
1137       }
1138
1139     case R_PARISC_DLTREL14R:
1140     case R_PARISC_DLTREL14F:
1141     case R_PARISC_DLTREL14DR:
1142     case R_PARISC_DLTREL14WR:
1143     case R_PARISC_DLTREL21L:
1144       {
1145         /* Subtract out the global pointer value to make value a DLT
1146            relative address.  */
1147         value -= _bfd_get_gp_value (output_bfd);
1148
1149         /* All DLTREL relocations are basically the same at this point,
1150            except that we need different field selectors for the 21bit
1151            version vs the 14bit versions.  */
1152         if (r_type == R_PARISC_DLTREL21L)
1153           value = hppa_field_adjust (value, addend, e_lrsel);
1154         else if (r_type == R_PARISC_DLTREL14F)
1155           value = hppa_field_adjust (value, addend, e_fsel);
1156         else
1157           value = hppa_field_adjust (value, addend, e_rrsel);
1158
1159         insn = elf_hppa_relocate_insn (insn, value, r_type);
1160         break;
1161       }
1162
1163     case R_PARISC_LTOFF_FPTR32:
1164       {
1165         /* We want the value of the DLT offset for this symbol, not
1166            the symbol's actual address.  */
1167         value = dyn_h->dlt_offset + hppa_info->dlt_sec->output_offset;
1168         bfd_put_32 (input_bfd, value, hit_data);
1169         return bfd_reloc_ok;
1170       }
1171
1172     case R_PARISC_LTOFF_FPTR64:
1173       {
1174         /* We want the value of the DLT offset for this symbol, not
1175            the symbol's actual address.  */
1176         value = dyn_h->dlt_offset + hppa_info->dlt_sec->output_offset;
1177         bfd_put_64 (input_bfd, value, hit_data);
1178         return bfd_reloc_ok;
1179       }
1180
1181     case R_PARISC_DIR32:
1182       bfd_put_32 (input_bfd, value + addend, hit_data);
1183       return bfd_reloc_ok;
1184
1185     case R_PARISC_DIR64:
1186       bfd_put_64 (input_bfd, value + addend, hit_data);
1187       return bfd_reloc_ok;
1188
1189     case R_PARISC_PCREL32:
1190       {
1191         /* If this is a call to a function defined in another dynamic
1192            library, then redirect the call to the local stub for this
1193            function.  */
1194         if (sym_sec->output_section == NULL)
1195           value = dyn_h->stub_offset;
1196   
1197         /* Turn VALUE into a proper PC relative address.  */
1198         value -= (offset + input_section->output_offset
1199                   + input_section->output_section->vma);
1200
1201         value += addend
1202         value -= 8;
1203         bfd_put_64 (input_bfd, value, hit_data);
1204         return bfd_reloc_ok;
1205       }
1206
1207     case R_PARISC_PCREL64:
1208       {
1209         /* If this is a call to a function defined in another dynamic
1210            library, then redirect the call to the local stub for this
1211            function.  */
1212         if (sym_sec->output_section == NULL)
1213           value = dyn_h->stub_offset;
1214   
1215         /* Turn VALUE into a proper PC relative address.  */
1216         value -= (offset + input_section->output_offset
1217                   + input_section->output_section->vma);
1218
1219         value += addend
1220         value -= 8;
1221         bfd_put_64 (input_bfd, value, hit_data);
1222         return bfd_reloc_ok;
1223       }
1224
1225
1226     /* These do not require any work here.  They are simply passed
1227        through as dynamic relocations.  */
1228     case R_PARISC_FPTR64:
1229       return bfd_reloc_ok;
1230
1231     /* Something we don't know how to handle.  */
1232     default:
1233       /* ?!? This is temporary as we flesh out basic linker support, once
1234          the basic support is functional we will return the not_supported
1235          error conditional appropriately.  */
1236 #if 0
1237       return bfd_reloc_not_supported;
1238 #else
1239       return bfd_reloc_ok;
1240 #endif
1241     }
1242
1243   /* Update the instruction word.  */
1244   bfd_put_32 (input_bfd, insn, hit_data);
1245   return (bfd_reloc_ok);
1246 }
1247
1248 /* Relocate the given INSN.  VALUE should be the actual value we want
1249    to insert into the instruction, ie by this point we should not be
1250    concerned with computing an offset relative to the DLT, PC, etc.
1251    Instead this routine is meant to handle the bit manipulations needed
1252    to insert the relocation into the given instruction.  */
1253
1254 static unsigned long
1255 elf_hppa_relocate_insn (insn, sym_value, r_type)
1256      unsigned long insn;
1257      long sym_value;
1258      unsigned long r_type;
1259 {
1260   long constant_value;
1261
1262   switch (r_type)
1263     {
1264     /* This is any 22bit branch.  In PA2.0 syntax it corresponds to
1265        the "B" instruction.  */
1266     case R_PARISC_PCREL22F:
1267     case R_PARISC_PCREL22C:
1268       {
1269         unsigned int w3, w2, w1, w;
1270
1271         /* These are 22 bit branches.  Mask off bits we do not care
1272            about.  */
1273         sym_value &= 0x3fffff;
1274
1275         /* Now extract the W1, W2, W3 and W fields from the value.  */
1276         dis_assemble_22 (sym_value, &w3, &w1, &w2, &w);
1277
1278         /* Mask out bits for the value in the instruction.  */
1279         insn &= 0xfc00e002;
1280
1281         /* Insert the bits for the W1, W2 and W fields into the
1282            instruction.  */
1283         insn |= (w3 << 21) | (w2 << 2) | (w1 << 16) | w;
1284         return insn;
1285        }
1286
1287     /* This is any 17bit branch.  In PA2.0 syntax it also corresponds to
1288        the "B" instruction as well as BE.  */
1289     case R_PARISC_PCREL17F:
1290     case R_PARISC_DIR17F:
1291     case R_PARISC_PCREL17C:
1292     case R_PARISC_PCREL17R:
1293       {
1294         unsigned int w2, w1, w;
1295
1296         /* These are 17 bit branches.  Mask off bits we do not care
1297            about.  */
1298         sym_value &= 0x1ffff;
1299
1300         /* Now extract the W1, W2 and W fields from the value.  */
1301         dis_assemble_17 (sym_value, &w1, &w2, &w);
1302
1303         /* Mask out bits for the value in the instruction.  */
1304         insn &= 0xffe0e002;
1305
1306         /* Insert the bits for the W1, W2 and W fields into the
1307            instruction.  */
1308         insn |= (w2 << 2) | (w1 << 16) | w;
1309         return insn;
1310       }
1311
1312     /* ADDIL or LDIL instructions.  */
1313     case R_PARISC_DLTREL21L:
1314     case R_PARISC_DLTIND21L:
1315     case R_PARISC_LTOFF_FPTR21L:
1316     case R_PARISC_PCREL21L;
1317       {
1318         int w;
1319
1320         /* Mask off bits in INSN we do not want.  */
1321         insn &= 0xffe00000;
1322
1323         /* Turn the 21bit value into the proper format.  */
1324         dis_assemble_21 (sym_value, &w);
1325
1326         /* And insert the proper bits into INSN.  */
1327         return insn | w;
1328       }
1329
1330     /* LDO and integer loads/stores with 14bit displacements.  */
1331     case R_PARISC_DLTREL14R:
1332     case R_PARISC_DLTREL14F:
1333     case R_PARISC_DLTIND14R:
1334     case R_PARISC_DLTIND14F:
1335     case R_PARISC_LTOFF_FPTR14R:
1336     case R_PARISC_LTOFF_FPTR16F:
1337     case R_PARISC_PCREL14R;
1338     case R_PARISC_PCREL14F:
1339     case R_PARISC_PCREL16F:
1340       {
1341         int w;
1342
1343         /* Mask off bits in INSN we do not want.  */
1344         insn &= 0xffffc000;
1345
1346         /* Turn the 14bit value into the proper format.  */
1347         low_sign_unext (sym_value, 14, &w);
1348
1349         /* And insert the proper bits into INSN.  */
1350         return insn | w;
1351       }
1352
1353     /* Doubleword loads and stores with a 14bit displacement.  */
1354     case R_PARISC_DLTREL14DR:
1355     case R_PARISC_DLTIND14DR:
1356     case R_PARISC_LTOFF_FPTR14DR:
1357     case R_PARISC_LTOFF_FPTR16DF:
1358     case R_PARISC_PCREL14DR:
1359     case R_PARISC_PCREL16DF:
1360       {
1361         int w;
1362
1363         /* Mask off bits in INSN we do not want.  */
1364         insn &= 0xffffc00e;
1365
1366         /* The sign bit at 14 moves into bit zero in the destination.  */
1367         insn |= ((sym_value & 0x2000) >> 13);
1368
1369         /* Turn off the bits in sym_value we do not care about.  */
1370         sym_value &= 0x1ff8;
1371
1372         /* Now shift it one bit position left so that it lines up with the
1373            destination field in INSN.  */
1374         sym_value <<= 1;
1375
1376         return insn | sym_value;
1377       }
1378
1379     /* Floating point single word load/store instructions.  */
1380     case R_PARISC_DLTREL14WR:
1381     case R_PARISC_DLTIND14WR:
1382     case R_PARISC_LTOFF_FPTR14WR:
1383     case R_PARISC_LTOFF_FPTR16WF:
1384     case R_PARISC_PCREL14WR:
1385     case R_PARISC_PCREL16WF:
1386       {
1387         int w;
1388
1389         /* Mask off bits in INSN we do not want.  */
1390         insn &= 0xffffc006;
1391
1392         /* The sign bit at 14 moves into bit zero in the destination.  */
1393         insn |= ((sym_value & 0x2000) >> 13);
1394
1395         /* Turn off the bits in sym_value we do not care about.  */
1396         sym_value &= 0x1ffc;
1397
1398         /* Now shift it one bit position left so that it lines up with the
1399            destination field in INSN.  */
1400         sym_value <<= 1;
1401
1402         return insn | sym_value;
1403       }
1404
1405     default:
1406       return insn;
1407     }
1408 }