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