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