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