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