Commit | Line | Data |
---|---|---|
4c85cbfa KR |
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 | ||
33 | static struct elf_backend_data elf_hppa_backend_data = { | |
34 | NULL /* initially, $global$ is undefined */ | |
35 | }; | |
36 | ||
37 | /* ELF32/HPPA relocation support | |
38 | ||
39 | This file contains ELF32/HPPA relocation support as specified | |
40 | in the Stratus FTX/Golf Object File Format (SED-1762) dated | |
41 | November 19, 1992. | |
42 | */ | |
43 | ||
44 | /* | |
45 | Written by: | |
46 | ||
47 | Center for Software Science | |
48 | Department of Computer Science | |
49 | University of Utah | |
50 | */ | |
51 | ||
52 | #include "elf32-hppa.h" | |
53 | ||
54 | /* ELF/PA stab entries */ | |
55 | ||
56 | #ifdef hp800 | |
57 | #undef hp800 | |
58 | #include <a.out.h> /* we want the non-hp800 definition of 'struct nlist' */ | |
59 | #define hp800 | |
60 | #else | |
61 | #include <a.out.h> | |
62 | #endif | |
63 | ||
64 | /* ELF/PA relocation howto entries */ | |
65 | ||
66 | static bfd_reloc_status_type hppa_elf_reloc(); | |
67 | ||
68 | reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = { | |
69 | /* 'bitpos' and 'abs' are obsolete */ | |
70 | /* type rs sz bsz pcrel bpos abs ovrf sf name */ | |
71 | /* 9.3.4. Address relocation types */ | |
72 | { R_HPPA_NONE, 0, 3, 19, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NONE"}, | |
73 | { R_HPPA_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_32" }, | |
74 | { R_HPPA_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_11" }, | |
75 | { R_HPPA_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_14" }, | |
76 | { R_HPPA_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_17" }, | |
77 | { R_HPPA_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L21" }, | |
78 | { R_HPPA_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R11" }, | |
79 | { R_HPPA_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R14" }, | |
80 | { R_HPPA_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R17" }, | |
81 | { R_HPPA_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LS21" }, | |
82 | { R_HPPA_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS11" }, | |
83 | { R_HPPA_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS14" }, | |
84 | { R_HPPA_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS17" }, | |
85 | { R_HPPA_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LD21" }, | |
86 | { R_HPPA_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD11" }, | |
87 | { R_HPPA_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD14" }, | |
88 | { R_HPPA_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD17" }, | |
89 | { R_HPPA_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LR21" }, | |
90 | { R_HPPA_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR14" }, | |
91 | { R_HPPA_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR17" }, | |
92 | /* 9.3.5. GOTOFF address relocation types */ | |
93 | { R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_11" }, | |
94 | { R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_14" }, | |
95 | { R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_L21" }, | |
96 | { R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R11" }, | |
97 | { R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R14" }, | |
98 | { R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21" }, | |
99 | { R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11" }, | |
100 | { R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14" }, | |
101 | { R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21" }, | |
102 | { R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11" }, | |
103 | { R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14" }, | |
104 | { R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21" }, | |
105 | { R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14" }, | |
106 | /* 9.3.6. Absolute call relocation types */ | |
107 | { R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_11" }, | |
108 | { R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_14" }, | |
109 | { R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_17" }, | |
110 | { R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21" }, | |
111 | { R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11" }, | |
112 | { R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14" }, | |
113 | { R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17" }, | |
114 | { R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21" }, | |
115 | { R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11" }, | |
116 | { R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14" }, | |
117 | { R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17" }, | |
118 | { R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21" }, | |
119 | { R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11" }, | |
120 | { R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14" }, | |
121 | { R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17" }, | |
122 | { R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21" }, | |
123 | { R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14" }, | |
124 | { R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17" }, | |
125 | /* 9.3.7. PC-relative call relocation types */ | |
126 | { R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11" }, | |
127 | { R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14" }, | |
128 | { R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17" }, | |
129 | { R_HPPA_PCREL_CALL_L21,0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21" }, | |
130 | { R_HPPA_PCREL_CALL_R11,0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11" }, | |
131 | { R_HPPA_PCREL_CALL_R14,0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14" }, | |
132 | { R_HPPA_PCREL_CALL_R17,0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17" }, | |
133 | { R_HPPA_PCREL_CALL_LS21,0,3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21" }, | |
134 | { R_HPPA_PCREL_CALL_RS11,0,3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11" }, | |
135 | { R_HPPA_PCREL_CALL_RS14,0,3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14" }, | |
136 | { R_HPPA_PCREL_CALL_RS17,0,3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17" }, | |
137 | { R_HPPA_PCREL_CALL_LD21,0,3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21" }, | |
138 | { R_HPPA_PCREL_CALL_RD11,0,3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11" }, | |
139 | { R_HPPA_PCREL_CALL_RD14,0,3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14" }, | |
140 | { R_HPPA_PCREL_CALL_RD17,0,3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17" }, | |
141 | { R_HPPA_PCREL_CALL_LR21,0,3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21" }, | |
142 | { R_HPPA_PCREL_CALL_RR14,0,3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14" }, | |
143 | { R_HPPA_PCREL_CALL_RR17,0,3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17" }, /* #69 */ | |
144 | ||
145 | /* 9.3.8. Plabel relocation types */ | |
146 | { R_HPPA_PLABEL_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_32" }, | |
147 | { R_HPPA_PLABEL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_11" }, | |
148 | { R_HPPA_PLABEL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_14" }, | |
149 | { R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_L21" }, | |
150 | { R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R11" }, | |
151 | { R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R14" }, /* 75 */ | |
152 | ||
153 | /* 9.3.9. Data linkage table (DLT) relocation types */ | |
154 | { R_HPPA_DLT_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_32" }, | |
155 | { R_HPPA_DLT_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_11" }, | |
156 | { R_HPPA_DLT_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_14" }, | |
157 | { R_HPPA_DLT_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_L21" }, | |
158 | { R_HPPA_DLT_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R11" }, | |
159 | { R_HPPA_DLT_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R14" }, /* 81 */ | |
160 | ||
161 | /* 9.3.10. Relocations for unwinder tables */ | |
162 | { R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"}, | |
163 | { R_HPPA_UNWIND_ENTRIES,0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"}, /* 83 */ | |
164 | ||
165 | { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 84-89 */ | |
166 | { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 90-99 */ | |
167 | { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 100-109 */ | |
168 | { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 110-119 */ | |
169 | { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 120-127 */ | |
170 | ||
171 | /* 9.3.11. Relocation types for complex expressions */ | |
172 | { R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_CONST" }, | |
173 | { R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_SYM" }, | |
174 | { R_HPPA_PUSH_GOT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_GOT" }, | |
175 | { R_HPPA_PUSH_PC, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PC" }, | |
176 | { R_HPPA_PUSH_PROC, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PROC" }, | |
177 | { R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL" }, | |
178 | { R_HPPA_MAX, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MAX" }, | |
179 | { R_HPPA_MIN, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MIN" }, | |
180 | { R_HPPA_ADD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ADD" }, | |
181 | { R_HPPA_SUB, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_SUB" }, | |
182 | { R_HPPA_MULT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MULT" }, | |
183 | { R_HPPA_DIV, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_DIV" }, | |
184 | { R_HPPA_MOD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MOD" }, | |
185 | { R_HPPA_AND, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_AND" }, | |
186 | { R_HPPA_OR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_OR" }, | |
187 | { R_HPPA_XOR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_XOR" }, | |
188 | { R_HPPA_NOT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NOT" }, | |
189 | { R_HPPA_LSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LSHIFT" }, | |
190 | { R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT" }, | |
191 | { R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT" }, | |
192 | { R_HPPA_EXPR_F, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L" }, | |
193 | { R_HPPA_EXPR_L, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_L" }, | |
194 | { R_HPPA_EXPR_R, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_R" }, | |
195 | { R_HPPA_EXPR_LS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LS" }, | |
196 | { R_HPPA_EXPR_RS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RS" }, | |
197 | { R_HPPA_EXPR_LD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LD" }, | |
198 | { R_HPPA_EXPR_RD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RD" }, | |
199 | { R_HPPA_EXPR_LR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LR" }, | |
200 | { R_HPPA_EXPR_RR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RR" }, | |
201 | ||
202 | { R_HPPA_EXPR_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_32" }, | |
203 | { R_HPPA_EXPR_21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_21" }, | |
204 | { R_HPPA_EXPR_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_11" }, | |
205 | { R_HPPA_EXPR_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_14" }, | |
206 | { R_HPPA_EXPR_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_17" }, | |
207 | { R_HPPA_EXPR_12, 0, 3, 12, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_12" }, | |
208 | { R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, false, false,NULL, "R_HPPA_UNIMPLEMENTED"}, /* 163 */ | |
209 | }; | |
210 | ||
211 | static unsigned long | |
212 | DEFUN(hppa_elf_rebuild_insn, (abfd,insn,value,r_type,r_field, r_format), | |
213 | bfd *abfd AND | |
214 | unsigned long insn AND | |
215 | unsigned long value AND | |
216 | unsigned short r_type AND | |
217 | unsigned short r_field AND | |
218 | unsigned short r_format) | |
219 | { | |
220 | unsigned long const_part; /* part of the instruction that does not change */ | |
221 | unsigned long rebuilt_part; | |
222 | ||
223 | switch ( r_format ) { | |
224 | case 11: { | |
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 12: { | |
234 | unsigned w1, w; | |
235 | ||
236 | const_part = insn & 0xffffe002; | |
237 | dis_assemble_12(value,&w1,&w); | |
238 | rebuilt_part = (w1 << 2) | w; | |
239 | return const_part | rebuilt_part; | |
240 | } | |
241 | ||
242 | case 14: | |
243 | const_part = insn & 0xffffc000; | |
244 | low_sign_unext(value,14,&rebuilt_part); | |
245 | return const_part | rebuilt_part; | |
246 | ||
247 | case 17: { | |
248 | unsigned w1, w2, w; | |
249 | ||
250 | const_part = insn & 0xffe0e002; | |
251 | dis_assemble_17(value,&w1,&w2,&w); | |
252 | rebuilt_part = (w2 << 2) | (w1 << 16) | w; | |
253 | return const_part | rebuilt_part; | |
254 | } | |
255 | ||
256 | case 21: | |
257 | const_part = insn & 0xffe00000; | |
258 | dis_assemble_21(value,&rebuilt_part); | |
259 | return const_part | rebuilt_part; | |
260 | ||
261 | case 32: | |
262 | const_part = 0; | |
263 | return value; | |
264 | ||
265 | default: | |
266 | fprintf(stderr,"Relocation problem : "); | |
267 | fprintf(stderr,"Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n", | |
268 | r_type, r_format, r_field, abfd->filename); | |
269 | } | |
270 | return insn; | |
271 | } | |
272 | ||
273 | static unsigned long | |
274 | DEFUN(hppa_elf_relocate_insn, | |
275 | (abfd, input_sect, | |
276 | insn, address, symp, sym_value, r_addend, | |
277 | r_type, r_format, r_field, pcrel), | |
278 | bfd *abfd AND | |
279 | asection *input_sect AND | |
280 | unsigned long insn AND | |
281 | unsigned long address AND | |
282 | asymbol *symp AND | |
283 | long sym_value AND | |
284 | long r_addend AND | |
285 | unsigned short r_type AND | |
286 | unsigned short r_format AND | |
287 | unsigned short r_field AND | |
288 | unsigned char pcrel) | |
289 | { | |
290 | unsigned char opcode = get_opcode(insn); | |
291 | long constant_value; | |
292 | unsigned arg_reloc; | |
293 | ||
294 | switch ( opcode ) { | |
295 | case LDO: | |
296 | case LDB: | |
297 | case LDH: | |
298 | case LDW: | |
299 | case LDWM: | |
300 | case STB: | |
301 | case STH: | |
302 | case STW: | |
303 | case STWM: | |
304 | constant_value = ELF32_HPPA_R_CONSTANT(r_addend); | |
305 | BFD_ASSERT(r_format == 14); | |
306 | ||
307 | if ( pcrel ) | |
308 | sym_value -= address; | |
309 | sym_value = hppa_field_adjust(sym_value,constant_value,r_field); | |
310 | return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_format, r_format); | |
311 | ||
312 | case COMICLR: | |
313 | case SUBI: /* case SUBIO: */ | |
314 | case ADDIT: /* case ADDITO: */ | |
315 | case ADDI: /* case ADDIO: */ | |
316 | BFD_ASSERT(r_format == 11); | |
317 | ||
318 | constant_value = ((insn & 0x1) << 10) | ((insn & 0xffe) >> 1); | |
319 | sym_value = hppa_field_adjust(sym_value,constant_value,r_field); | |
320 | return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_field, r_format); | |
321 | ||
322 | case LDIL: | |
323 | case ADDIL: | |
324 | BFD_ASSERT(r_format == 21); | |
325 | ||
326 | constant_value = assemble_21(insn); | |
327 | sym_value = hppa_field_adjust(sym_value,constant_value,r_field); | |
328 | return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_field, r_format); | |
329 | ||
330 | case BL: | |
331 | case BE: | |
332 | case BLE: | |
333 | arg_reloc = ELF32_HPPA_R_ARG_RELOC(r_addend); | |
334 | ||
335 | BFD_ASSERT(r_format == 17); | |
336 | ||
337 | /* XXX computing constant_value is not needed??? */ | |
338 | constant_value = assemble_17((insn & 0x001f0000) >> 16, | |
339 | (insn & 0x00001ffc) >> 2, | |
340 | insn & 1); | |
341 | constant_value = sign_ext(constant_value,17); | |
342 | if ( pcrel ) { | |
343 | sym_value -= | |
344 | address + input_sect->output_offset | |
345 | + input_sect->output_section->vma; | |
346 | sym_value = hppa_field_adjust(sym_value,-8,r_field); | |
347 | } | |
348 | else | |
349 | sym_value = hppa_field_adjust(sym_value, constant_value, r_field); | |
350 | ||
351 | return hppa_elf_rebuild_insn(abfd,insn,sym_value >> 2,r_type,r_field, r_format); | |
352 | ||
353 | default: | |
354 | if ( opcode == 0 && r_format == 32 ) { | |
355 | constant_value = insn; | |
356 | sym_value = hppa_field_adjust(sym_value,constant_value,r_field); | |
357 | return sym_value; | |
358 | } | |
359 | else { | |
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 constant_value; | |
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 | 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 | unsigned int fsize; | |
409 | start_offset = bfd_get_32(abfd, hit_data); | |
410 | /* Stuff the symbol value into the first word */ | |
411 | /* of the unwind descriptor */ | |
412 | bfd_put_32(abfd, sym_value ,hit_data); | |
413 | ||
414 | hit_data += sizeof(unsigned long); | |
415 | end_offset = bfd_get_32(abfd, hit_data); | |
416 | /* We could also compute the ending offset for */ | |
417 | /* the 2nd word of the unwind entry by */ | |
418 | /* retrieving the st_size field of the Elf_Sym */ | |
419 | /* structure stored with this symbol. We can */ | |
420 | /* get it with: */ | |
421 | /* e = (elf_symbol_type *)symp */ | |
422 | /* fsize = e->internal_elf_sym.st_size */ | |
423 | ||
424 | fsize = end_offset - start_offset; | |
425 | relocated_value = hppa_field_adjust(sym_value,fsize,r_field); | |
426 | bfd_put_32(abfd, relocated_value ,hit_data); | |
427 | ||
428 | /* If this is not the last unwind entry, */ | |
429 | /* adjust the symbol value. */ | |
430 | if ( i+1 < r_addend ) { | |
431 | start_offset = bfd_get_32(abfd, hit_data+3*sizeof(unsigned long)); | |
432 | sym_value += fsize + start_offset - end_offset; | |
433 | } | |
434 | } | |
435 | break; | |
436 | ||
437 | default: | |
438 | fprintf(stderr, | |
439 | "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n", | |
440 | r_type, r_format, r_field); | |
441 | } | |
442 | return; | |
443 | } | |
444 | ||
445 | /* Provided the symbol, returns the value reffed */ | |
446 | static long | |
447 | get_symbol_value(symbol) | |
448 | asymbol *symbol; | |
449 | { | |
450 | long relocation = 0; | |
451 | ||
452 | if ( symbol == (asymbol *)NULL ) | |
453 | relocation = 0; | |
454 | else if (symbol->section == &bfd_com_section) { | |
455 | relocation = 0; | |
456 | } | |
457 | else { | |
458 | relocation = symbol->value + | |
459 | symbol->section->output_section->vma + | |
460 | symbol->section->output_offset; | |
461 | } | |
462 | ||
463 | return(relocation); | |
464 | } | |
465 | ||
466 | /* This function provides a pretty straight-forward mapping between a */ | |
467 | /* base relocation type, format and field into the relocation type */ | |
468 | /* that will be emitted in an object file. The only wrinkle in the */ | |
469 | /* mapping is that when the T, TR, TL, P, PR, or PL expression */ | |
470 | /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */ | |
471 | /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */ | |
472 | /* (in the case of P, PR, and PL). */ | |
473 | ||
474 | /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */ | |
475 | /* handled yet. */ | |
476 | ||
477 | static void | |
478 | hppa_elf_gen_reloc_error(base_type,fmt,field) | |
479 | elf32_hppa_reloc_type base_type; | |
480 | int fmt; | |
481 | int field; | |
482 | { | |
483 | fprintf(stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n", | |
484 | base_type, fmt, field); | |
485 | } | |
486 | ||
487 | unsigned char | |
488 | hppa_elf_gen_reloc_type(base_type, format, field) | |
489 | elf32_hppa_reloc_type base_type; | |
490 | int format; | |
491 | int field; | |
492 | { | |
493 | #define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field); | |
494 | ||
495 | elf32_hppa_reloc_type final_type = base_type; | |
496 | switch ( base_type ) { | |
497 | case R_HPPA: | |
498 | switch (format) { | |
499 | case 11: | |
500 | switch ( field ) { | |
501 | case e_rsel: | |
502 | final_type = R_HPPA_R11; | |
503 | break; | |
504 | case e_rssel: | |
505 | final_type = R_HPPA_RS11; | |
506 | break; | |
507 | case e_rdsel: | |
508 | final_type = R_HPPA_RD11; | |
509 | break; | |
510 | ||
511 | case e_psel: | |
512 | final_type = R_HPPA_PLABEL_11; | |
513 | break; | |
514 | case e_rpsel: | |
515 | final_type = R_HPPA_PLABEL_R11; | |
516 | break; | |
517 | case e_lpsel: | |
518 | case e_tsel: | |
519 | case e_ltsel: | |
520 | case e_rtsel: | |
521 | ||
522 | case e_fsel: | |
523 | case e_lsel: | |
524 | case e_lrsel: | |
525 | case e_lssel: | |
526 | case e_rrsel: | |
527 | default: | |
528 | UNDEFINED; | |
529 | final_type = base_type; | |
530 | break; | |
531 | } | |
532 | break; | |
533 | case 12: | |
534 | UNDEFINED; | |
535 | break; | |
536 | case 14: | |
537 | switch ( field ) { | |
538 | case e_rsel: | |
539 | final_type = R_HPPA_R14; | |
540 | break; | |
541 | case e_rssel: | |
542 | final_type = R_HPPA_RS14; | |
543 | break; | |
544 | case e_rdsel: | |
545 | final_type = R_HPPA_RD14; | |
546 | break; | |
547 | case e_rrsel: | |
548 | final_type = R_HPPA_RR14; | |
549 | break; | |
550 | ||
551 | case e_psel: | |
552 | final_type = R_HPPA_PLABEL_14; | |
553 | break; | |
554 | case e_rpsel: | |
555 | final_type = R_HPPA_PLABEL_R14; | |
556 | break; | |
557 | case e_lpsel: | |
558 | case e_tsel: | |
559 | case e_ltsel: | |
560 | case e_rtsel: | |
561 | ||
562 | case e_fsel: | |
563 | case e_lsel: | |
564 | case e_lssel: | |
565 | case e_ldsel: | |
566 | case e_lrsel: | |
567 | default: | |
568 | UNDEFINED; | |
569 | final_type = base_type; | |
570 | break; | |
571 | } | |
572 | break; | |
573 | case 17: | |
574 | switch ( field ) { | |
575 | case e_rsel: | |
576 | final_type = R_HPPA_R17; | |
577 | break; | |
578 | case e_rssel: | |
579 | final_type = R_HPPA_RS17; | |
580 | break; | |
581 | case e_rdsel: | |
582 | final_type = R_HPPA_RD17; | |
583 | break; | |
584 | case e_rrsel: | |
585 | final_type = R_HPPA_RR17; | |
586 | break; | |
587 | case e_fsel: | |
588 | case e_lsel: | |
589 | case e_lssel: | |
590 | case e_ldsel: | |
591 | case e_lrsel: | |
592 | default: | |
593 | UNDEFINED; | |
594 | final_type = base_type; | |
595 | break; | |
596 | } | |
597 | break; | |
598 | case 21: | |
599 | switch ( field ) { | |
600 | case e_lsel: | |
601 | final_type = R_HPPA_L21; | |
602 | break; | |
603 | case e_lssel: | |
604 | final_type = R_HPPA_LS21; | |
605 | break; | |
606 | case e_ldsel: | |
607 | final_type = R_HPPA_LD21; | |
608 | break; | |
609 | case e_lrsel: | |
610 | final_type = R_HPPA_LR21; | |
611 | break; | |
612 | case e_lpsel: | |
613 | final_type = R_HPPA_PLABEL_L21; | |
614 | break; | |
615 | case e_rsel: | |
616 | case e_rssel: | |
617 | case e_rdsel: | |
618 | case e_rrsel: | |
619 | case e_fsel: | |
620 | default: | |
621 | UNDEFINED; | |
622 | final_type = base_type; | |
623 | break; | |
624 | } | |
625 | break; | |
626 | case 32: | |
627 | switch ( field ) { | |
628 | case e_fsel: | |
629 | final_type = R_HPPA_32; | |
630 | break; | |
631 | case e_psel: | |
632 | final_type = R_HPPA_PLABEL_32; | |
633 | break; | |
634 | default: | |
635 | UNDEFINED; | |
636 | final_type = base_type; | |
637 | break; | |
638 | } | |
639 | break; | |
640 | default: | |
641 | UNDEFINED; | |
642 | final_type = base_type; | |
643 | break; | |
644 | } | |
645 | break; | |
646 | case R_HPPA_GOTOFF: | |
647 | switch (format) { | |
648 | case 11: | |
649 | switch ( field ) { | |
650 | case e_rsel: | |
651 | final_type = R_HPPA_GOTOFF_R11; | |
652 | break; | |
653 | case e_rssel: | |
654 | final_type = R_HPPA_GOTOFF_RS11; | |
655 | break; | |
656 | case e_rdsel: | |
657 | final_type = R_HPPA_GOTOFF_RD11; | |
658 | break; | |
659 | case e_fsel: | |
660 | final_type = R_HPPA_GOTOFF_11; | |
661 | break; | |
662 | case e_lsel: | |
663 | case e_lrsel: | |
664 | case e_lssel: | |
665 | case e_rrsel: | |
666 | default: | |
667 | UNDEFINED; | |
668 | final_type = base_type; | |
669 | break; | |
670 | } | |
671 | break; | |
672 | case 12: | |
673 | UNDEFINED; | |
674 | final_type = base_type; | |
675 | break; | |
676 | case 14: | |
677 | switch ( field ) { | |
678 | case e_rsel: | |
679 | final_type = R_HPPA_GOTOFF_R14; | |
680 | break; | |
681 | case e_rssel: | |
682 | final_type = R_HPPA_GOTOFF_RS14; | |
683 | break; | |
684 | case e_rdsel: | |
685 | final_type = R_HPPA_GOTOFF_RD14; | |
686 | break; | |
687 | case e_rrsel: | |
688 | final_type = R_HPPA_GOTOFF_RR14; | |
689 | break; | |
690 | case e_fsel: | |
691 | final_type = R_HPPA_GOTOFF_14; | |
692 | break; | |
693 | case e_lsel: | |
694 | case e_lssel: | |
695 | case e_ldsel: | |
696 | case e_lrsel: | |
697 | default: | |
698 | UNDEFINED; | |
699 | final_type = base_type; | |
700 | break; | |
701 | } | |
702 | break; | |
703 | case 17: | |
704 | UNDEFINED; | |
705 | final_type = base_type; | |
706 | break; | |
707 | case 21: | |
708 | switch ( field ) { | |
709 | case e_lsel: | |
710 | final_type = R_HPPA_GOTOFF_L21; | |
711 | break; | |
712 | case e_lssel: | |
713 | final_type = R_HPPA_GOTOFF_LS21; | |
714 | break; | |
715 | case e_ldsel: | |
716 | final_type = R_HPPA_GOTOFF_LD21; | |
717 | break; | |
718 | case e_lrsel: | |
719 | final_type = R_HPPA_GOTOFF_LR21; | |
720 | break; | |
721 | case e_rsel: | |
722 | case e_rssel: | |
723 | case e_rdsel: | |
724 | case e_rrsel: | |
725 | case e_fsel: | |
726 | default: | |
727 | UNDEFINED; | |
728 | final_type = base_type; | |
729 | break; | |
730 | } | |
731 | break; | |
732 | case 32: | |
733 | UNDEFINED; | |
734 | final_type = base_type; | |
735 | break; | |
736 | default: | |
737 | UNDEFINED; | |
738 | final_type = base_type; | |
739 | break; | |
740 | } | |
741 | break; | |
742 | case R_HPPA_PCREL_CALL: | |
743 | switch (format) { | |
744 | case 11: | |
745 | switch ( field ) { | |
746 | case e_rsel: | |
747 | final_type = R_HPPA_PCREL_CALL_R11; | |
748 | break; | |
749 | case e_rssel: | |
750 | final_type = R_HPPA_PCREL_CALL_RS11; | |
751 | break; | |
752 | case e_rdsel: | |
753 | final_type = R_HPPA_PCREL_CALL_RD11; | |
754 | break; | |
755 | case e_fsel: | |
756 | final_type = R_HPPA_PCREL_CALL_11; | |
757 | break; | |
758 | case e_lsel: | |
759 | case e_lrsel: | |
760 | case e_lssel: | |
761 | case e_rrsel: | |
762 | default: | |
763 | UNDEFINED; | |
764 | final_type = base_type; | |
765 | break; | |
766 | } | |
767 | break; | |
768 | case 12: | |
769 | UNDEFINED; | |
770 | final_type = base_type; | |
771 | break; | |
772 | case 14: | |
773 | switch ( field ) { | |
774 | case e_rsel: | |
775 | final_type = R_HPPA_PCREL_CALL_R14; | |
776 | break; | |
777 | case e_rssel: | |
778 | final_type = R_HPPA_PCREL_CALL_RS14; | |
779 | break; | |
780 | case e_rdsel: | |
781 | final_type = R_HPPA_PCREL_CALL_RD14; | |
782 | break; | |
783 | case e_rrsel: | |
784 | final_type = R_HPPA_PCREL_CALL_RR14; | |
785 | break; | |
786 | case e_fsel: | |
787 | final_type = R_HPPA_PCREL_CALL_14; | |
788 | break; | |
789 | case e_lsel: | |
790 | case e_lssel: | |
791 | case e_ldsel: | |
792 | case e_lrsel: | |
793 | default: | |
794 | UNDEFINED; | |
795 | final_type = base_type; | |
796 | break; | |
797 | } | |
798 | break; | |
799 | case 17: | |
800 | switch ( field ) { | |
801 | case e_rsel: | |
802 | final_type = R_HPPA_PCREL_CALL_R17; | |
803 | break; | |
804 | case e_rssel: | |
805 | final_type = R_HPPA_PCREL_CALL_RS17; | |
806 | break; | |
807 | case e_rdsel: | |
808 | final_type = R_HPPA_PCREL_CALL_RD17; | |
809 | break; | |
810 | case e_rrsel: | |
811 | final_type = R_HPPA_PCREL_CALL_RR17; | |
812 | break; | |
813 | case e_fsel: | |
814 | final_type = R_HPPA_PCREL_CALL_17; | |
815 | break; | |
816 | case e_lsel: | |
817 | case e_lssel: | |
818 | case e_ldsel: | |
819 | case e_lrsel: | |
820 | default: | |
821 | UNDEFINED; | |
822 | final_type = base_type; | |
823 | break; | |
824 | } | |
825 | break; | |
826 | case 21: | |
827 | switch ( field ) { | |
828 | case e_lsel: | |
829 | final_type = R_HPPA_PCREL_CALL_L21; | |
830 | break; | |
831 | case e_lssel: | |
832 | final_type = R_HPPA_PCREL_CALL_LS21; | |
833 | break; | |
834 | case e_ldsel: | |
835 | final_type = R_HPPA_PCREL_CALL_LD21; | |
836 | break; | |
837 | case e_lrsel: | |
838 | final_type = R_HPPA_PCREL_CALL_LR21; | |
839 | break; | |
840 | case e_rsel: | |
841 | case e_rssel: | |
842 | case e_rdsel: | |
843 | case e_rrsel: | |
844 | case e_fsel: | |
845 | default: | |
846 | UNDEFINED; | |
847 | final_type = base_type; | |
848 | break; | |
849 | } | |
850 | break; | |
851 | case 32: | |
852 | UNDEFINED; | |
853 | final_type = base_type; | |
854 | break; | |
855 | default: | |
856 | UNDEFINED; | |
857 | final_type = base_type; | |
858 | break; | |
859 | } | |
860 | break; | |
861 | case R_HPPA_PLABEL: | |
862 | switch (format) { | |
863 | case 11: | |
864 | switch (field) { | |
865 | case e_fsel: | |
866 | final_type = R_HPPA_PLABEL_11; | |
867 | break; | |
868 | case e_rsel: | |
869 | final_type = R_HPPA_PLABEL_R11; | |
870 | break; | |
871 | default: | |
872 | UNDEFINED; | |
873 | final_type = base_type; | |
874 | break; | |
875 | } | |
876 | break; | |
877 | case 14: | |
878 | switch (field) { | |
879 | case e_fsel: | |
880 | final_type = R_HPPA_PLABEL_14; | |
881 | break; | |
882 | case e_rsel: | |
883 | final_type = R_HPPA_PLABEL_R14; | |
884 | break; | |
885 | default: | |
886 | UNDEFINED; | |
887 | final_type = base_type; | |
888 | break; | |
889 | } | |
890 | break; | |
891 | case 21: | |
892 | switch (field) { | |
893 | case e_lsel: | |
894 | final_type = R_HPPA_PLABEL_L21; | |
895 | break; | |
896 | default: | |
897 | UNDEFINED; | |
898 | final_type = base_type; | |
899 | break; | |
900 | } | |
901 | break; | |
902 | case 32: | |
903 | switch (field) { | |
904 | case e_fsel: | |
905 | final_type = R_HPPA_PLABEL_32; | |
906 | break; | |
907 | default: | |
908 | UNDEFINED; | |
909 | final_type = base_type; | |
910 | break; | |
911 | } | |
912 | break; | |
913 | default: | |
914 | UNDEFINED; | |
915 | final_type = base_type; | |
916 | break; | |
917 | } | |
918 | case R_HPPA_ABS_CALL: | |
919 | switch (format) { | |
920 | case 11: | |
921 | switch ( field ) { | |
922 | case e_rsel: | |
923 | final_type = R_HPPA_ABS_CALL_R11; | |
924 | break; | |
925 | case e_rssel: | |
926 | final_type = R_HPPA_ABS_CALL_RS11; | |
927 | break; | |
928 | case e_rdsel: | |
929 | final_type = R_HPPA_ABS_CALL_RD11; | |
930 | break; | |
931 | case e_fsel: | |
932 | final_type = R_HPPA_ABS_CALL_11; | |
933 | break; | |
934 | case e_lsel: | |
935 | case e_lrsel: | |
936 | case e_lssel: | |
937 | case e_rrsel: | |
938 | default: | |
939 | UNDEFINED; | |
940 | final_type = base_type; | |
941 | break; | |
942 | } | |
943 | break; | |
944 | case 12: | |
945 | UNDEFINED; | |
946 | final_type = base_type; | |
947 | break; | |
948 | case 14: | |
949 | switch ( field ) { | |
950 | case e_rsel: | |
951 | final_type = R_HPPA_ABS_CALL_R14; | |
952 | break; | |
953 | case e_rssel: | |
954 | final_type = R_HPPA_ABS_CALL_RS14; | |
955 | break; | |
956 | case e_rdsel: | |
957 | final_type = R_HPPA_ABS_CALL_RD14; | |
958 | break; | |
959 | case e_rrsel: | |
960 | final_type = R_HPPA_ABS_CALL_RR14; | |
961 | break; | |
962 | case e_fsel: | |
963 | final_type = R_HPPA_ABS_CALL_14; | |
964 | break; | |
965 | case e_lsel: | |
966 | case e_lssel: | |
967 | case e_ldsel: | |
968 | case e_lrsel: | |
969 | default: | |
970 | UNDEFINED; | |
971 | final_type = base_type; | |
972 | break; | |
973 | } | |
974 | break; | |
975 | case 17: | |
976 | switch ( field ) { | |
977 | case e_rsel: | |
978 | final_type = R_HPPA_ABS_CALL_R17; | |
979 | break; | |
980 | case e_rssel: | |
981 | final_type = R_HPPA_ABS_CALL_RS17; | |
982 | break; | |
983 | case e_rdsel: | |
984 | final_type = R_HPPA_ABS_CALL_RD17; | |
985 | break; | |
986 | case e_rrsel: | |
987 | final_type = R_HPPA_ABS_CALL_RR17; | |
988 | break; | |
989 | case e_fsel: | |
990 | final_type = R_HPPA_ABS_CALL_17; | |
991 | break; | |
992 | case e_lsel: | |
993 | case e_lssel: | |
994 | case e_ldsel: | |
995 | case e_lrsel: | |
996 | default: | |
997 | UNDEFINED; | |
998 | final_type = base_type; | |
999 | break; | |
1000 | } | |
1001 | break; | |
1002 | case 21: | |
1003 | switch ( field ) { | |
1004 | case e_lsel: | |
1005 | final_type = R_HPPA_ABS_CALL_L21; | |
1006 | break; | |
1007 | case e_lssel: | |
1008 | final_type = R_HPPA_ABS_CALL_LS21; | |
1009 | break; | |
1010 | case e_ldsel: | |
1011 | final_type = R_HPPA_ABS_CALL_LD21; | |
1012 | break; | |
1013 | case e_lrsel: | |
1014 | final_type = R_HPPA_ABS_CALL_LR21; | |
1015 | break; | |
1016 | case e_rsel: | |
1017 | case e_rssel: | |
1018 | case e_rdsel: | |
1019 | case e_rrsel: | |
1020 | case e_fsel: | |
1021 | default: | |
1022 | UNDEFINED; | |
1023 | final_type = base_type; | |
1024 | break; | |
1025 | } | |
1026 | break; | |
1027 | case 32: | |
1028 | UNDEFINED; | |
1029 | final_type = base_type; | |
1030 | break; | |
1031 | default: | |
1032 | UNDEFINED; | |
1033 | final_type = base_type; | |
1034 | break; | |
1035 | } | |
1036 | break; | |
1037 | case R_HPPA_UNWIND: | |
1038 | final_type = R_HPPA_UNWIND_ENTRY; | |
1039 | break; | |
1040 | default: | |
1041 | final_type = base_type; | |
1042 | break; | |
1043 | } | |
1044 | ||
1045 | return final_type; | |
1046 | } | |
1047 | ||
1048 | /* 12.4.4. Derive format from instruction */ | |
1049 | ||
1050 | /* Given a machine instruction, this function determines its format. */ | |
1051 | /* The format can be determined solely from looking at the first six */ | |
1052 | /* bits (the major opcode) of the instruction. Several major opcodes */ | |
1053 | /* map to the same format. Opcodes which do not map to a known format */ | |
1054 | /* should probably be reported as an error. */ | |
1055 | ||
1056 | unsigned char | |
1057 | hppa_elf_insn2fmt(type, insn) | |
1058 | elf32_hppa_reloc_type type; | |
1059 | unsigned long insn; | |
1060 | { | |
1061 | unsigned char fmt = 0; /* XXX: is this a proper default? */ | |
1062 | unsigned char op = get_opcode(insn); | |
1063 | ||
1064 | if ( type == R_HPPA_NONE ) | |
1065 | fmt = 0; | |
1066 | else { | |
1067 | switch ( op ) { | |
1068 | case ADDI: | |
1069 | case ADDIT: | |
1070 | case SUBI: | |
1071 | fmt = 11; | |
1072 | break; | |
1073 | case MOVB: | |
1074 | case MOVIB: | |
1075 | case COMBT: | |
1076 | case COMBF: | |
1077 | case COMIBT: | |
1078 | case COMIBF: | |
1079 | case ADDBT: | |
1080 | case ADDBF: | |
1081 | case ADDIBT: | |
1082 | case ADDIBF: | |
1083 | case BVB: | |
1084 | case BB: | |
1085 | fmt = 12; | |
1086 | break; | |
1087 | case LDO: | |
1088 | case LDB: | |
1089 | case LDH: | |
1090 | case LDW: | |
1091 | case LDWM: | |
1092 | case STB: | |
1093 | case STH: | |
1094 | case STW: | |
1095 | case STWM: | |
1096 | fmt = 14; | |
1097 | break; | |
1098 | case BL: | |
1099 | case BE: | |
1100 | case BLE: | |
1101 | fmt = 17; | |
1102 | break; | |
1103 | case LDIL: | |
1104 | case ADDIL: | |
1105 | fmt = 21; | |
1106 | break; | |
1107 | default: | |
1108 | fmt = 32; | |
1109 | break; | |
1110 | } | |
1111 | ||
1112 | } | |
1113 | return fmt; | |
1114 | } | |
1115 | ||
1116 | /* this function is in charge of performing all the HP PA relocations */ | |
1117 | long global_value = 0; | |
1118 | long GOT_value = 0; /* XXX: need to calculate this! For HPUX, GOT == DP */ | |
1119 | asymbol *global_symbol = (asymbol *)NULL; | |
1120 | ||
1121 | static bfd_reloc_status_type | |
1122 | DEFUN(hppa_elf_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd), | |
1123 | bfd *abfd AND | |
1124 | arelent *reloc_entry AND | |
1125 | asymbol *symbol_in AND | |
1126 | PTR data AND | |
1127 | asection *input_section AND | |
1128 | bfd *output_bfd) | |
1129 | { | |
1130 | unsigned long insn; | |
1131 | long sym_value = 0; | |
1132 | unsigned long unsigned_value; | |
1133 | long signed_value; | |
1134 | ||
1135 | unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/ | |
1136 | bfd_byte *hit_data = addr + (bfd_byte *)(data); | |
1137 | unsigned short r_type = reloc_entry->howto->type & 0xFF; | |
1138 | unsigned short r_field = e_fsel; | |
1139 | boolean r_pcrel = reloc_entry->howto->pc_relative; | |
1140 | ||
1141 | /* howto->bitsize contains the format (11, 14, 21, etc) information */ | |
1142 | unsigned r_format = reloc_entry->howto->bitsize; | |
1143 | long r_addend = reloc_entry->addend; | |
1144 | ||
1145 | ||
1146 | if (output_bfd) { | |
1147 | /* Partial linking - do nothing */ | |
1148 | reloc_entry->address += input_section->output_offset; | |
1149 | return bfd_reloc_ok; | |
1150 | } | |
1151 | ||
1152 | if ( symbol_in && symbol_in->section == &bfd_und_section ) | |
1153 | return bfd_reloc_undefined; | |
1154 | ||
1155 | sym_value = get_symbol_value(symbol_in); | |
1156 | ||
1157 | /* compute value of $global$ if it is there. */ | |
1158 | ||
1159 | if ( global_symbol == (asymbol *)NULL ) { | |
1160 | struct elf_backend_data * bed | |
1161 | = (struct elf_backend_data *)abfd->xvec->backend_data; | |
1162 | ||
1163 | if ( bed && bed->global_sym ) { | |
1164 | asymbol *gsym = &bed->global_sym->symbol; | |
1165 | global_value | |
1166 | = gsym->value | |
1167 | + gsym->section->output_section->vma | |
1168 | + gsym->section->output_offset; | |
1169 | GOT_value = global_value; /* XXX: For HP-UX, GOT==DP */ | |
1170 | global_symbol = gsym; | |
1171 | } | |
1172 | } | |
1173 | ||
1174 | /* get the instruction word */ | |
1175 | insn = bfd_get_32(abfd, hit_data); | |
1176 | ||
1177 | /* relocate the value based on the relocation type */ | |
1178 | ||
1179 | /* basic_type_1: relocation is relative to $global$ */ | |
1180 | /* basic_type_2: relocation is relative to the current GOT */ | |
1181 | /* basic_type_3: relocation is an absolute call */ | |
1182 | /* basic_type_4: relocation is an PC-relative call */ | |
1183 | /* basic_type_5: relocation is plabel reference */ | |
1184 | /* basic_type_6: relocation is an unwind table relocation */ | |
1185 | /* extended_type: unimplemented */ | |
1186 | ||
1187 | switch ( r_type ) { | |
1188 | case R_HPPA_NONE: | |
1189 | break; | |
1190 | case R_HPPA_32: /* Symbol + Addend 32 */ | |
1191 | ||
1192 | r_field = e_fsel; | |
1193 | goto do_basic_type_1; | |
1194 | case R_HPPA_L21: /* L (Symbol, Addend) 21 */ | |
1195 | r_field = e_lsel; | |
1196 | goto do_basic_type_1; | |
1197 | case R_HPPA_R11: /* R (Symbol, Addend) 11 */ | |
1198 | r_field = e_rsel; | |
1199 | goto do_basic_type_1; | |
1200 | case R_HPPA_R14: /* R (Symbol, Addend) 14 */ | |
1201 | r_field = e_rsel; | |
1202 | goto do_basic_type_1; | |
1203 | case R_HPPA_R17: /* R (Symbol, Addend) 17 */ | |
1204 | r_field = e_rsel; | |
1205 | goto do_basic_type_1; | |
1206 | case R_HPPA_LS21: /* LS(Symbol, Addend) 21 */ | |
1207 | r_field = e_lssel; | |
1208 | goto do_basic_type_1; | |
1209 | case R_HPPA_RS11: /* RS(Symbol, Addend) 11 */ | |
1210 | r_field = e_rssel; | |
1211 | goto do_basic_type_1; | |
1212 | case R_HPPA_RS14: /* RS(Symbol, Addend) 14 */ | |
1213 | r_field = e_rssel; | |
1214 | goto do_basic_type_1; | |
1215 | case R_HPPA_RS17: /* RS(Symbol, Addend) 17 */ | |
1216 | r_field = e_ldsel; | |
1217 | goto do_basic_type_1; | |
1218 | case R_HPPA_LD21: /* LD(Symbol, Addend) 21 */ | |
1219 | r_field = e_ldsel; | |
1220 | goto do_basic_type_1; | |
1221 | case R_HPPA_RD11: /* RD(Symbol, Addend) 11 */ | |
1222 | r_field = e_rdsel; | |
1223 | goto do_basic_type_1; | |
1224 | case R_HPPA_RD14: /* RD(Symbol, Addend) 14 */ | |
1225 | r_field = e_rdsel; | |
1226 | goto do_basic_type_1; | |
1227 | case R_HPPA_RD17: /* RD(Symbol, Addend) 17 */ | |
1228 | r_field = e_rdsel; | |
1229 | goto do_basic_type_1; | |
1230 | case R_HPPA_LR21: /* LR(Symbol, Addend) 21 */ | |
1231 | r_field = e_lrsel; | |
1232 | goto do_basic_type_1; | |
1233 | case R_HPPA_RR14: /* RR(Symbol, Addend) 14 */ | |
1234 | r_field = e_rrsel; | |
1235 | goto do_basic_type_1; | |
1236 | case R_HPPA_RR17: /* RR(Symbol, Addend) 17 */ | |
1237 | r_field = e_rrsel; | |
1238 | ||
1239 | do_basic_type_1: | |
1240 | insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr, | |
1241 | symbol_in, sym_value, r_addend, | |
1242 | r_type, r_format, r_field, r_pcrel); | |
1243 | break; | |
1244 | ||
1245 | case R_HPPA_GOTOFF_11: /* Symbol - GOT + Addend 11 */ | |
1246 | r_field = e_fsel; | |
1247 | goto do_basic_type_2; | |
1248 | case R_HPPA_GOTOFF_14: /* Symbol - GOT + Addend 14 */ | |
1249 | r_field = e_fsel; | |
1250 | goto do_basic_type_2; | |
1251 | case R_HPPA_GOTOFF_L21: /* L (Sym - GOT, Addend) 21 */ | |
1252 | r_field = e_lsel; | |
1253 | goto do_basic_type_2; | |
1254 | case R_HPPA_GOTOFF_R11: /* R (Sym - GOT, Addend) 11 */ | |
1255 | r_field = e_rsel; | |
1256 | goto do_basic_type_2; | |
1257 | case R_HPPA_GOTOFF_R14: /* R (Sym - GOT, Addend) 14 */ | |
1258 | r_field = e_rsel; | |
1259 | goto do_basic_type_2; | |
1260 | case R_HPPA_GOTOFF_LS21: /* LS(Sym - GOT, Addend) 21 */ | |
1261 | r_field = e_lssel; | |
1262 | goto do_basic_type_2; | |
1263 | case R_HPPA_GOTOFF_RS11: /* RS(Sym - GOT, Addend) 11 */ | |
1264 | r_field = e_rssel; | |
1265 | goto do_basic_type_2; | |
1266 | case R_HPPA_GOTOFF_RS14: /* RS(Sym - GOT, Addend) 14 */ | |
1267 | r_field = e_rssel; | |
1268 | goto do_basic_type_2; | |
1269 | case R_HPPA_GOTOFF_LD21: /* LD(Sym - GOT, Addend) 21 */ | |
1270 | r_field = e_ldsel; | |
1271 | goto do_basic_type_2; | |
1272 | case R_HPPA_GOTOFF_RD11: /* RD(Sym - GOT, Addend) 11 */ | |
1273 | r_field = e_rdsel; | |
1274 | goto do_basic_type_2; | |
1275 | case R_HPPA_GOTOFF_RD14: /* RD(Sym - GOT, Addend) 14 */ | |
1276 | r_field = e_rdsel; | |
1277 | goto do_basic_type_2; | |
1278 | case R_HPPA_GOTOFF_LR21: /* LR(Sym - GOT, Addend) 21 */ | |
1279 | r_field = e_lrsel; | |
1280 | goto do_basic_type_2; | |
1281 | case R_HPPA_GOTOFF_RR14: /* RR(Sym - GOT, Addend) 14 */ | |
1282 | r_field = e_rrsel; | |
1283 | do_basic_type_2: | |
1284 | sym_value -= GOT_value; | |
1285 | insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr, | |
1286 | symbol_in, sym_value, r_addend, | |
1287 | r_type, r_format, r_field, r_pcrel); | |
1288 | break; | |
1289 | ||
1290 | case R_HPPA_ABS_CALL_11: /* Symbol + Addend 11 */ | |
1291 | r_field = e_fsel; | |
1292 | goto do_basic_type_3; | |
1293 | case R_HPPA_ABS_CALL_14: /* Symbol + Addend 14 */ | |
1294 | r_field = e_fsel; | |
1295 | goto do_basic_type_3; | |
1296 | case R_HPPA_ABS_CALL_17: /* Symbol + Addend 17 */ | |
1297 | r_field = e_fsel; | |
1298 | goto do_basic_type_3; | |
1299 | case R_HPPA_ABS_CALL_L21: /* L (Symbol, Addend) 21 */ | |
1300 | r_field = e_lsel; | |
1301 | goto do_basic_type_3; | |
1302 | case R_HPPA_ABS_CALL_R11: /* R (Symbol, Addend) 11 */ | |
1303 | r_field = e_rsel; | |
1304 | goto do_basic_type_3; | |
1305 | case R_HPPA_ABS_CALL_R14: /* R (Symbol, Addend) 14 */ | |
1306 | r_field = e_rsel; | |
1307 | goto do_basic_type_3; | |
1308 | case R_HPPA_ABS_CALL_R17: /* R (Symbol, Addend) 17 */ | |
1309 | r_field = e_rsel; | |
1310 | goto do_basic_type_3; | |
1311 | case R_HPPA_ABS_CALL_LS21: /* LS(Symbol, Addend) 21 */ | |
1312 | r_field = e_lssel; | |
1313 | goto do_basic_type_3; | |
1314 | case R_HPPA_ABS_CALL_RS11: /* RS(Symbol, Addend) 11 */ | |
1315 | r_field = e_lssel; | |
1316 | goto do_basic_type_3; | |
1317 | case R_HPPA_ABS_CALL_RS14: /* RS(Symbol, Addend) 14 */ | |
1318 | r_field = e_rssel; | |
1319 | goto do_basic_type_3; | |
1320 | case R_HPPA_ABS_CALL_RS17: /* RS(Symbol, Addend) 17 */ | |
1321 | r_field = e_rssel; | |
1322 | goto do_basic_type_3; | |
1323 | case R_HPPA_ABS_CALL_LD21: /* LD(Symbol, Addend) 21 */ | |
1324 | r_field = e_ldsel; | |
1325 | goto do_basic_type_3; | |
1326 | case R_HPPA_ABS_CALL_RD11: /* RD(Symbol, Addend) 11 */ | |
1327 | r_field = e_rdsel; | |
1328 | goto do_basic_type_3; | |
1329 | case R_HPPA_ABS_CALL_RD14: /* RD(Symbol, Addend) 14 */ | |
1330 | r_field = e_rdsel; | |
1331 | goto do_basic_type_3; | |
1332 | case R_HPPA_ABS_CALL_RD17: /* RD(Symbol, Addend) 17 */ | |
1333 | r_field = e_rdsel; | |
1334 | goto do_basic_type_3; | |
1335 | case R_HPPA_ABS_CALL_LR21: /* LR(Symbol, Addend) 21 */ | |
1336 | r_field = e_lrsel; | |
1337 | goto do_basic_type_3; | |
1338 | case R_HPPA_ABS_CALL_RR14: /* RR(Symbol, Addend) 14 */ | |
1339 | r_field = e_rrsel; | |
1340 | goto do_basic_type_3; | |
1341 | case R_HPPA_ABS_CALL_RR17: /* RR(Symbol, Addend) 17 */ | |
1342 | r_field = e_rrsel; | |
1343 | do_basic_type_3: | |
1344 | insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr, | |
1345 | symbol_in, sym_value, r_addend, | |
1346 | r_type, r_format, r_field, r_pcrel); | |
1347 | break; | |
1348 | ||
1349 | case R_HPPA_PCREL_CALL_11: /* Symbol - PC + Addend 11 */ | |
1350 | r_field = e_fsel; | |
1351 | goto do_basic_type_4; | |
1352 | case R_HPPA_PCREL_CALL_14: /* Symbol - PC + Addend 14 */ | |
1353 | r_field = e_fsel; | |
1354 | goto do_basic_type_4; | |
1355 | case R_HPPA_PCREL_CALL_17: /* Symbol - PC + Addend 17 */ | |
1356 | r_field = e_fsel; | |
1357 | goto do_basic_type_4; | |
1358 | case R_HPPA_PCREL_CALL_L21: /* L (Symbol - PC, Addend) 21 */ | |
1359 | r_field = e_lsel; | |
1360 | goto do_basic_type_4; | |
1361 | case R_HPPA_PCREL_CALL_R11: /* R (Symbol - PC, Addend) 11 */ | |
1362 | r_field = e_rsel; | |
1363 | goto do_basic_type_4; | |
1364 | case R_HPPA_PCREL_CALL_R14: /* R (Symbol - PC, Addend) 14 */ | |
1365 | r_field = e_rsel; | |
1366 | goto do_basic_type_4; | |
1367 | case R_HPPA_PCREL_CALL_R17: /* R (Symbol - PC, Addend) 17 */ | |
1368 | r_field = e_rsel; | |
1369 | goto do_basic_type_4; | |
1370 | case R_HPPA_PCREL_CALL_LS21: /* LS(Symbol - PC, Addend) 21 */ | |
1371 | r_field = e_lssel; | |
1372 | goto do_basic_type_4; | |
1373 | case R_HPPA_PCREL_CALL_RS11: /* RS(Symbol - PC, Addend) 11 */ | |
1374 | r_field = e_rssel; | |
1375 | goto do_basic_type_4; | |
1376 | case R_HPPA_PCREL_CALL_RS14: /* RS(Symbol - PC, Addend) 14 */ | |
1377 | r_field = e_rssel; | |
1378 | goto do_basic_type_4; | |
1379 | case R_HPPA_PCREL_CALL_RS17: /* RS(Symbol - PC, Addend) 17 */ | |
1380 | r_field = e_rssel; | |
1381 | goto do_basic_type_4; | |
1382 | case R_HPPA_PCREL_CALL_LD21: /* LD(Symbol - PC, Addend) 21 */ | |
1383 | r_field = e_ldsel; | |
1384 | goto do_basic_type_4; | |
1385 | case R_HPPA_PCREL_CALL_RD11: /* RD(Symbol - PC, Addend) 11 */ | |
1386 | r_field = e_rdsel; | |
1387 | goto do_basic_type_4; | |
1388 | case R_HPPA_PCREL_CALL_RD14: /* RD(Symbol - PC, Addend) 14 */ | |
1389 | r_field = e_rdsel; | |
1390 | goto do_basic_type_4; | |
1391 | case R_HPPA_PCREL_CALL_RD17: /* RD(Symbol - PC, Addend) 17 */ | |
1392 | r_field = e_rdsel; | |
1393 | goto do_basic_type_4; | |
1394 | case R_HPPA_PCREL_CALL_LR21: /* LR(Symbol - PC, Addend) 21 */ | |
1395 | r_field = e_lrsel; | |
1396 | goto do_basic_type_4; | |
1397 | case R_HPPA_PCREL_CALL_RR14: /* RR(Symbol - PC, Addend) 14 */ | |
1398 | r_field = e_rrsel; | |
1399 | goto do_basic_type_4; | |
1400 | case R_HPPA_PCREL_CALL_RR17: /* RR(Symbol - PC, Addend) 17 */ /* #69 */ | |
1401 | r_field = e_rrsel; | |
1402 | do_basic_type_4: | |
1403 | insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr, | |
1404 | symbol_in, sym_value, r_addend, | |
1405 | r_type, r_format, r_field, r_pcrel); | |
1406 | break; | |
1407 | ||
1408 | case R_HPPA_PLABEL_32: | |
1409 | case R_HPPA_PLABEL_11: | |
1410 | case R_HPPA_PLABEL_14: | |
1411 | r_field = e_fsel; | |
1412 | goto do_basic_type_5; | |
1413 | case R_HPPA_PLABEL_L21: | |
1414 | r_field = e_lsel; | |
1415 | goto do_basic_type_5; | |
1416 | case R_HPPA_PLABEL_R11: | |
1417 | case R_HPPA_PLABEL_R14: | |
1418 | r_field = e_rsel; | |
1419 | do_basic_type_5: | |
1420 | insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr, | |
1421 | symbol_in, sym_value, r_addend, | |
1422 | r_type, r_format, r_field, r_pcrel); | |
1423 | break; | |
1424 | ||
1425 | case R_HPPA_UNWIND_ENTRY: | |
1426 | case R_HPPA_UNWIND_ENTRIES: | |
1427 | hppa_elf_relocate_unwind_table(abfd, input_section, data, addr, | |
1428 | symbol_in, sym_value, r_addend, | |
1429 | r_type, r_format, r_field, r_pcrel); | |
1430 | return (bfd_reloc_ok); | |
1431 | ||
1432 | case R_HPPA_PUSH_CONST: /* push Addend - - */ | |
1433 | case R_HPPA_PUSH_SYM: /* push Symbol - - */ | |
1434 | case R_HPPA_PUSH_GOT: /* push GOT - - */ | |
1435 | case R_HPPA_PUSH_PC: /* push PC - - */ | |
1436 | case R_HPPA_PUSH_PROC: /* push Symbol - - */ | |
1437 | case R_HPPA_PUSH_PLABEL: /* [TBD] - - */ | |
1438 | case R_HPPA_MAX: /* pop A and B, push max(B,A) - - */ | |
1439 | case R_HPPA_MIN: /* pop A and B, push min(B,A) - - */ | |
1440 | case R_HPPA_ADD: /* pop A and B, push B + A - - */ | |
1441 | case R_HPPA_SUB: /* pop A and B, push B - A - - */ | |
1442 | case R_HPPA_MULT: /* pop A and B, push B * A - - */ | |
1443 | case R_HPPA_DIV: /* pop A and B, push B / A - - */ | |
1444 | case R_HPPA_MOD: /* pop A and B, push B % A - - */ | |
1445 | case R_HPPA_AND: /* pop A and B, push B & A - - */ | |
1446 | case R_HPPA_OR: /* pop A and B, push B | A - - */ | |
1447 | case R_HPPA_XOR: /* pop A and B, push B ^ A - - */ | |
1448 | case R_HPPA_NOT: /* pop A, push ~A - - */ | |
1449 | case R_HPPA_LSHIFT: /* pop A, push A << Addend - - */ | |
1450 | case R_HPPA_ARITH_RSHIFT: /* pop A, push A >> Addend - - */ | |
1451 | case R_HPPA_LOGIC_RSHIFT: /* pop A, push A >> Addend - - */ | |
1452 | case R_HPPA_EXPR_F: /* pop A, push A + Addend L - */ | |
1453 | case R_HPPA_EXPR_L: /* pop A, push L(A,Addend) L - */ | |
1454 | case R_HPPA_EXPR_R: /* pop A, push R(A,Addend) R - */ | |
1455 | case R_HPPA_EXPR_LS: /* pop A, push LS(A,Addend) LS - */ | |
1456 | case R_HPPA_EXPR_RS: /* pop A, push RS(A,Addend) RS - */ | |
1457 | case R_HPPA_EXPR_LD: /* pop A, push LD(A,Addend) LD - */ | |
1458 | case R_HPPA_EXPR_RD: /* pop A, push RD(A,Addend) RD - */ | |
1459 | case R_HPPA_EXPR_LR: /* pop A, push LR(A,Addend) LR - */ | |
1460 | case R_HPPA_EXPR_RR: /* pop A, push RR(A,Addend) RR - */ | |
1461 | ||
1462 | case R_HPPA_EXPR_32: /* pop - 32 */ | |
1463 | case R_HPPA_EXPR_21: /* pop - 21 */ | |
1464 | case R_HPPA_EXPR_11: /* pop - 11 */ | |
1465 | case R_HPPA_EXPR_14: /* pop - 14 */ | |
1466 | case R_HPPA_EXPR_17: /* pop - 17 */ | |
1467 | case R_HPPA_EXPR_12: /* pop - 12 */ | |
1468 | fprintf(stderr, "Relocation problem: "); | |
1469 | fprintf(stderr,"Unimplemented reloc type %d, in module %s\n", | |
1470 | r_type,abfd->filename); | |
1471 | return(bfd_reloc_notsupported); | |
1472 | default: | |
1473 | fprintf(stderr,"Relocation problem : "); | |
1474 | fprintf(stderr,"Unrecognized reloc type %d, in module %s\n", | |
1475 | r_type,abfd->filename); | |
1476 | return (bfd_reloc_dangerous); | |
1477 | } | |
1478 | ||
1479 | /* update the instruction word */ | |
1480 | bfd_put_32(abfd, insn ,hit_data); | |
1481 | ||
1482 | return (bfd_reloc_ok); | |
1483 | ||
1484 | } | |
1485 | ||
1486 | static reloc_howto_type * | |
1487 | elf_hppa_reloc_type_lookup (arch, code) | |
1488 | bfd_arch_info_type *arch; | |
1489 | bfd_reloc_code_real_type code; | |
1490 | { | |
8ddd7ab3 KR |
1491 | if (code < R_HPPA_UNIMPLEMENTED) |
1492 | return &elf_hppa_howto_table[code]; | |
4c85cbfa | 1493 | |
8ddd7ab3 | 1494 | return (reloc_howto_type *)0; |
4c85cbfa | 1495 | } |
8ddd7ab3 | 1496 | #define elf_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup |
4c85cbfa | 1497 | |
8ddd7ab3 KR |
1498 | static void |
1499 | DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst), | |
1500 | bfd *abfd AND | |
1501 | arelent *cache_ptr AND | |
1502 | Elf_Internal_Rela *dst) | |
4c85cbfa | 1503 | { |
8ddd7ab3 KR |
1504 | abort (); |
1505 | } | |
4c85cbfa | 1506 | |
8ddd7ab3 KR |
1507 | #define TARGET_BIG_SYM elf32_hppa_vec |
1508 | #define TARGET_BIG_NAME "elf32-hppa" | |
1509 | #define ELF_ARCH bfd_arch_hppa | |
1510 | ||
1511 | #include "elf32-target.h" |