]> Git Repo - binutils.git/blob - bfd/elf32-hppa.c
* gdb.t20/gdbme.cc (main): Move variable initialization for AIX to
[binutils.git] / bfd / elf32-hppa.c
1 /* BFD back-end for HP PA-RISC ELF files.
2    Copyright (C) 1990-1991 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 "libelf.h"
31
32 /* ELF32/HPPA relocation support
33
34         This file contains ELF32/HPPA relocation support as specified
35         in the Stratus FTX/Golf Object File Format (SED-1762) dated
36         November 19, 1992.
37 */
38
39 /*
40         Written by:
41
42         Center for Software Science
43         Department of Computer Science
44         University of Utah
45 */
46
47 #include "elf32-hppa.h"
48 /*#include "libhppa.h"*/
49 #define BYTES_IN_WORD 4
50 #include "aout/aout64.h"
51
52 /* ELF/PA relocation howto entries */
53
54 static bfd_reloc_status_type hppa_elf_reloc ();
55
56 reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
57 {
58 /*  'bitpos' and 'abs' are obsolete */
59 /* type                 rs sz bsz pcrel  bpos abs    ovrf  sf              name */
60 /* 9.3.4. Address relocation types */
61   {R_HPPA_NONE, 0, 3, 19, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NONE"},
62   {R_HPPA_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_32"},
63   {R_HPPA_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_11"},
64   {R_HPPA_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_14"},
65   {R_HPPA_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_17"},
66 {R_HPPA_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L21"},
67 {R_HPPA_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R11"},
68 {R_HPPA_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R14"},
69 {R_HPPA_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R17"},
70   {R_HPPA_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LS21"},
71   {R_HPPA_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS11"},
72   {R_HPPA_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS14"},
73   {R_HPPA_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS17"},
74   {R_HPPA_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LD21"},
75   {R_HPPA_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD11"},
76   {R_HPPA_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD14"},
77   {R_HPPA_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD17"},
78   {R_HPPA_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LR21"},
79   {R_HPPA_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR14"},
80   {R_HPPA_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR17"},
81 /* 9.3.5. GOTOFF address relocation types               */
82   {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_11"},
83   {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_14"},
84   {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"},
85   {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"},
86   {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"},
87   {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"},
88   {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"},
89   {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"},
90   {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"},
91   {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"},
92   {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"},
93   {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"},
94   {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"},
95 /* 9.3.6. Absolute call relocation types        */
96   {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"},
97   {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"},
98   {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"},
99   {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"},
100   {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"},
101   {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"},
102   {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"},
103   {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"},
104   {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"},
105   {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"},
106   {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"},
107   {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"},
108   {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"},
109   {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"},
110   {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"},
111   {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"},
112   {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"},
113   {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"},
114 /* 9.3.7. PC-relative call relocation types     */
115   {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"},
116   {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"},
117   {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"},
118   {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"},
119   {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"},
120   {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"},
121   {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"},
122   {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"},
123   {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"},
124   {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"},
125   {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"},
126   {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"},
127   {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"},
128   {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"},
129   {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"},
130   {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"},
131   {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"},
132   {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"},
133   {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"},
134
135 /* 9.3.8. Plabel relocation types */
136   {R_HPPA_PLABEL_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_32"},
137   {R_HPPA_PLABEL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_11"},
138   {R_HPPA_PLABEL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_14"},
139   {R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_L21"},
140   {R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R11"},
141   {R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R14"},
142
143 /* 9.3.9. Data linkage table (DLT) relocation types     */
144   {R_HPPA_DLT_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_32"},
145   {R_HPPA_DLT_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_11"},
146   {R_HPPA_DLT_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_14"},
147   {R_HPPA_DLT_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_L21"},
148   {R_HPPA_DLT_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R11"},
149   {R_HPPA_DLT_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R14"},
150
151 /* 9.3.10. Relocations for unwinder tables      */
152   {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
153   {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"},
154
155 /*  9.3.11. Relocation types for complex expressions    */
156   {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_CONST"},
157   {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PC"},
158   {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_SYM"},
159   {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"},
160   {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"},
161   {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"},
162   {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"},
163 {R_HPPA_MAX, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MAX"},
164 {R_HPPA_MIN, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MIN"},
165 {R_HPPA_ADD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ADD"},
166 {R_HPPA_SUB, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_SUB"},
167   {R_HPPA_MULT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MULT"},
168 {R_HPPA_DIV, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_DIV"},
169 {R_HPPA_MOD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MOD"},
170 {R_HPPA_AND, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_AND"},
171   {R_HPPA_OR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_OR"},
172 {R_HPPA_XOR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_XOR"},
173 {R_HPPA_NOT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NOT"},
174   {R_HPPA_LSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LSHIFT"},
175   {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"},
176   {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"},
177 {R_HPPA_EXPR_F, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L"},
178   {R_HPPA_EXPR_L, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_L"},
179   {R_HPPA_EXPR_R, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_R"},
180   {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LS"},
181   {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RS"},
182   {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LD"},
183   {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RD"},
184   {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LR"},
185   {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RR"},
186
187   {R_HPPA_EXPR_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_32"},
188   {R_HPPA_EXPR_21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_21"},
189   {R_HPPA_EXPR_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_11"},
190   {R_HPPA_EXPR_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_14"},
191   {R_HPPA_EXPR_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_17"},
192   {R_HPPA_EXPR_12, 0, 3, 12, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_12"},
193   {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, false, false, NULL, "R_HPPA_UNIMPLEMENTED"},
194 };
195
196 static symext_chainS *symext_rootP = NULL;
197 static symext_chainS *symext_lastP = NULL;
198
199 static unsigned long
200 DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format),
201        bfd * abfd AND
202        unsigned long insn AND
203        unsigned long value AND
204        unsigned short r_type AND
205        unsigned short r_field AND
206        unsigned short r_format)
207 {
208   unsigned long const_part;     /* part of the instruction that does not change */
209   unsigned long rebuilt_part;
210
211   switch (r_format)
212     {
213     case 11:
214       {
215         unsigned w1, w;
216
217         const_part = insn & 0xffffe002;
218         dis_assemble_12 (value, &w1, &w);
219         rebuilt_part = (w1 << 2) | w;
220         return const_part | rebuilt_part;
221       }
222
223     case 12:
224       {
225         unsigned w1, w;
226
227         const_part = insn & 0xffffe002;
228         dis_assemble_12 (value, &w1, &w);
229         rebuilt_part = (w1 << 2) | w;
230         return const_part | rebuilt_part;
231       }
232
233     case 14:
234       const_part = insn & 0xffffc000;
235       low_sign_unext (value, 14, &rebuilt_part);
236       return const_part | rebuilt_part;
237
238     case 17:
239       {
240         unsigned w1, w2, w;
241
242         const_part = insn & 0xffe0e002;
243         dis_assemble_17 (value, &w1, &w2, &w);
244         rebuilt_part = (w2 << 2) | (w1 << 16) | w;
245         return const_part | rebuilt_part;
246       }
247
248     case 21:
249       const_part = insn & 0xffe00000;
250       dis_assemble_21 (value, &rebuilt_part);
251       return const_part | rebuilt_part;
252
253     case 32:
254       const_part = 0;
255       return value;
256
257     default:
258       fprintf (stderr, "Relocation problem : ");
259       fprintf (stderr,
260                "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
261                r_type, r_format, r_field, abfd->filename);
262     }
263   return insn;
264 }
265
266 static unsigned long
267 DEFUN (hppa_elf_relocate_insn,
268        (abfd, input_sect,
269         insn, address, symp, sym_value, r_addend,
270         r_type, r_format, r_field, pcrel),
271        bfd * abfd AND
272        asection * input_sect AND
273        unsigned long insn AND
274        unsigned long address AND
275        asymbol * symp AND
276        long sym_value AND
277        long r_addend AND
278        unsigned short r_type AND
279        unsigned short r_format AND
280        unsigned short r_field AND
281        unsigned char pcrel)
282 {
283   unsigned char opcode = get_opcode (insn);
284   long constant_value;
285   unsigned arg_reloc;
286
287   switch (opcode)
288     {
289     case LDO:
290     case LDB:
291     case LDH:
292     case LDW:
293     case LDWM:
294     case STB:
295     case STH:
296     case STW:
297     case STWM:
298       constant_value = ELF32_HPPA_R_CONSTANT (r_addend);
299       BFD_ASSERT (r_format == 14);
300
301       if (pcrel)
302         sym_value -= address;
303       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
304       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_format, r_format);
305
306     case COMICLR:
307     case SUBI:                  /* case SUBIO: */
308     case ADDIT:         /* case ADDITO: */
309     case ADDI:                  /* case ADDIO: */
310       BFD_ASSERT (r_format == 11);
311
312       constant_value = ((insn & 0x1) << 10) | ((insn & 0xffe) >> 1);
313       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
314       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
315
316     case LDIL:
317     case ADDIL:
318       BFD_ASSERT (r_format == 21);
319
320       constant_value = assemble_21 (insn);
321       constant_value += ELF32_HPPA_R_CONSTANT (r_addend);
322       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
323       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
324
325     case BL:
326     case BE:
327     case BLE:
328       arg_reloc = ELF32_HPPA_R_ARG_RELOC (r_addend);
329
330       BFD_ASSERT (r_format == 17);
331
332       /* XXX computing constant_value is not needed??? */
333       constant_value = assemble_17 ((insn & 0x001f0000) >> 16,
334                                     (insn & 0x00001ffc) >> 2,
335                                     insn & 1);
336       /* @@ Assumes only 32 bits.  */
337       constant_value = (constant_value << 15) >> 15;
338       if (pcrel)
339         {
340           sym_value -=
341             address + input_sect->output_offset
342             + input_sect->output_section->vma;
343           sym_value = hppa_field_adjust (sym_value, -8, r_field);
344         }
345       else
346         sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
347
348       return hppa_elf_rebuild_insn (abfd, insn, sym_value >> 2, r_type, r_field, r_format);
349
350     default:
351       if (opcode == 0)
352         {
353           BFD_ASSERT (r_format == 32);
354           constant_value = insn;
355           constant_value += ELF32_HPPA_R_CONSTANT (r_addend);
356
357           return hppa_field_adjust (sym_value, constant_value, r_field);
358         }
359       else
360         {
361           fprintf (stderr,
362                    "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
363                    opcode, r_format, r_field);
364           return insn;
365         }
366     }
367 }
368
369 static void
370 DEFUN (hppa_elf_relocate_unwind_table,
371        (abfd, input_sect,
372         data, address, symp, sym_value, r_addend,
373         r_type, r_format, r_field, pcrel),
374        bfd * abfd AND
375        asection * input_sect AND
376        PTR data AND
377        unsigned long address AND
378        asymbol * symp AND
379        long sym_value AND
380        long r_addend AND
381        unsigned short r_type AND
382        unsigned short r_format AND
383        unsigned short r_field AND
384        unsigned char pcrel)
385 {
386   bfd_byte *hit_data = address + (bfd_byte *) (data);
387   long start_offset;
388   long end_offset;
389   long relocated_value;
390   int i;
391
392   BFD_ASSERT (r_format == 32);
393   BFD_ASSERT (r_field == e_fsel);
394   switch (r_type)
395     {
396     case R_HPPA_UNWIND_ENTRY:
397       start_offset = bfd_get_32 (abfd, hit_data);
398       relocated_value = hppa_field_adjust (sym_value, start_offset, r_field);
399       bfd_put_32 (abfd, relocated_value, hit_data);
400
401       hit_data += sizeof (unsigned long);
402       end_offset = bfd_get_32 (abfd, hit_data);
403       relocated_value = hppa_field_adjust (sym_value, end_offset, r_field);
404       bfd_put_32 (abfd, relocated_value, hit_data);
405       break;
406
407     case R_HPPA_UNWIND_ENTRIES:
408       for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long))
409         {
410           unsigned int fsize;
411           start_offset = bfd_get_32 (abfd, hit_data);
412           /* Stuff the symbol value into the first word */
413           /* of the  unwind descriptor */
414           bfd_put_32 (abfd, sym_value, hit_data);
415
416           hit_data += sizeof (unsigned long);
417           end_offset = bfd_get_32 (abfd, hit_data);
418           /* We could also compute the ending offset for */
419           /* the 2nd word of the unwind entry by */
420           /* retrieving the st_size field of the Elf_Sym */
421           /* structure stored with this symbol.  We can */
422           /* get it with:       */
423           /*    e = (elf_symbol_type *)symp     */
424           /*    fsize = e->internal_elf_sym.st_size */
425
426           fsize = end_offset - start_offset;
427           relocated_value = hppa_field_adjust (sym_value, fsize, r_field);
428           bfd_put_32 (abfd, relocated_value, hit_data);
429
430           /* If this is not the last unwind entry, */
431           /* adjust the symbol value. */
432           if (i + 1 < r_addend)
433             {
434               start_offset = bfd_get_32 (abfd, hit_data + 3 * sizeof (unsigned long));
435               sym_value += fsize + start_offset - end_offset;
436             }
437         }
438       break;
439
440     default:
441       fprintf (stderr,
442                "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
443                r_type, r_format, r_field);
444     }
445 }
446
447 /* Provided the symbol, returns the value reffed */
448 static long
449 get_symbol_value (symbol)
450      asymbol *symbol;
451 {
452   long relocation = 0;
453
454   if (symbol == (asymbol *) NULL)
455     relocation = 0;
456   else if (symbol->section == &bfd_com_section)
457     {
458       relocation = 0;
459     }
460   else
461     {
462       relocation = symbol->value +
463         symbol->section->output_section->vma +
464         symbol->section->output_offset;
465     }
466
467   return (relocation);
468 }
469
470 /* This function provides a pretty straight-forward mapping between a */
471 /* base relocation type, format and field into the relocation type */
472 /* that will be emitted in an object file.  The only wrinkle in the */
473 /* mapping is that when the T, TR, TL, P, PR, or PL expression */
474 /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
475 /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
476 /* (in the case of P, PR, and PL).      */
477
478 /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
479 /* handled yet. */
480
481 static void
482 hppa_elf_gen_reloc_error (base_type, fmt, field)
483      elf32_hppa_reloc_type base_type;
484      int fmt;
485      int field;
486 {
487   fprintf (stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
488            base_type, fmt, field);
489 }
490
491 elf32_hppa_reloc_type **
492 hppa_elf_gen_reloc_type (abfd, base_type, format, field)
493      bfd *abfd;
494      elf32_hppa_reloc_type base_type;
495      int format;
496      int field;
497 {
498 #define UNDEFINED       hppa_elf_gen_reloc_error(base_type,format,field);
499
500   elf32_hppa_reloc_type *finaltype;
501   elf32_hppa_reloc_type **final_types;
502   int i;
503
504   final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2);
505   BFD_ASSERT (final_types != 0);
506
507   finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type));
508   BFD_ASSERT (finaltype != 0);
509
510   final_types[0] = finaltype;
511   final_types[1] = NULL;
512
513 #define final_type finaltype[0]
514
515   final_type = base_type;
516
517   switch (base_type)
518     {
519     case R_HPPA:
520       switch (format)
521         {
522         case 11:
523           switch (field)
524             {
525             case e_fsel:
526               final_type = R_HPPA_11;
527               break;
528             case e_rsel:
529               final_type = R_HPPA_R11;
530               break;
531             case e_rssel:
532               final_type = R_HPPA_RS11;
533               break;
534             case e_rdsel:
535               final_type = R_HPPA_RD11;
536               break;
537
538             case e_psel:
539               final_type = R_HPPA_PLABEL_11;
540               break;
541             case e_rpsel:
542               final_type = R_HPPA_PLABEL_R11;
543               break;
544             case e_lpsel:
545             case e_tsel:
546             case e_ltsel:
547             case e_rtsel:
548
549             case e_lsel:
550             case e_lrsel:
551             case e_lssel:
552             case e_rrsel:
553             default:
554               UNDEFINED;
555               final_type = base_type;
556               break;
557             }
558           break;
559         case 12:
560           UNDEFINED;
561           break;
562         case 14:
563           switch (field)
564             {
565             case e_rsel:
566               final_type = R_HPPA_R14;
567               break;
568             case e_rssel:
569               final_type = R_HPPA_RS14;
570               break;
571             case e_rdsel:
572               final_type = R_HPPA_RD14;
573               break;
574             case e_rrsel:
575               final_type = R_HPPA_RR14;
576               break;
577
578             case e_psel:
579               final_type = R_HPPA_PLABEL_14;
580               break;
581             case e_rpsel:
582               final_type = R_HPPA_PLABEL_R14;
583               break;
584             case e_lpsel:
585             case e_tsel:
586             case e_ltsel:
587             case e_rtsel:
588
589             case e_fsel:
590             case e_lsel:
591             case e_lssel:
592             case e_ldsel:
593             case e_lrsel:
594             default:
595               UNDEFINED;
596               final_type = base_type;
597               break;
598             }
599           break;
600         case 17:
601           switch (field)
602             {
603             case e_fsel:
604               final_type = R_HPPA_17;
605               break;
606             case e_rsel:
607               final_type = R_HPPA_R17;
608               break;
609             case e_rssel:
610               final_type = R_HPPA_RS17;
611               break;
612             case e_rdsel:
613               final_type = R_HPPA_RD17;
614               break;
615             case e_rrsel:
616               final_type = R_HPPA_RR17;
617               break;
618             case e_lsel:
619             case e_lssel:
620             case e_ldsel:
621             case e_lrsel:
622             default:
623               UNDEFINED;
624               final_type = base_type;
625               break;
626             }
627           break;
628         case 21:
629           switch (field)
630             {
631             case e_lsel:
632               final_type = R_HPPA_L21;
633               break;
634             case e_lssel:
635               final_type = R_HPPA_LS21;
636               break;
637             case e_ldsel:
638               final_type = R_HPPA_LD21;
639               break;
640             case e_lrsel:
641               final_type = R_HPPA_LR21;
642               break;
643             case e_lpsel:
644               final_type = R_HPPA_PLABEL_L21;
645               break;
646             case e_rsel:
647             case e_rssel:
648             case e_rdsel:
649             case e_rrsel:
650             case e_fsel:
651             default:
652               UNDEFINED;
653               final_type = base_type;
654               break;
655             }
656           break;
657         case 32:
658           switch (field)
659             {
660             case e_fsel:
661               final_type = R_HPPA_32;
662               break;
663             case e_psel:
664               final_type = R_HPPA_PLABEL_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 /* 12.4.4. Derive format from instruction       */
1182
1183 /*      Given a machine instruction, this function determines its format.       */
1184 /*      The format can be determined solely from looking at the first six       */
1185 /*      bits (the major opcode) of the instruction.  Several major opcodes      */
1186 /*      map to the same format.  Opcodes which do not map to a known format     */
1187 /*      should probably be reported as an error.                                */
1188
1189 unsigned char
1190 hppa_elf_insn2fmt (type, insn)
1191      elf32_hppa_reloc_type type;
1192      unsigned long insn;
1193 {
1194   unsigned char fmt = 0;        /* XXX: is this a proper default?       */
1195   unsigned char op = get_opcode (insn);
1196
1197   if (type == R_HPPA_NONE)
1198     fmt = 0;
1199   else
1200     {
1201       switch (op)
1202         {
1203         case ADDI:
1204         case ADDIT:
1205         case SUBI:
1206           fmt = 11;
1207           break;
1208         case MOVB:
1209         case MOVIB:
1210         case COMBT:
1211         case COMBF:
1212         case COMIBT:
1213         case COMIBF:
1214         case ADDBT:
1215         case ADDBF:
1216         case ADDIBT:
1217         case ADDIBF:
1218         case BVB:
1219         case BB:
1220           fmt = 12;
1221           break;
1222         case LDO:
1223         case LDB:
1224         case LDH:
1225         case LDW:
1226         case LDWM:
1227         case STB:
1228         case STH:
1229         case STW:
1230         case STWM:
1231           fmt = 14;
1232           break;
1233         case BL:
1234         case BE:
1235         case BLE:
1236           fmt = 17;
1237           break;
1238         case LDIL:
1239         case ADDIL:
1240           fmt = 21;
1241           break;
1242         default:
1243           fmt = 32;
1244           break;
1245         }
1246
1247     }
1248   return fmt;
1249 }
1250
1251 /* this function is in charge of performing all the HP PA relocations */
1252 static long global_value = 0;
1253 static long GOT_value = 0;      /* XXX:  need to calculate this! For HPUX, GOT == DP */
1254 static asymbol *global_symbol = (asymbol *) NULL;
1255
1256 static bfd_reloc_status_type
1257 DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
1258        bfd * abfd AND
1259        arelent * reloc_entry AND
1260        asymbol * symbol_in AND
1261        PTR data AND
1262        asection * input_section AND
1263        bfd * output_bfd)
1264 {
1265   unsigned long insn;
1266   long sym_value = 0;
1267
1268   unsigned long addr = reloc_entry->address;    /*+ input_section->vma*/
1269   bfd_byte *hit_data = addr + (bfd_byte *) (data);
1270   unsigned short r_type = reloc_entry->howto->type & 0xFF;
1271   unsigned short r_field = e_fsel;
1272   boolean r_pcrel = reloc_entry->howto->pc_relative;
1273
1274   /* howto->bitsize contains the format (11, 14, 21, etc) information */
1275   unsigned r_format = reloc_entry->howto->bitsize;
1276   long r_addend = reloc_entry->addend;
1277
1278
1279   if (output_bfd)
1280     {
1281       /* Partial linking - do nothing */
1282       reloc_entry->address += input_section->output_offset;
1283       return bfd_reloc_ok;
1284     }
1285
1286   if (symbol_in && symbol_in->section == &bfd_und_section)
1287     return bfd_reloc_undefined;
1288
1289   /* Check for stubs that might be required.  */
1290   /* symbol_in = hppa_elf_stub_check (abfd, input_section->output_section->owner, reloc_entry); */
1291
1292   sym_value = get_symbol_value (symbol_in);
1293
1294   /* compute value of $global$ if it is there. */
1295
1296   if (global_symbol == (asymbol *) NULL)
1297     {
1298       struct elf_backend_data *bed
1299       = (struct elf_backend_data *) abfd->xvec->backend_data;
1300
1301       if (bed && bed->global_sym)
1302         {
1303           asymbol *gsym = &bed->global_sym->symbol;
1304           global_value
1305             = gsym->value
1306             + gsym->section->output_section->vma
1307             + gsym->section->output_offset;
1308           GOT_value = global_value;     /* XXX: For HP-UX, GOT==DP */
1309           global_symbol = gsym;
1310         }
1311     }
1312
1313   /* get the instruction word */
1314   insn = bfd_get_32 (abfd, hit_data);
1315
1316   /* relocate the value based on the relocation type */
1317
1318   /* basic_type_1:      relocation is relative to $global$              */
1319   /* basic_type_2:      relocation is relative to the current GOT       */
1320   /* basic_type_3:      relocation is an absolute call                  */
1321   /* basic_type_4:      relocation is an PC-relative call               */
1322   /* basic_type_5:      relocation is plabel reference                  */
1323   /* basic_type_6:      relocation is an unwind table relocation        */
1324   /* extended_type:     unimplemented                                   */
1325
1326   switch (r_type)
1327     {
1328     case R_HPPA_NONE:
1329       break;
1330     case R_HPPA_32:             /*              Symbol + Addend         32      */
1331       r_field = e_fsel;
1332       goto do_basic_type_1;
1333     case R_HPPA_11:             /*              Symbol + Addend         11      */
1334       r_field = e_fsel;
1335       goto do_basic_type_1;
1336     case R_HPPA_14:             /*              Symbol + Addend         14      */
1337       r_field = e_fsel;
1338       goto do_basic_type_1;
1339     case R_HPPA_17:             /*              Symbol + Addend         17      */
1340       r_field = e_fsel;
1341       goto do_basic_type_1;
1342     case R_HPPA_L21:            /*              L (Symbol, Addend)      21      */
1343       r_field = e_lsel;
1344       goto do_basic_type_1;
1345     case R_HPPA_R11:            /*              R (Symbol, Addend)      11      */
1346       r_field = e_rsel;
1347       goto do_basic_type_1;
1348     case R_HPPA_R14:            /*              R (Symbol, Addend)      14      */
1349       r_field = e_rsel;
1350       goto do_basic_type_1;
1351     case R_HPPA_R17:            /*              R (Symbol, Addend)      17      */
1352       r_field = e_rsel;
1353       goto do_basic_type_1;
1354     case R_HPPA_LS21:           /*              LS(Symbol, Addend)      21      */
1355       r_field = e_lssel;
1356       goto do_basic_type_1;
1357     case R_HPPA_RS11:           /*              RS(Symbol, Addend)      11      */
1358       r_field = e_rssel;
1359       goto do_basic_type_1;
1360     case R_HPPA_RS14:           /*              RS(Symbol, Addend)      14      */
1361       r_field = e_rssel;
1362       goto do_basic_type_1;
1363     case R_HPPA_RS17:           /*              RS(Symbol, Addend)      17      */
1364       r_field = e_ldsel;
1365       goto do_basic_type_1;
1366     case R_HPPA_LD21:           /*              LD(Symbol, Addend)      21      */
1367       r_field = e_ldsel;
1368       goto do_basic_type_1;
1369     case R_HPPA_RD11:           /*              RD(Symbol, Addend)      11      */
1370       r_field = e_rdsel;
1371       goto do_basic_type_1;
1372     case R_HPPA_RD14:           /*              RD(Symbol, Addend)      14      */
1373       r_field = e_rdsel;
1374       goto do_basic_type_1;
1375     case R_HPPA_RD17:           /*              RD(Symbol, Addend)      17      */
1376       r_field = e_rdsel;
1377       goto do_basic_type_1;
1378     case R_HPPA_LR21:           /*              LR(Symbol, Addend)      21      */
1379       r_field = e_lrsel;
1380       goto do_basic_type_1;
1381     case R_HPPA_RR14:           /*              RR(Symbol, Addend)      14      */
1382       r_field = e_rrsel;
1383       goto do_basic_type_1;
1384     case R_HPPA_RR17:           /*              RR(Symbol, Addend)      17      */
1385       r_field = e_rrsel;
1386
1387     do_basic_type_1:
1388       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1389                                      symbol_in, sym_value, r_addend,
1390                                      r_type, r_format, r_field, r_pcrel);
1391       break;
1392
1393     case R_HPPA_GOTOFF_11:      /*      Symbol - GOT + Addend   11      */
1394       r_field = e_fsel;
1395       goto do_basic_type_2;
1396     case R_HPPA_GOTOFF_14:      /*      Symbol - GOT + Addend   14      */
1397       r_field = e_fsel;
1398       goto do_basic_type_2;
1399     case R_HPPA_GOTOFF_L21:     /*      L (Sym - GOT, Addend)   21      */
1400       r_field = e_lsel;
1401       goto do_basic_type_2;
1402     case R_HPPA_GOTOFF_R11:     /*      R (Sym - GOT, Addend)   11      */
1403       r_field = e_rsel;
1404       goto do_basic_type_2;
1405     case R_HPPA_GOTOFF_R14:     /*      R (Sym - GOT, Addend)   14      */
1406       r_field = e_rsel;
1407       goto do_basic_type_2;
1408     case R_HPPA_GOTOFF_LS21:    /*      LS(Sym - GOT, Addend)   21      */
1409       r_field = e_lssel;
1410       goto do_basic_type_2;
1411     case R_HPPA_GOTOFF_RS11:    /*      RS(Sym - GOT, Addend)   11      */
1412       r_field = e_rssel;
1413       goto do_basic_type_2;
1414     case R_HPPA_GOTOFF_RS14:    /*      RS(Sym - GOT, Addend)   14      */
1415       r_field = e_rssel;
1416       goto do_basic_type_2;
1417     case R_HPPA_GOTOFF_LD21:    /*      LD(Sym - GOT, Addend)   21      */
1418       r_field = e_ldsel;
1419       goto do_basic_type_2;
1420     case R_HPPA_GOTOFF_RD11:    /*      RD(Sym - GOT, Addend)   11      */
1421       r_field = e_rdsel;
1422       goto do_basic_type_2;
1423     case R_HPPA_GOTOFF_RD14:    /*      RD(Sym - GOT, Addend)   14      */
1424       r_field = e_rdsel;
1425       goto do_basic_type_2;
1426     case R_HPPA_GOTOFF_LR21:    /*      LR(Sym - GOT, Addend)   21      */
1427       r_field = e_lrsel;
1428       goto do_basic_type_2;
1429     case R_HPPA_GOTOFF_RR14:    /*      RR(Sym - GOT, Addend)   14      */
1430       r_field = e_rrsel;
1431     do_basic_type_2:
1432       sym_value -= GOT_value;
1433       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1434                                      symbol_in, sym_value, r_addend,
1435                                      r_type, r_format, r_field, r_pcrel);
1436       break;
1437
1438     case R_HPPA_ABS_CALL_11:    /*      Symbol + Addend         11      */
1439       r_field = e_fsel;
1440       goto do_basic_type_3;
1441     case R_HPPA_ABS_CALL_14:    /*      Symbol + Addend         14      */
1442       r_field = e_fsel;
1443       goto do_basic_type_3;
1444     case R_HPPA_ABS_CALL_17:    /*      Symbol + Addend         17      */
1445       r_field = e_fsel;
1446       goto do_basic_type_3;
1447     case R_HPPA_ABS_CALL_L21:   /*      L (Symbol, Addend)      21      */
1448       r_field = e_lsel;
1449       goto do_basic_type_3;
1450     case R_HPPA_ABS_CALL_R11:   /*      R (Symbol, Addend)      11      */
1451       r_field = e_rsel;
1452       goto do_basic_type_3;
1453     case R_HPPA_ABS_CALL_R14:   /*      R (Symbol, Addend)      14      */
1454       r_field = e_rsel;
1455       goto do_basic_type_3;
1456     case R_HPPA_ABS_CALL_R17:   /*      R (Symbol, Addend)      17      */
1457       r_field = e_rsel;
1458       goto do_basic_type_3;
1459     case R_HPPA_ABS_CALL_LS21:  /*      LS(Symbol, Addend)      21      */
1460       r_field = e_lssel;
1461       goto do_basic_type_3;
1462     case R_HPPA_ABS_CALL_RS11:  /*      RS(Symbol, Addend)      11      */
1463       r_field = e_lssel;
1464       goto do_basic_type_3;
1465     case R_HPPA_ABS_CALL_RS14:  /*      RS(Symbol, Addend)      14      */
1466       r_field = e_rssel;
1467       goto do_basic_type_3;
1468     case R_HPPA_ABS_CALL_RS17:  /*      RS(Symbol, Addend)      17      */
1469       r_field = e_rssel;
1470       goto do_basic_type_3;
1471     case R_HPPA_ABS_CALL_LD21:  /*      LD(Symbol, Addend)      21      */
1472       r_field = e_ldsel;
1473       goto do_basic_type_3;
1474     case R_HPPA_ABS_CALL_RD11:  /*      RD(Symbol, Addend)      11      */
1475       r_field = e_rdsel;
1476       goto do_basic_type_3;
1477     case R_HPPA_ABS_CALL_RD14:  /*      RD(Symbol, Addend)      14      */
1478       r_field = e_rdsel;
1479       goto do_basic_type_3;
1480     case R_HPPA_ABS_CALL_RD17:  /*      RD(Symbol, Addend)      17      */
1481       r_field = e_rdsel;
1482       goto do_basic_type_3;
1483     case R_HPPA_ABS_CALL_LR21:  /*      LR(Symbol, Addend)      21      */
1484       r_field = e_lrsel;
1485       goto do_basic_type_3;
1486     case R_HPPA_ABS_CALL_RR14:  /*      RR(Symbol, Addend)      14      */
1487       r_field = e_rrsel;
1488       goto do_basic_type_3;
1489     case R_HPPA_ABS_CALL_RR17:  /*      RR(Symbol, Addend)      17      */
1490       r_field = e_rrsel;
1491     do_basic_type_3:
1492       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1493                                      symbol_in, sym_value, r_addend,
1494                                      r_type, r_format, r_field, r_pcrel);
1495       break;
1496
1497     case R_HPPA_PCREL_CALL_11:  /*      Symbol - PC + Addend    11      */
1498       r_field = e_fsel;
1499       goto do_basic_type_4;
1500     case R_HPPA_PCREL_CALL_14:  /*      Symbol - PC + Addend    14      */
1501       r_field = e_fsel;
1502       goto do_basic_type_4;
1503     case R_HPPA_PCREL_CALL_17:  /*      Symbol - PC + Addend    17      */
1504       r_field = e_fsel;
1505       goto do_basic_type_4;
1506     case R_HPPA_PCREL_CALL_L21:/*       L (Symbol - PC, Addend) 21      */
1507       r_field = e_lsel;
1508       goto do_basic_type_4;
1509     case R_HPPA_PCREL_CALL_R11:/*       R (Symbol - PC, Addend) 11      */
1510       r_field = e_rsel;
1511       goto do_basic_type_4;
1512     case R_HPPA_PCREL_CALL_R14:/*       R (Symbol - PC, Addend) 14      */
1513       r_field = e_rsel;
1514       goto do_basic_type_4;
1515     case R_HPPA_PCREL_CALL_R17:/*       R (Symbol - PC, Addend) 17      */
1516       r_field = e_rsel;
1517       goto do_basic_type_4;
1518     case R_HPPA_PCREL_CALL_LS21:        /*      LS(Symbol - PC, Addend) 21      */
1519       r_field = e_lssel;
1520       goto do_basic_type_4;
1521     case R_HPPA_PCREL_CALL_RS11:        /*      RS(Symbol - PC, Addend) 11      */
1522       r_field = e_rssel;
1523       goto do_basic_type_4;
1524     case R_HPPA_PCREL_CALL_RS14:        /*      RS(Symbol - PC, Addend) 14      */
1525       r_field = e_rssel;
1526       goto do_basic_type_4;
1527     case R_HPPA_PCREL_CALL_RS17:        /*      RS(Symbol - PC, Addend) 17      */
1528       r_field = e_rssel;
1529       goto do_basic_type_4;
1530     case R_HPPA_PCREL_CALL_LD21:        /*      LD(Symbol - PC, Addend) 21      */
1531       r_field = e_ldsel;
1532       goto do_basic_type_4;
1533     case R_HPPA_PCREL_CALL_RD11:        /*      RD(Symbol - PC, Addend) 11      */
1534       r_field = e_rdsel;
1535       goto do_basic_type_4;
1536     case R_HPPA_PCREL_CALL_RD14:        /*      RD(Symbol - PC, Addend) 14      */
1537       r_field = e_rdsel;
1538       goto do_basic_type_4;
1539     case R_HPPA_PCREL_CALL_RD17:        /*      RD(Symbol - PC, Addend) 17      */
1540       r_field = e_rdsel;
1541       goto do_basic_type_4;
1542     case R_HPPA_PCREL_CALL_LR21:        /*      LR(Symbol - PC, Addend) 21      */
1543       r_field = e_lrsel;
1544       goto do_basic_type_4;
1545     case R_HPPA_PCREL_CALL_RR14:        /*      RR(Symbol - PC, Addend) 14      */
1546       r_field = e_rrsel;
1547       goto do_basic_type_4;
1548     case R_HPPA_PCREL_CALL_RR17:        /*      RR(Symbol - PC, Addend) 17      *//* #69 */
1549       r_field = e_rrsel;
1550     do_basic_type_4:
1551       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1552                                      symbol_in, sym_value, r_addend,
1553                                      r_type, r_format, r_field, r_pcrel);
1554       break;
1555
1556     case R_HPPA_PLABEL_32:
1557     case R_HPPA_PLABEL_11:
1558     case R_HPPA_PLABEL_14:
1559       r_field = e_fsel;
1560       goto do_basic_type_5;
1561     case R_HPPA_PLABEL_L21:
1562       r_field = e_lsel;
1563       goto do_basic_type_5;
1564     case R_HPPA_PLABEL_R11:
1565     case R_HPPA_PLABEL_R14:
1566       r_field = e_rsel;
1567     do_basic_type_5:
1568       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1569                                      symbol_in, sym_value, r_addend,
1570                                      r_type, r_format, r_field, r_pcrel);
1571       break;
1572
1573     case R_HPPA_UNWIND_ENTRY:
1574     case R_HPPA_UNWIND_ENTRIES:
1575       hppa_elf_relocate_unwind_table (abfd, input_section, data, addr,
1576                                       symbol_in, sym_value, r_addend,
1577                                       r_type, r_format, r_field, r_pcrel);
1578       return (bfd_reloc_ok);
1579
1580     case R_HPPA_PUSH_CONST:     /*      push Addend                     -   -   */
1581     case R_HPPA_PUSH_PC:        /*      push PC + Addend                -   -   */
1582     case R_HPPA_PUSH_SYM:       /*      push Symbol + Addend            -   -   */
1583     case R_HPPA_PUSH_GOTOFF:    /*      push Symbol - GOT + Addend      -   -   */
1584     case R_HPPA_PUSH_ABS_CALL:  /*      push Symbol + Addend            -   -   */
1585     case R_HPPA_PUSH_PCREL_CALL:        /*      push Symbol - PC + Addend       -   -   */
1586     case R_HPPA_PUSH_PLABEL:    /*      [TBD]                           -   -   */
1587     case R_HPPA_MAX:            /*      pop A and B, push max(B,A)      -   -   */
1588     case R_HPPA_MIN:            /*      pop A and B, push min(B,A)      -   -   */
1589     case R_HPPA_ADD:            /*      pop A and B, push B + A         -   -   */
1590     case R_HPPA_SUB:            /*      pop A and B, push B - A         -   -   */
1591     case R_HPPA_MULT:           /*      pop A and B, push B * A         -   -   */
1592     case R_HPPA_DIV:            /*      pop A and B, push B / A         -   -   */
1593     case R_HPPA_MOD:            /*      pop A and B, push B % A         -   -   */
1594     case R_HPPA_AND:            /*      pop A and B, push B & A         -   -   */
1595     case R_HPPA_OR:             /*      pop A and B, push B | A         -   -   */
1596     case R_HPPA_XOR:            /*      pop A and B, push B ^ A         -   -   */
1597     case R_HPPA_NOT:            /*      pop A, push ~A                  -   -   */
1598     case R_HPPA_LSHIFT: /*      pop A, push A << Addend         -   -   */
1599     case R_HPPA_ARITH_RSHIFT:   /*      pop A, push A >> Addend         -   -   */
1600     case R_HPPA_LOGIC_RSHIFT:   /*      pop A, push A >> Addend         -   -   */
1601     case R_HPPA_EXPR_F: /*      pop A, push A + Addend          L   -   */
1602     case R_HPPA_EXPR_L: /*      pop A, push L(A,Addend)         L   -   */
1603     case R_HPPA_EXPR_R: /*      pop A, push R(A,Addend)         R   -   */
1604     case R_HPPA_EXPR_LS:        /*      pop A, push LS(A,Addend)        LS  -   */
1605     case R_HPPA_EXPR_RS:        /*      pop A, push RS(A,Addend)        RS  -   */
1606     case R_HPPA_EXPR_LD:        /*      pop A, push LD(A,Addend)        LD  -   */
1607     case R_HPPA_EXPR_RD:        /*      pop A, push RD(A,Addend)        RD  -   */
1608     case R_HPPA_EXPR_LR:        /*      pop A, push LR(A,Addend)        LR  -   */
1609     case R_HPPA_EXPR_RR:        /*      pop A, push RR(A,Addend)        RR  -   */
1610
1611     case R_HPPA_EXPR_32:        /*      pop                             -   32  */
1612     case R_HPPA_EXPR_21:        /*      pop                             -   21  */
1613     case R_HPPA_EXPR_11:        /*      pop                             -   11  */
1614     case R_HPPA_EXPR_14:        /*      pop                             -   14  */
1615     case R_HPPA_EXPR_17:        /*      pop                             -   17  */
1616     case R_HPPA_EXPR_12:        /*      pop                             -   12  */
1617       fprintf (stderr, "Relocation problem: ");
1618       fprintf (stderr, "Unimplemented reloc type %d, in module %s\n",
1619                r_type, abfd->filename);
1620       return (bfd_reloc_notsupported);
1621     default:
1622       fprintf (stderr, "Relocation problem : ");
1623       fprintf (stderr, "Unrecognized reloc type %d, in module %s\n",
1624                r_type, abfd->filename);
1625       return (bfd_reloc_dangerous);
1626     }
1627
1628   /* update the instruction word */
1629   bfd_put_32 (abfd, insn, hit_data);
1630
1631   return (bfd_reloc_ok);
1632
1633 }
1634
1635 struct elf_reloc_map
1636   {
1637     unsigned char bfd_reloc_val;
1638     unsigned char elf_reloc_val;
1639   };
1640
1641 static CONST struct elf_reloc_map elf_hppa_reloc_map[] =
1642 {
1643   {BFD_RELOC_NONE, R_HPPA_NONE,},
1644   {BFD_RELOC_HPPA_32, R_HPPA_32,},
1645   {BFD_RELOC_HPPA_11, R_HPPA_11,},
1646   {BFD_RELOC_HPPA_14, R_HPPA_14,},
1647   {BFD_RELOC_HPPA_17, R_HPPA_17,},
1648   {BFD_RELOC_HPPA_L21, R_HPPA_L21,},
1649   {BFD_RELOC_HPPA_R11, R_HPPA_R11,},
1650   {BFD_RELOC_HPPA_R14, R_HPPA_R14,},
1651   {BFD_RELOC_HPPA_R17, R_HPPA_R17,},
1652   {BFD_RELOC_HPPA_LS21, R_HPPA_LS21,},
1653   {BFD_RELOC_HPPA_RS11, R_HPPA_RS11,},
1654   {BFD_RELOC_HPPA_RS14, R_HPPA_RS14,},
1655   {BFD_RELOC_HPPA_RS17, R_HPPA_RS17,},
1656   {BFD_RELOC_HPPA_LD21, R_HPPA_LD21,},
1657   {BFD_RELOC_HPPA_RD11, R_HPPA_RD11,},
1658   {BFD_RELOC_HPPA_RD14, R_HPPA_RD14,},
1659   {BFD_RELOC_HPPA_RD17, R_HPPA_RD17,},
1660   {BFD_RELOC_HPPA_LR21, R_HPPA_LR21,},
1661   {BFD_RELOC_HPPA_RR14, R_HPPA_RR14,},
1662   {BFD_RELOC_HPPA_RR17, R_HPPA_RR17,},
1663   {BFD_RELOC_HPPA_GOTOFF_11, R_HPPA_GOTOFF_11,},
1664   {BFD_RELOC_HPPA_GOTOFF_14, R_HPPA_GOTOFF_14,},
1665   {BFD_RELOC_HPPA_GOTOFF_L21, R_HPPA_GOTOFF_L21,},
1666   {BFD_RELOC_HPPA_GOTOFF_R11, R_HPPA_GOTOFF_R11,},
1667   {BFD_RELOC_HPPA_GOTOFF_R14, R_HPPA_GOTOFF_R14,},
1668   {BFD_RELOC_HPPA_GOTOFF_LS21, R_HPPA_GOTOFF_LS21,},
1669   {BFD_RELOC_HPPA_GOTOFF_RS11, R_HPPA_GOTOFF_RS11,},
1670   {BFD_RELOC_HPPA_GOTOFF_RS14, R_HPPA_GOTOFF_RS14,},
1671   {BFD_RELOC_HPPA_GOTOFF_LD21, R_HPPA_GOTOFF_LD21,},
1672   {BFD_RELOC_HPPA_GOTOFF_RD11, R_HPPA_GOTOFF_RD11,},
1673   {BFD_RELOC_HPPA_GOTOFF_RD14, R_HPPA_GOTOFF_RD14,},
1674   {BFD_RELOC_HPPA_GOTOFF_LR21, R_HPPA_GOTOFF_LR21,},
1675   {BFD_RELOC_HPPA_GOTOFF_RR14, R_HPPA_GOTOFF_RR14,},
1676   {BFD_RELOC_HPPA_ABS_CALL_11, R_HPPA_ABS_CALL_11,},
1677   {BFD_RELOC_HPPA_ABS_CALL_14, R_HPPA_ABS_CALL_14,},
1678   {BFD_RELOC_HPPA_ABS_CALL_17, R_HPPA_ABS_CALL_17,},
1679   {BFD_RELOC_HPPA_ABS_CALL_L21, R_HPPA_ABS_CALL_L21,},
1680   {BFD_RELOC_HPPA_ABS_CALL_R11, R_HPPA_ABS_CALL_R11,},
1681   {BFD_RELOC_HPPA_ABS_CALL_R14, R_HPPA_ABS_CALL_R14,},
1682   {BFD_RELOC_HPPA_ABS_CALL_R17, R_HPPA_ABS_CALL_R17,},
1683   {BFD_RELOC_HPPA_ABS_CALL_LS21, R_HPPA_ABS_CALL_LS21,},
1684   {BFD_RELOC_HPPA_ABS_CALL_RS11, R_HPPA_ABS_CALL_RS11,},
1685   {BFD_RELOC_HPPA_ABS_CALL_RS14, R_HPPA_ABS_CALL_RS14,},
1686   {BFD_RELOC_HPPA_ABS_CALL_RS17, R_HPPA_ABS_CALL_RS17,},
1687   {BFD_RELOC_HPPA_ABS_CALL_LD21, R_HPPA_ABS_CALL_LD21,},
1688   {BFD_RELOC_HPPA_ABS_CALL_RD11, R_HPPA_ABS_CALL_RD11,},
1689   {BFD_RELOC_HPPA_ABS_CALL_RD14, R_HPPA_ABS_CALL_RD14,},
1690   {BFD_RELOC_HPPA_ABS_CALL_RD17, R_HPPA_ABS_CALL_RD17,},
1691   {BFD_RELOC_HPPA_ABS_CALL_LR21, R_HPPA_ABS_CALL_LR21,},
1692   {BFD_RELOC_HPPA_ABS_CALL_RR14, R_HPPA_ABS_CALL_RR14,},
1693   {BFD_RELOC_HPPA_ABS_CALL_RR17, R_HPPA_ABS_CALL_RR17,},
1694   {BFD_RELOC_HPPA_PCREL_CALL_11, R_HPPA_PCREL_CALL_11,},
1695   {BFD_RELOC_HPPA_PCREL_CALL_14, R_HPPA_PCREL_CALL_14,},
1696   {BFD_RELOC_HPPA_PCREL_CALL_17, R_HPPA_PCREL_CALL_17,},
1697   {BFD_RELOC_HPPA_PCREL_CALL_12, R_HPPA_PCREL_CALL_12,},
1698   {BFD_RELOC_HPPA_PCREL_CALL_L21, R_HPPA_PCREL_CALL_L21,},
1699   {BFD_RELOC_HPPA_PCREL_CALL_R11, R_HPPA_PCREL_CALL_R11,},
1700   {BFD_RELOC_HPPA_PCREL_CALL_R14, R_HPPA_PCREL_CALL_R14,},
1701   {BFD_RELOC_HPPA_PCREL_CALL_R17, R_HPPA_PCREL_CALL_R17,},
1702   {BFD_RELOC_HPPA_PCREL_CALL_LS21, R_HPPA_PCREL_CALL_LS21,},
1703   {BFD_RELOC_HPPA_PCREL_CALL_RS11, R_HPPA_PCREL_CALL_RS11,},
1704   {BFD_RELOC_HPPA_PCREL_CALL_RS14, R_HPPA_PCREL_CALL_RS14,},
1705   {BFD_RELOC_HPPA_PCREL_CALL_RS17, R_HPPA_PCREL_CALL_RS17,},
1706   {BFD_RELOC_HPPA_PCREL_CALL_LD21, R_HPPA_PCREL_CALL_LD21,},
1707   {BFD_RELOC_HPPA_PCREL_CALL_RD11, R_HPPA_PCREL_CALL_RD11,},
1708   {BFD_RELOC_HPPA_PCREL_CALL_RD14, R_HPPA_PCREL_CALL_RD14,},
1709   {BFD_RELOC_HPPA_PCREL_CALL_RD17, R_HPPA_PCREL_CALL_RD17,},
1710   {BFD_RELOC_HPPA_PCREL_CALL_LR21, R_HPPA_PCREL_CALL_LR21,},
1711   {BFD_RELOC_HPPA_PCREL_CALL_RR14, R_HPPA_PCREL_CALL_RR14,},
1712   {BFD_RELOC_HPPA_PCREL_CALL_RR17, R_HPPA_PCREL_CALL_RR17,},
1713   {BFD_RELOC_HPPA_PLABEL_32, R_HPPA_PLABEL_32,},
1714   {BFD_RELOC_HPPA_PLABEL_11, R_HPPA_PLABEL_11,},
1715   {BFD_RELOC_HPPA_PLABEL_14, R_HPPA_PLABEL_14,},
1716   {BFD_RELOC_HPPA_PLABEL_L21, R_HPPA_PLABEL_L21,},
1717   {BFD_RELOC_HPPA_PLABEL_R11, R_HPPA_PLABEL_R11,},
1718   {BFD_RELOC_HPPA_PLABEL_R14, R_HPPA_PLABEL_R14,},
1719   {BFD_RELOC_HPPA_DLT_32, R_HPPA_DLT_32,},
1720   {BFD_RELOC_HPPA_DLT_11, R_HPPA_DLT_11,},
1721   {BFD_RELOC_HPPA_DLT_14, R_HPPA_DLT_14,},
1722   {BFD_RELOC_HPPA_DLT_L21, R_HPPA_DLT_L21,},
1723   {BFD_RELOC_HPPA_DLT_R11, R_HPPA_DLT_R11,},
1724   {BFD_RELOC_HPPA_DLT_R14, R_HPPA_DLT_R14,},
1725   {BFD_RELOC_HPPA_UNWIND_ENTRY, R_HPPA_UNWIND_ENTRY,},
1726   {BFD_RELOC_HPPA_UNWIND_ENTRIES, R_HPPA_UNWIND_ENTRIES,},
1727 };
1728
1729 static reloc_howto_type *
1730 elf_hppa_reloc_type_lookup (arch, code)
1731      bfd_arch_info_type *arch;
1732      bfd_reloc_code_real_type code;
1733 {
1734   int i;
1735
1736   if ((int) code < (int) R_HPPA_UNIMPLEMENTED)
1737     {
1738       BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
1739       return &elf_hppa_howto_table[(int) code];
1740     }
1741
1742   return (reloc_howto_type *) 0;
1743 }
1744
1745 #define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
1746
1747
1748 void
1749 DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx),
1750        bfd * abfd AND
1751        elf32_symbol_type * symbolP AND
1752        int sym_idx)
1753 {
1754   symext_chainS *symextP;
1755   unsigned int arg_reloc;
1756
1757   if (!(symbolP->symbol.flags & BSF_FUNCTION))
1758     return;
1759
1760   if (!((symbolP->symbol.flags & BSF_EXPORT) ||
1761         (symbolP->symbol.flags & BSF_GLOBAL)))
1762     return;
1763
1764   arg_reloc = symbolP->tc_data.hppa_arg_reloc;
1765
1766   symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
1767
1768   symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
1769   symextP[0].next = &symextP[1];
1770
1771   symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
1772   symextP[1].next = NULL;
1773
1774   if (symext_rootP == NULL)
1775     {
1776       symext_rootP = &symextP[0];
1777       symext_lastP = &symextP[1];
1778     }
1779   else
1780     {
1781       symext_lastP->next = &symextP[0];
1782       symext_lastP = &symextP[1];
1783     }
1784 }
1785
1786 static symext_entryS *symextn_contents = NULL;
1787 static unsigned int symextn_contents_real_size = 0;
1788
1789 void
1790 DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
1791        bfd * abfd AND
1792        PTR ignored)
1793 {
1794   symext_chainS *symextP;
1795   symext_entryS *outbound_symexts;
1796   int size;
1797   int n;
1798   int i;
1799   extern char *stub_section_contents;   /* forward declaration */
1800   void hppa_elf_stub_finish (); /* forward declaration */
1801   asection *symextn_sec;
1802
1803   hppa_elf_stub_finish (abfd);
1804
1805   if (symext_rootP == NULL)
1806     return;
1807
1808   for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
1809     ;
1810
1811   size = sizeof (symext_entryS) * n;
1812   symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
1813   if (symextn_sec == (asection *) 0)
1814     {
1815       symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
1816       bfd_set_section_flags (abfd,
1817                              symextn_sec,
1818          SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE | SEC_READONLY);
1819       symextn_sec->output_section = symextn_sec;
1820       symextn_sec->output_offset = 0;
1821       bfd_set_section_alignment (abfd, symextn_sec, 2);
1822     }
1823   symextn_contents = (symext_entryS *) bfd_alloc (abfd, size);
1824
1825   for (i = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++i)
1826     symextn_contents[i] = symextP->entry;
1827   symextn_contents_real_size = size;
1828   bfd_set_section_size (abfd, symextn_sec, symextn_contents_real_size);
1829
1830   return;
1831 }
1832
1833 /* Support for HP PA-RISC stub generation.
1834
1835    Written by
1836
1837         Center for Software Science
1838         Department of Computer Science
1839         University of Utah
1840
1841     */
1842
1843 /*
1844     HP-PA calling conventions state:
1845
1846     1. an argument relocation stub is required whenever the callee and
1847     caller argument relocation bits do not match exactly.  The exception
1848     to this rule is if either the caller or callee argument relocation
1849     bit are 00 (do not relocate).
1850
1851     2. The linker can optionally add a symbol record for the stub so that
1852     the stub can be reused.  The symbol record will be the same as the
1853     original export symbol record, except that the relocation bits will
1854     reflect the input of the stub, the type would be STUB and the symbol
1855     value will be the location of the relocation stub.
1856
1857     Other notes:
1858
1859     Stubs can be inserted *before* the section of the caller.  The stubs
1860     can be treated as calls to code that manipulates the arguments.
1861
1862  */
1863
1864 typedef enum
1865   {
1866     HPPA_STUB_ILLEGAL,
1867     HPPA_STUB_ARG_RELOC,
1868     HPPA_STUB_LONG_BRANCH
1869   } hppa_stub_type;
1870
1871 symext_entryS
1872 elf32_hppa_get_sym_extn (abfd, sym, type)
1873      bfd *abfd;
1874      asymbol *sym;
1875      int type;
1876 {
1877   /* This function finds the symbol extension record of the */
1878   /* specified type for the specified symbol.  It returns the */
1879   /* value of the symbol extension record.      */
1880   symext_entryS retval;
1881
1882   switch (type)
1883     {
1884     case HPPA_SXT_NULL:
1885       retval = (symext_entryS) 0;
1886       break;
1887     case HPPA_SXT_SYMNDX:
1888       retval = (symext_entryS) 0;       /* XXX: need to fix this */
1889       break;
1890     case HPPA_SXT_ARG_RELOC:
1891       {
1892         elf32_symbol_type *esymP = (elf32_symbol_type *) sym;
1893
1894         retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
1895         break;
1896       }
1897     }
1898   return retval;
1899 }
1900
1901
1902 typedef struct Elf32_hppa_Stub_description_struct
1903   {
1904     bfd *this_bfd;              /* bfd to which this stub */
1905     /* applies */
1906     asection *stub_sec;         /* stub section for this bfd */
1907     unsigned relocs_allocated_cnt;      /* count of relocations for this stub section */
1908     unsigned real_size;
1909     unsigned allocated_size;
1910     int *stub_secp;             /* pointer to the next available location in the buffer */
1911     char *stub_contents;        /* contents of the stubs for this bfd */
1912   }
1913
1914 Elf32_hppa_Stub_description;
1915
1916 typedef struct Elf32_hppa_Stub_list_struct
1917   {
1918     Elf32_hppa_Stub_description *stub;
1919     struct Elf32_hppa_Stub_list_struct *next;
1920   } Elf32_hppa_Stub_list;
1921
1922 static Elf32_hppa_Stub_list *elf_hppa_stub_rootP = NULL;
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_list *stubP;
1931
1932   for (stubP = elf_hppa_stub_rootP; stubP; stubP = stubP->next)
1933     {
1934       if (stubP->stub->this_bfd == abfd
1935           && stubP->stub->stub_sec == stub_sec)
1936         return stubP->stub;
1937     }
1938
1939   return (Elf32_hppa_Stub_description *) NULL;
1940 }
1941
1942 static Elf32_hppa_Stub_description *
1943 new_stub (abfd, stub_sec)
1944      bfd *abfd;
1945      asection *stub_sec;
1946 {
1947   Elf32_hppa_Stub_description *stub = find_stubs (abfd, stub_sec);
1948
1949   if (stub)
1950     return stub;
1951
1952   stub = (Elf32_hppa_Stub_description *) bfd_zalloc (abfd, sizeof (Elf32_hppa_Stub_description));
1953   stub->this_bfd = abfd;
1954   stub->stub_sec = stub_sec;
1955   stub->real_size = 0;
1956   stub->allocated_size = 0;
1957   stub->stub_contents = NULL;
1958   stub->stub_secp = NULL;
1959
1960   return stub;
1961 }
1962
1963 static void
1964 add_stub (stub)
1965      Elf32_hppa_Stub_description *stub;
1966 {
1967   Elf32_hppa_Stub_list *new_entry;
1968
1969   new_entry = (Elf32_hppa_Stub_list *) bfd_zalloc (stub->this_bfd, sizeof (Elf32_hppa_Stub_list));
1970
1971   if (new_entry)
1972     {
1973       new_entry->stub = stub;
1974
1975       if (elf_hppa_stub_rootP)
1976         {
1977           new_entry->next = elf_hppa_stub_rootP;
1978           elf_hppa_stub_rootP = new_entry;
1979         }
1980       else
1981         {
1982           new_entry->next = (Elf32_hppa_Stub_list *) NULL;
1983           elf_hppa_stub_rootP = new_entry;
1984         }
1985     }
1986   else
1987     {
1988       bfd_error = no_memory;
1989       bfd_perror ("add_stub");
1990     }
1991 }
1992
1993 #define ARGUMENTS       0
1994 #define RETURN_VALUE    1
1995
1996 #define NO_ARG_RELOC    0
1997 #define R_TO_FR         1
1998 #define FR_TO_R         2
1999 #define ARG_RELOC_ERR   3
2000
2001 #define ARG0    0
2002 #define ARG1    1
2003 #define ARG2    2
2004 #define ARG3    3
2005 #define RETVAL  4
2006
2007 #define AR_NO   0
2008 #define AR_GR   1
2009 #define AR_FR   2
2010 #define AR_FU   3
2011
2012 static CONST char *CONST reloc_type_strings[] =
2013 {
2014   "NONE", "GR->FR", "FR->GR", "ERROR"
2015 };
2016
2017 static CONST char mismatches[4][4] =
2018 {                               /*      CALLEE NONE     CALLEE GR       CALLEE FR       CALLEE FU       */
2019   /* CALLER NONE        */
2020  {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC},
2021  /* CALLER GR   */
2022  {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR},
2023  /* CALLER FR   */
2024  {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
2025  /* CALLER FU   */
2026  {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
2027 };
2028
2029 static CONST char retval_mismatches[4][4] =
2030 {                               /*      CALLEE NONE     CALLEE GR       CALLEE FR       CALLEE FU       */
2031   /* CALLER NONE        */
2032  {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC},
2033  /* CALLER GR   */
2034  {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR},
2035  /* CALLER FR   */
2036  {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
2037  /* CALLER FU   */
2038  {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC},
2039 };
2040
2041 static int
2042 type_of_mismatch (caller_bits, callee_bits, type)
2043      int caller_bits;
2044      int callee_bits;
2045      int type;
2046 {
2047   switch (type)
2048     {
2049     case ARGUMENTS:
2050       return mismatches[caller_bits][callee_bits];
2051     case RETURN_VALUE:
2052       return retval_mismatches[caller_bits][callee_bits];
2053     }
2054
2055   return 0;
2056 }
2057
2058 #define EXTRACT_ARBITS(ar,which)        ((ar) >> (8-(which*2))) & 3
2059
2060 #include "hppa_stubs.h"
2061
2062 #define NEW_INSTRUCTION(desc,insn)      \
2063     *((desc)->stub_secp)++ = (insn);    \
2064     (desc)->real_size += sizeof(int);   \
2065     bfd_set_section_size((desc)->this_bfd,(desc)->stub_sec,(desc)->real_size);
2066
2067 void
2068 hppa_elf_stub_finish (output_bfd)
2069      bfd *output_bfd;
2070 {
2071   extern bfd_error_vector_type bfd_error_vector;
2072   Elf32_hppa_Stub_list *stub_list = elf_hppa_stub_rootP;
2073   /* All the stubs have been built.  Finish up building */
2074   /* stub section.  Apply relocations to the section.   */
2075
2076   for (; stub_list; stub_list = stub_list->next)
2077     {
2078       if (stub_list->stub->real_size)
2079         {
2080           bfd *stub_bfd = stub_list->stub->this_bfd;
2081           asection *stub_sec = bfd_get_section_by_name (stub_bfd, ".hppa_linker_stubs");
2082           bfd_size_type reloc_size;
2083           arelent **reloc_vector;
2084
2085           BFD_ASSERT (stub_sec == stub_list->stub->stub_sec);
2086           reloc_size = bfd_get_reloc_upper_bound (stub_bfd, stub_sec);
2087           reloc_vector = (arelent **) alloca (reloc_size);
2088
2089           BFD_ASSERT (stub_sec);
2090
2091           /* We are not relaxing the section, so just copy the size info */
2092           stub_sec->_cooked_size = stub_sec->_raw_size;
2093           stub_sec->reloc_done = true;
2094
2095
2096           if (bfd_canonicalize_reloc (stub_bfd,
2097                                       stub_sec,
2098                                       reloc_vector,
2099                                       output_bfd->outsymbols))
2100             {
2101               arelent **parent;
2102               for (parent = reloc_vector; *parent != (arelent *) NULL;
2103                    parent++)
2104                 {
2105                   bfd_reloc_status_type r =
2106                   bfd_perform_relocation (stub_bfd,
2107                                           *parent,
2108                                           stub_list->stub->stub_contents,
2109                                           stub_sec, 0);
2110
2111
2112                   if (r != bfd_reloc_ok)
2113                     {
2114                       switch (r)
2115                         {
2116                         case bfd_reloc_undefined:
2117                           bfd_error_vector.undefined_symbol (*parent, NULL);
2118                           break;
2119                         case bfd_reloc_dangerous:
2120                           bfd_error_vector.reloc_dangerous (*parent, NULL);
2121                           break;
2122                         case bfd_reloc_outofrange:
2123                         case bfd_reloc_overflow:
2124                           bfd_error_vector.reloc_value_truncated (*parent, NULL);
2125                           break;
2126                         default:
2127                           abort ();
2128                           break;
2129                         }
2130                     }
2131                 }
2132             }
2133
2134           bfd_set_section_contents (output_bfd,
2135                                     stub_sec,
2136                                     stub_list->stub->stub_contents,
2137                                     0,
2138                                     stub_list->stub->real_size);
2139
2140           free (reloc_vector);
2141         }
2142     }
2143 }
2144
2145 void
2146 hppa_elf_stub_branch_reloc (stub_desc,  /* the bfd */
2147                             output_bfd, /* the output bfd */
2148                             stub_sym,   /* the stub symbol */
2149                             offset)     /* the offset within the stub buffer (pre-calculated) */
2150      Elf32_hppa_Stub_description *stub_desc;
2151      bfd *output_bfd;
2152      asymbol *stub_sym;
2153      int offset;
2154 {
2155   /* Allocate a new relocation entry. */
2156   arelent relent;
2157   int size;
2158
2159   if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2160     {
2161       if (stub_desc->stub_sec->relocation == NULL)
2162         {
2163           stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2164           size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2165           stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
2166         }
2167       else
2168         {
2169           stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2170           size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2171           stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2172                                                                  size);
2173         }
2174     }
2175
2176   /* Fill in the details. */
2177   relent.address = offset;
2178   relent.addend = 0;
2179   relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2180   BFD_ASSERT (relent.sym_ptr_ptr);
2181
2182   relent.sym_ptr_ptr[0] = stub_sym;
2183   relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_ABS_CALL_17);
2184
2185   /* Save it in the array of relocations for the stub section. */
2186
2187   memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2188           &relent,
2189           sizeof (arelent));
2190 }
2191
2192 asymbol *
2193 hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
2194      bfd *abfd;
2195      bfd *output_bfd;
2196      arelent *reloc_entry;
2197      int stub_types[5];
2198 {
2199   asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
2200   Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, stub_sec);
2201   asymbol *stub_sym = NULL;
2202   asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2203   int i;
2204   char stub_sym_name[128];
2205
2206   if (!stub_sec)
2207     {
2208       BFD_ASSERT (stub_desc == NULL);
2209       stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2210       bfd_set_section_flags (output_bfd,
2211                              stub_sec,
2212                              SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_READONLY);
2213       stub_sec->output_section = output_text_section->output_section;
2214       stub_sec->output_offset = 0;
2215       bfd_set_section_alignment (output_bfd, stub_sec, 2);
2216       stub_desc = new_stub (abfd, stub_sec);
2217       add_stub (stub_desc);
2218     }
2219
2220   /* make sure we have a stub descriptor structure */
2221
2222   if (!stub_desc)
2223     {
2224       stub_desc = new_stub (abfd, stub_sec);
2225       add_stub (stub_desc);
2226     }
2227
2228   /* allocate some space to write the stub */
2229
2230   if (!stub_desc->stub_contents)
2231     {
2232       stub_desc->allocated_size = STUB_BUFFER_INCR;
2233       stub_desc->stub_contents = (char *) xmalloc (STUB_BUFFER_INCR);
2234     }
2235   else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2236     {
2237       stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2238       stub_desc->stub_contents = (char *) xrealloc (stub_desc->stub_contents,
2239                                                     stub_desc->allocated_size);
2240     }
2241
2242   stub_desc->stub_secp = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2243
2244   /* create a symbol to point to this stub */
2245   stub_sym = bfd_make_empty_symbol (abfd);
2246   sprintf (stub_sym_name,
2247            "_stub_%s_%02d_%02d_%02d_%02d_%02d\000",
2248            reloc_entry->sym_ptr_ptr[0]->name,
2249   stub_types[0], stub_types[1], stub_types[2], stub_types[3], stub_types[4]);
2250   stub_sym->name = bfd_zalloc (output_bfd, strlen (stub_sym_name) + 1);
2251   strcpy ((char *) stub_sym->name, stub_sym_name);
2252   stub_sym->value = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
2253   stub_sym->section = stub_sec;
2254   stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
2255
2256   /* redirect the original relocation from the old symbol (a function) */
2257   /* to the stub (the stub calls the function). */
2258   /* XXX do we need to change the relocation type? */
2259   reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2260   reloc_entry->sym_ptr_ptr[0] = stub_sym;
2261
2262   /* generate the beginning common section for all stubs */
2263
2264   NEW_INSTRUCTION (stub_desc, ADDI_8_SP);
2265
2266   /* generate the code to move the arguments around */
2267   for (i = ARG0; i < ARG3; i++)
2268     {
2269       if (stub_types[i] != NO_ARG_RELOC)
2270         {
2271           /* A stub is needed */
2272           switch (stub_types[i])
2273             {
2274             case R_TO_FR:
2275               switch (i)
2276                 {
2277                 case ARG0:
2278                   NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG0);
2279                   NEW_INSTRUCTION (stub_desc, FSTWS_FARG0_M8SP);
2280                   break;
2281                 case ARG1:
2282                   NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
2283                   NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
2284                   break;
2285                 case ARG2:
2286                   NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
2287                   NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
2288                   break;
2289                 case ARG3:
2290                   NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1);
2291                   NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
2292                   break;
2293                 }
2294               break;
2295
2296             case FR_TO_R:
2297               switch (i)
2298                 {
2299                 case ARG0:
2300                   NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG0);
2301                   NEW_INSTRUCTION (stub_desc, STWS_ARG0_M8SP);
2302                   break;
2303                 case ARG1:
2304                   NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
2305                   NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
2306                   break;
2307                 case ARG2:
2308                   NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
2309                   NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
2310                   break;
2311                 case ARG3:
2312                   NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
2313                   NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
2314                   break;
2315                 }
2316               break;
2317
2318             }
2319         }
2320     }
2321
2322   /* generate the branch to the target routine */
2323   NEW_INSTRUCTION (stub_desc, STW_RP_M8SP);     /* First, save the return address */
2324   NEW_INSTRUCTION (stub_desc, BL_XXX_RP);       /* set up a branch to the function */
2325
2326   /* Fix the branch to the function.  We can do this with a relocation. */
2327
2328   hppa_elf_stub_branch_reloc (stub_desc,
2329                               output_bfd,       /* the output bfd */
2330                               stub_sym, /* the stub symbol */
2331            (int) stub_desc->stub_secp - (int) stub_desc->stub_contents - 4);    /* the offset within the stub buffer */
2332
2333   NEW_INSTRUCTION (stub_desc, NOP);
2334
2335   /* generate the code to move the return value around */
2336   i = RETVAL;
2337   if (stub_types[i] != NO_ARG_RELOC)
2338     {
2339       /* A stub is needed */
2340       switch (stub_types[i])
2341         {
2342         case R_TO_FR:
2343           NEW_INSTRUCTION (stub_desc, LDWS_M8SP_RET0);
2344           NEW_INSTRUCTION (stub_desc, FSTWS_FRET0_M8SP);
2345           break;
2346
2347         case FR_TO_R:
2348           NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FRET0);
2349           NEW_INSTRUCTION (stub_desc, STWS_RET0_M8SP);
2350           break;
2351         }
2352     }
2353
2354   /* generate the ending common section for all stubs */
2355
2356   NEW_INSTRUCTION (stub_desc, LDW_M8SP_RP);     /* restore return address */
2357   NEW_INSTRUCTION (stub_desc, SUBI_8_SP);
2358
2359   /* XXX: can we assume this is a save return? */
2360   NEW_INSTRUCTION (stub_desc, BV_N_0RP);
2361
2362   return stub_sym;
2363 }
2364
2365 int
2366 hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
2367      bfd *abfd;
2368      arelent *reloc_entry;
2369      int stub_types[5];
2370 {
2371   int i;
2372   /* If the symbol is still undefined, there is */
2373   /* no way to know if a stub is required.      */
2374
2375   if (reloc_entry->sym_ptr_ptr[0] && reloc_entry->sym_ptr_ptr[0]->section != &bfd_und_section)
2376     {
2377       symext_entryS caller_ar = (symext_entryS) ELF32_HPPA_R_ARG_RELOC (reloc_entry->addend);
2378       symext_entryS callee_ar = elf32_hppa_get_sym_extn (abfd,
2379                                                 reloc_entry->sym_ptr_ptr[0],
2380                                                          HPPA_SXT_ARG_RELOC);
2381
2382       /* Now, determine if a stub is */
2383       /* required.  A stub is required if they the callee and caller    */
2384       /* argument relocation bits are both nonzero and not equal.       */
2385
2386       if (caller_ar && callee_ar)
2387         {
2388           /* Both are non-zero, we need to do further checking. */
2389           /* First, check if there is a return value relocation to be done */
2390           int caller_loc[5];
2391           int callee_loc[5];
2392
2393           callee_loc[RETVAL] = EXTRACT_ARBITS (callee_ar, RETVAL);
2394           caller_loc[RETVAL] = EXTRACT_ARBITS (caller_ar, RETVAL);
2395           callee_loc[ARG0] = EXTRACT_ARBITS (callee_ar, ARG0);
2396           caller_loc[ARG0] = EXTRACT_ARBITS (caller_ar, ARG0);
2397           callee_loc[ARG1] = EXTRACT_ARBITS (callee_ar, ARG1);
2398           caller_loc[ARG1] = EXTRACT_ARBITS (caller_ar, ARG1);
2399           callee_loc[ARG2] = EXTRACT_ARBITS (callee_ar, ARG2);
2400           caller_loc[ARG2] = EXTRACT_ARBITS (caller_ar, ARG2);
2401           callee_loc[ARG3] = EXTRACT_ARBITS (callee_ar, ARG3);
2402           caller_loc[ARG3] = EXTRACT_ARBITS (caller_ar, ARG3);
2403
2404           /* Check some special combinations.  For */
2405           /* example, if FU appears in ARG1 or ARG3, we */
2406           /* can move it to ARG0 or ARG2, respectively. */
2407
2408           if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
2409             {
2410               caller_loc[ARG0] = AR_FU;
2411               caller_loc[ARG1] = AR_NO;
2412             }
2413           if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
2414             {
2415               caller_loc[ARG2] = AR_FU;
2416               caller_loc[ARG3] = AR_NO;
2417             }
2418           if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
2419             {
2420               callee_loc[ARG0] = AR_FU;
2421               callee_loc[ARG1] = AR_NO;
2422             }
2423           if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
2424             {
2425               callee_loc[ARG2] = AR_FU;
2426               callee_loc[ARG3] = AR_NO;
2427             }
2428
2429           stub_types[ARG0] = type_of_mismatch (caller_loc[ARG0], callee_loc[ARG0], ARGUMENTS);
2430           stub_types[ARG1] = type_of_mismatch (caller_loc[ARG1], callee_loc[ARG1], ARGUMENTS);
2431           stub_types[ARG2] = type_of_mismatch (caller_loc[ARG2], callee_loc[ARG2], ARGUMENTS);
2432           stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS);
2433           stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE);
2434
2435           /* XXX for now, just report a */
2436           /* warning */
2437
2438           /* But, when we start building stubs, here are the steps involved: */
2439           /* 1. Determine what argument registers need to relocated.  This */
2440           /*    step is already done here. */
2441           /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
2442           /*    This section should never appear in an object file.  It is */
2443           /*    only used internally.  The output_section of the */
2444           /*    .hppa_linker_stubs section is the .text section of the */
2445           /*    executable.     */
2446           /* 3. Build a symbol that is used (internally only) as the entry */
2447           /*    point of the stub. */
2448           /* 4. Change the instruction of the original branch into a branch to */
2449           /*    the stub routine. */
2450           /* 5. Build a relocation entry for the instruction of the original */
2451           /*    branch to be R_HPPA_ABS_CALL to the stub routine. */
2452
2453
2454           if (stub_types[0]
2455               || stub_types[1]
2456               || stub_types[2]
2457               || stub_types[3]
2458               || stub_types[4])
2459             {
2460 #ifdef DETECT_STUBS
2461               fprintf (stderr, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
2462                        reloc_entry->sym_ptr_ptr[0]->name,
2463                        abfd->filename, reloc_entry->address,
2464                        callee_ar, caller_ar);
2465               for (i = ARG0; i < RETVAL; i++)
2466                 {
2467                   if (stub_types[i] != NO_ARG_RELOC)
2468                     {
2469                       fprintf (stderr, "%s%d: %s ",
2470                                i == RETVAL ? "ret" : "arg",
2471                                i == RETVAL ? 0 : i,
2472                                reloc_type_strings[stub_types[i]]);
2473                     }
2474                 }
2475               fprintf (stderr, "\n");
2476 #endif
2477               return 1;
2478             }
2479
2480         }
2481     }
2482   return 0;
2483 }
2484
2485 asymbol *
2486 hppa_elf_stub_check (abfd, output_bfd, reloc_entry)
2487      bfd *abfd;
2488      bfd *output_bfd;
2489      arelent *reloc_entry;
2490 {
2491   int stub_types[5];
2492
2493   switch (reloc_entry->howto->type)
2494     {
2495     case R_HPPA_ABS_CALL_11:    /*      Symbol + Addend         11      */
2496     case R_HPPA_ABS_CALL_14:    /*      Symbol + Addend         14      */
2497     case R_HPPA_ABS_CALL_17:    /*      Symbol + Addend         17      */
2498     case R_HPPA_ABS_CALL_L21:   /*      L (Symbol, Addend)      21      */
2499     case R_HPPA_ABS_CALL_R11:   /*      R (Symbol, Addend)      11      */
2500     case R_HPPA_ABS_CALL_R14:   /*      R (Symbol, Addend)      14      */
2501     case R_HPPA_ABS_CALL_R17:   /*      R (Symbol, Addend)      17      */
2502     case R_HPPA_ABS_CALL_LS21:  /*      LS(Symbol, Addend)      21      */
2503     case R_HPPA_ABS_CALL_RS11:  /*      RS(Symbol, Addend)      11      */
2504     case R_HPPA_ABS_CALL_RS14:  /*      RS(Symbol, Addend)      14      */
2505     case R_HPPA_ABS_CALL_RS17:  /*      RS(Symbol, Addend)      17      */
2506     case R_HPPA_ABS_CALL_LD21:  /*      LD(Symbol, Addend)      21      */
2507     case R_HPPA_ABS_CALL_RD11:  /*      RD(Symbol, Addend)      11      */
2508     case R_HPPA_ABS_CALL_RD14:  /*      RD(Symbol, Addend)      14      */
2509     case R_HPPA_ABS_CALL_RD17:  /*      RD(Symbol, Addend)      17      */
2510     case R_HPPA_ABS_CALL_LR21:  /*      LR(Symbol, Addend)      21      */
2511     case R_HPPA_ABS_CALL_RR14:  /*      RR(Symbol, Addend)      14      */
2512     case R_HPPA_ABS_CALL_RR17:  /*      RR(Symbol, Addend)      17      */
2513
2514     case R_HPPA_PCREL_CALL_11:  /*      Symbol - PC + Addend    11      */
2515     case R_HPPA_PCREL_CALL_14:  /*      Symbol - PC + Addend    14      */
2516     case R_HPPA_PCREL_CALL_17:  /*      Symbol - PC + Addend    17      */
2517     case R_HPPA_PCREL_CALL_12:  /*      Symbol - PC + Addend    12      */
2518     case R_HPPA_PCREL_CALL_L21:/*       L (Symbol - PC, Addend) 21      */
2519     case R_HPPA_PCREL_CALL_R11:/*       R (Symbol - PC, Addend) 11      */
2520     case R_HPPA_PCREL_CALL_R14:/*       R (Symbol - PC, Addend) 14      */
2521     case R_HPPA_PCREL_CALL_R17:/*       R (Symbol - PC, Addend) 17      */
2522     case R_HPPA_PCREL_CALL_LS21:        /*      LS(Symbol - PC, Addend) 21      */
2523     case R_HPPA_PCREL_CALL_RS11:        /*      RS(Symbol - PC, Addend) 11      */
2524     case R_HPPA_PCREL_CALL_RS14:        /*      RS(Symbol - PC, Addend) 14      */
2525     case R_HPPA_PCREL_CALL_RS17:        /*      RS(Symbol - PC, Addend) 17      */
2526     case R_HPPA_PCREL_CALL_LD21:        /*      LD(Symbol - PC, Addend) 21      */
2527     case R_HPPA_PCREL_CALL_RD11:        /*      RD(Symbol - PC, Addend) 11      */
2528     case R_HPPA_PCREL_CALL_RD14:        /*      RD(Symbol - PC, Addend) 14      */
2529     case R_HPPA_PCREL_CALL_RD17:        /*      RD(Symbol - PC, Addend) 17      */
2530     case R_HPPA_PCREL_CALL_LR21:        /*      LR(Symbol - PC, Addend) 21      */
2531     case R_HPPA_PCREL_CALL_RR14:        /*      RR(Symbol - PC, Addend) 14      */
2532     case R_HPPA_PCREL_CALL_RR17:        /*      RR(Symbol - PC, Addend) 17      */
2533       if (hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types))
2534         {
2535           /* generate a stub */
2536           return hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types);
2537         }
2538       break;
2539
2540     default:
2541       break;
2542
2543     }
2544   return reloc_entry->sym_ptr_ptr[0];
2545 }
2546
2547 #define STUB_SYM_BUFFER_INC     5
2548
2549 asymbol *
2550 hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt)
2551      bfd *abfd;
2552      bfd *output_bfd;
2553      asection *asec;
2554      asymbol **syms;
2555      int *new_sym_cnt;
2556 {
2557   int i;
2558   int stub_types[5];
2559   asymbol *new_syms = (asymbol *) NULL;
2560   int new_cnt = 0;
2561   int new_max = 0;
2562
2563   /* Relocations are in different places depending on whether this is   */
2564   /* an output section or an input section.  Also, the relocations are  */
2565   /* in different forms.  Sigh. */
2566   /* Luckily, we have bfd_canonicalize_reloc() to straighten this out for us. */
2567
2568   /* if ( asec->orelocation || asec->relocation ) { */
2569   if (asec->reloc_count > 0)
2570     {
2571       arelent **reloc_vector = (arelent **) alloca (asec->reloc_count * (sizeof (arelent *) + 1));
2572
2573       bfd_canonicalize_reloc (abfd, asec, reloc_vector, syms);
2574       for (i = 0; i < asec->reloc_count; i++)
2575         {
2576 #if 0
2577           arelent *rle;
2578
2579           if ( asec->orelocation )
2580             rle = asec->orelocation[i];
2581           else
2582             rle = asec->relocation+i;
2583 #endif
2584
2585           arelent *rle = reloc_vector[i];
2586
2587           switch (rle->howto->type)
2588             {
2589             case R_HPPA_ABS_CALL_11:    /*      Symbol + Addend         11      */
2590             case R_HPPA_ABS_CALL_14:    /*      Symbol + Addend         14      */
2591             case R_HPPA_ABS_CALL_17:    /*      Symbol + Addend         17      */
2592             case R_HPPA_ABS_CALL_L21:   /*      L (Symbol, Addend)      21      */
2593             case R_HPPA_ABS_CALL_R11:   /*      R (Symbol, Addend)      11      */
2594             case R_HPPA_ABS_CALL_R14:   /*      R (Symbol, Addend)      14      */
2595             case R_HPPA_ABS_CALL_R17:   /*      R (Symbol, Addend)      17      */
2596             case R_HPPA_ABS_CALL_LS21:  /*      LS(Symbol, Addend)      21      */
2597             case R_HPPA_ABS_CALL_RS11:  /*      RS(Symbol, Addend)      11      */
2598             case R_HPPA_ABS_CALL_RS14:  /*      RS(Symbol, Addend)      14      */
2599             case R_HPPA_ABS_CALL_RS17:  /*      RS(Symbol, Addend)      17      */
2600             case R_HPPA_ABS_CALL_LD21:  /*      LD(Symbol, Addend)      21      */
2601             case R_HPPA_ABS_CALL_RD11:  /*      RD(Symbol, Addend)      11      */
2602             case R_HPPA_ABS_CALL_RD14:  /*      RD(Symbol, Addend)      14      */
2603             case R_HPPA_ABS_CALL_RD17:  /*      RD(Symbol, Addend)      17      */
2604             case R_HPPA_ABS_CALL_LR21:  /*      LR(Symbol, Addend)      21      */
2605             case R_HPPA_ABS_CALL_RR14:  /*      RR(Symbol, Addend)      14      */
2606             case R_HPPA_ABS_CALL_RR17:  /*      RR(Symbol, Addend)      17      */
2607
2608             case R_HPPA_PCREL_CALL_11:  /*      Symbol - PC + Addend    11      */
2609             case R_HPPA_PCREL_CALL_14:  /*      Symbol - PC + Addend    14      */
2610             case R_HPPA_PCREL_CALL_17:  /*      Symbol - PC + Addend    17      */
2611             case R_HPPA_PCREL_CALL_12:  /*      Symbol - PC + Addend    12      */
2612             case R_HPPA_PCREL_CALL_L21: /*      L (Symbol - PC, Addend) 21      */
2613             case R_HPPA_PCREL_CALL_R11: /*      R (Symbol - PC, Addend) 11      */
2614             case R_HPPA_PCREL_CALL_R14: /*      R (Symbol - PC, Addend) 14      */
2615             case R_HPPA_PCREL_CALL_R17: /*      R (Symbol - PC, Addend) 17      */
2616             case R_HPPA_PCREL_CALL_LS21:        /*      LS(Symbol - PC, Addend) 21      */
2617             case R_HPPA_PCREL_CALL_RS11:        /*      RS(Symbol - PC, Addend) 11      */
2618             case R_HPPA_PCREL_CALL_RS14:        /*      RS(Symbol - PC, Addend) 14      */
2619             case R_HPPA_PCREL_CALL_RS17:        /*      RS(Symbol - PC, Addend) 17      */
2620             case R_HPPA_PCREL_CALL_LD21:        /*      LD(Symbol - PC, Addend) 21      */
2621             case R_HPPA_PCREL_CALL_RD11:        /*      RD(Symbol - PC, Addend) 11      */
2622             case R_HPPA_PCREL_CALL_RD14:        /*      RD(Symbol - PC, Addend) 14      */
2623             case R_HPPA_PCREL_CALL_RD17:        /*      RD(Symbol - PC, Addend) 17      */
2624             case R_HPPA_PCREL_CALL_LR21:        /*      LR(Symbol - PC, Addend) 21      */
2625             case R_HPPA_PCREL_CALL_RR14:        /*      RR(Symbol - PC, Addend) 14      */
2626             case R_HPPA_PCREL_CALL_RR17:        /*      RR(Symbol - PC, Addend) 17      */
2627               if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types))
2628                 {
2629                   /* generate a stub */
2630                   /* keep track of the new symbol */
2631                   if (new_cnt == new_max)
2632                     {
2633                       new_max += STUB_SYM_BUFFER_INC;
2634                       new_syms = (asymbol *) realloc (new_syms, new_max * sizeof (asymbol));
2635                     }
2636                   new_syms[new_cnt++] = *(hppa_elf_build_arg_reloc_stub (abfd, output_bfd, rle, stub_types));
2637                 }
2638               break;
2639
2640             default:
2641               break;
2642
2643             }
2644         }
2645     }
2646   *new_sym_cnt = new_cnt;
2647   return new_syms;
2648 }
2649
2650 int
2651 hppa_look_for_stubs (abfd, output_bfd)
2652      bfd *abfd;
2653      bfd *output_bfd;
2654 {
2655   /* bfd_map_over_sections(abfd,hppa_look_for_stubs_in_section,(PTR)output_bfd,NULL); */
2656 }
2657
2658 boolean
2659 DEFUN (hppa_elf_get_section_contents, (abfd, section, location, offset, count),
2660        bfd * abfd AND
2661        sec_ptr section AND
2662        PTR location AND
2663        file_ptr offset AND
2664        bfd_size_type count)
2665 {
2666   /* if this is the linker stub section, then we have the       */
2667   /* section contents in memory rather than on disk.    */
2668   if (strcmp (section->name, ".hppa_linker_stubs") == 0)
2669     {
2670       Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, section);
2671
2672       if (count == 0)
2673         return true;
2674       if ((bfd_size_type) (offset + count) > section->_raw_size)
2675         return (false);         /* on error */
2676       if ((bfd_size_type) (offset + count) > stub_desc->real_size)
2677         return (false);         /* on error */
2678
2679       memcpy (location, stub_desc->stub_contents + offset, count);
2680       return (true);
2681     }
2682   /* if this is the symbol extension section, then we have the  */
2683   /* section contents in memory rather than on disk.    */
2684   else if (strcmp (section->name, ".hppa_symextn") == 0)
2685     {
2686       if (count == 0)
2687         return true;
2688       if ((bfd_size_type) (offset + count) > section->_raw_size)
2689         return (false);         /* on error */
2690       if ((bfd_size_type) (offset + count) > symextn_contents_real_size)
2691         return (false);         /* on error */
2692
2693       memcpy (location, symextn_contents + offset, count);
2694       return (true);
2695     }
2696   else
2697     return bfd_generic_get_section_contents (abfd, section, location, offset, count);
2698 }
2699
2700 static void
2701 DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst),
2702        bfd * abfd AND
2703        arelent * cache_ptr AND
2704        Elf32_Internal_Rela * dst)
2705 {
2706   abort ();
2707 }
2708
2709 #define TARGET_BIG_SYM          bfd_elf32_hppa_vec
2710 #define TARGET_BIG_NAME         "elf32-hppa"
2711 #define ELF_ARCH                bfd_arch_hppa
2712
2713 #include "elf32-target.h"
This page took 0.174058 seconds and 4 git commands to generate.