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