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