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