]>
Commit | Line | Data |
---|---|---|
f5bfdacd | 1 | /* ELF32/HPPA support |
7050286d | 2 | |
f5bfdacd JL |
3 | This file contains ELF32/HPPA relocation support as specified |
4 | in the Stratus FTX/Golf Object File Format (SED-1762) dated | |
5 | November 19, 1992. | |
7050286d | 6 | |
f5bfdacd | 7 | Copyright (C) 1990-1991 Free Software Foundation, Inc. |
7050286d | 8 | |
f5bfdacd | 9 | Written by: |
7050286d | 10 | |
f5bfdacd JL |
11 | Center for Software Science |
12 | Department of Computer Science | |
13 | University of Utah | |
7050286d | 14 | |
f5bfdacd | 15 | This file is part of BFD, the Binary File Descriptor library. |
7050286d | 16 | |
f5bfdacd JL |
17 | This program is free software; you can redistribute it and/or modify |
18 | it under the terms of the GNU General Public License as published by | |
19 | the Free Software Foundation; either version 2 of the License, or | |
20 | (at your option) any later version. | |
7050286d | 21 | |
f5bfdacd JL |
22 | This program is distributed in the hope that it will be useful, |
23 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | GNU General Public License for more details. | |
7050286d | 26 | |
f5bfdacd JL |
27 | You should have received a copy of the GNU General Public License |
28 | along with this program; if not, write to the Free Software | |
29 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
7050286d KR |
30 | |
31 | #ifndef _ELF32_HPPA_H | |
32 | #define _ELF32_HPPA_H | |
33 | ||
34 | #include "libelf.h" | |
4e64845c | 35 | #include "libhppa.h" |
7050286d | 36 | |
7050286d KR |
37 | /* ELF/HPPA relocation types */ |
38 | ||
7050286d KR |
39 | typedef enum |
40 | { | |
f5bfdacd JL |
41 | /* 9.3.4. Address relocation types |
42 | These relocation types do simple base + offset relocations. | |
43 | ||
44 | By convention, relocation type zero is always "no relocation", | |
45 | while type one is 32-bit word relocation. */ | |
46 | ||
47 | R_HPPA_NONE, /* - - */ | |
48 | R_HPPA_32, /* Symbol + Addend 32 */ | |
49 | R_HPPA_11, /* Symbol + Addend 11 */ | |
50 | R_HPPA_14, /* Symbol + Addend 11 */ | |
51 | R_HPPA_17, /* Symbol + Addend 11 */ | |
52 | R_HPPA_L21, /* L (Symbol, Addend) 21 */ | |
53 | R_HPPA_R11, /* R (Symbol, Addend) 11 */ | |
54 | R_HPPA_R14, /* R (Symbol, Addend) 14 */ | |
55 | R_HPPA_R17, /* R (Symbol, Addend) 17 */ | |
56 | R_HPPA_LS21, /* LS(Symbol, Addend) 21 */ | |
57 | R_HPPA_RS11, /* RS(Symbol, Addend) 11 */ | |
58 | R_HPPA_RS14, /* RS(Symbol, Addend) 14 */ | |
59 | R_HPPA_RS17, /* RS(Symbol, Addend) 17 */ | |
60 | R_HPPA_LD21, /* LD(Symbol, Addend) 21 */ | |
61 | R_HPPA_RD11, /* RD(Symbol, Addend) 11 */ | |
62 | R_HPPA_RD14, /* RD(Symbol, Addend) 14 */ | |
63 | R_HPPA_RD17, /* RD(Symbol, Addend) 17 */ | |
64 | R_HPPA_LR21, /* LR(Symbol, Addend) 21 */ | |
65 | R_HPPA_RR14, /* RR(Symbol, Addend) 14 */ | |
66 | R_HPPA_RR17, /* RR(Symbol, Addend) 17 */ | |
67 | ||
68 | /* 9.3.5. GOTOFF address relocation types | |
69 | ||
70 | The Global Offset Table (GOT) is a table of pointers to data, but | |
71 | its address can also be used as a base pointer to address data, | |
72 | similar to the way the DP is used in HP/UX. The expression | |
73 | calculation yields a signed offset of an address from the GOT. */ | |
74 | ||
75 | R_HPPA_GOTOFF_11, /* Symbol - GOT + Addend 11 */ | |
76 | R_HPPA_GOTOFF_14, /* Symbol - GOT + Addend 14 */ | |
77 | R_HPPA_GOTOFF_L21, /* L (Sym - GOT, Addend) 21 */ | |
78 | R_HPPA_GOTOFF_R11, /* R (Sym - GOT, Addend) 11 */ | |
79 | R_HPPA_GOTOFF_R14, /* R (Sym - GOT, Addend) 14 */ | |
80 | R_HPPA_GOTOFF_LS21, /* LS(Sym - GOT, Addend) 21 */ | |
81 | R_HPPA_GOTOFF_RS11, /* RS(Sym - GOT, Addend) 11 */ | |
82 | R_HPPA_GOTOFF_RS14, /* RS(Sym - GOT, Addend) 14 */ | |
83 | R_HPPA_GOTOFF_LD21, /* LD(Sym - GOT, Addend) 21 */ | |
84 | R_HPPA_GOTOFF_RD11, /* RD(Sym - GOT, Addend) 11 */ | |
85 | R_HPPA_GOTOFF_RD14, /* RD(Sym - GOT, Addend) 14 */ | |
86 | R_HPPA_GOTOFF_LR21, /* LR(Sym - GOT, Addend) 21 */ | |
87 | R_HPPA_GOTOFF_RR14, /* RR(Sym - GOT, Addend) 14 */ | |
88 | ||
89 | /* 9.3.6. Absolute call relocation types | |
90 | ||
91 | Relocations of function calls must be accompanied by parameter | |
92 | relocation information. This information is carried in the ten | |
93 | high-order bits of the addend field. The remaining 22 bits of | |
94 | of the addend field are sign-extended to form the Addend. | |
95 | ||
96 | Note the code to build argument relocations depends on the | |
97 | addend being zero. A consequence of this limitation is GAS | |
98 | can not perform relocation reductions for function symbols. */ | |
99 | ||
100 | R_HPPA_ABS_CALL_11, /* Symbol + Addend 11 */ | |
101 | R_HPPA_ABS_CALL_14, /* Symbol + Addend 14 */ | |
102 | R_HPPA_ABS_CALL_17, /* Symbol + Addend 17 */ | |
103 | R_HPPA_ABS_CALL_L21, /* L (Symbol, Addend) 21 */ | |
104 | R_HPPA_ABS_CALL_R11, /* R (Symbol, Addend) 11 */ | |
105 | R_HPPA_ABS_CALL_R14, /* R (Symbol, Addend) 14 */ | |
106 | R_HPPA_ABS_CALL_R17, /* R (Symbol, Addend) 17 */ | |
107 | R_HPPA_ABS_CALL_LS21, /* LS(Symbol, Addend) 21 */ | |
108 | R_HPPA_ABS_CALL_RS11, /* RS(Symbol, Addend) 11 */ | |
109 | R_HPPA_ABS_CALL_RS14, /* RS(Symbol, Addend) 14 */ | |
110 | R_HPPA_ABS_CALL_RS17, /* RS(Symbol, Addend) 17 */ | |
111 | R_HPPA_ABS_CALL_LD21, /* LD(Symbol, Addend) 21 */ | |
112 | R_HPPA_ABS_CALL_RD11, /* RD(Symbol, Addend) 11 */ | |
113 | R_HPPA_ABS_CALL_RD14, /* RD(Symbol, Addend) 14 */ | |
114 | R_HPPA_ABS_CALL_RD17, /* RD(Symbol, Addend) 17 */ | |
115 | R_HPPA_ABS_CALL_LR21, /* LR(Symbol, Addend) 21 */ | |
116 | R_HPPA_ABS_CALL_RR14, /* RR(Symbol, Addend) 14 */ | |
117 | R_HPPA_ABS_CALL_RR17, /* RR(Symbol, Addend) 17 */ | |
118 | ||
119 | /* 9.3.7. PC-relative call relocation types | |
120 | ||
121 | PC-relative relocation calculates the difference between an address | |
122 | and the location being relocated. This is most often used to | |
123 | relocate pc-relative calls. They are otherwise identical to | |
124 | their corresponding absolute call relocations. */ | |
125 | ||
126 | R_HPPA_PCREL_CALL_11, /* Symbol - PC + Addend 11 */ | |
127 | R_HPPA_PCREL_CALL_14, /* Symbol - PC + Addend 14 */ | |
128 | R_HPPA_PCREL_CALL_17, /* Symbol - PC + Addend 17 */ | |
129 | R_HPPA_PCREL_CALL_12, /* Symbol - PC + Addend 12 */ | |
130 | R_HPPA_PCREL_CALL_L21, /* L (Symbol - PC, Addend) 21 */ | |
131 | R_HPPA_PCREL_CALL_R11, /* R (Symbol - PC, Addend) 11 */ | |
132 | R_HPPA_PCREL_CALL_R14, /* R (Symbol - PC, Addend) 14 */ | |
133 | R_HPPA_PCREL_CALL_R17, /* R (Symbol - PC, Addend) 17 */ | |
134 | R_HPPA_PCREL_CALL_LS21, /* LS(Symbol - PC, Addend) 21 */ | |
135 | R_HPPA_PCREL_CALL_RS11, /* RS(Symbol - PC, Addend) 11 */ | |
136 | R_HPPA_PCREL_CALL_RS14, /* RS(Symbol - PC, Addend) 14 */ | |
137 | R_HPPA_PCREL_CALL_RS17, /* RS(Symbol - PC, Addend) 17 */ | |
138 | R_HPPA_PCREL_CALL_LD21, /* LD(Symbol - PC, Addend) 21 */ | |
139 | R_HPPA_PCREL_CALL_RD11, /* RD(Symbol - PC, Addend) 11 */ | |
140 | R_HPPA_PCREL_CALL_RD14, /* RD(Symbol - PC, Addend) 14 */ | |
141 | R_HPPA_PCREL_CALL_RD17, /* RD(Symbol - PC, Addend) 17 */ | |
142 | R_HPPA_PCREL_CALL_LR21, /* LR(Symbol - PC, Addend) 21 */ | |
143 | R_HPPA_PCREL_CALL_RR14, /* RR(Symbol - PC, Addend) 14 */ | |
144 | R_HPPA_PCREL_CALL_RR17, /* RR(Symbol - PC, Addend) 17 */ | |
145 | ||
146 | /* 9.3.8. Plabel relocation types | |
147 | ||
148 | Plabels are designed to allow code pointers to be passed between | |
149 | spaces. | |
150 | ||
151 | Plabels are procedure markers. They are used to denote relocations | |
152 | which involve procedures (call, loading the address of a procedure, | |
153 | etc). They are necessary for the proper functioning of argument | |
154 | relocations. The addend of the relocation should be either 0 (no | |
155 | static link) or 2 (static link required). These relocations | |
156 | correspond to the P%, LP% and RP% field selectors. */ | |
157 | ||
158 | R_HPPA_PLABEL_32, /* F(Plabel(Symbol,Addend),0) 32 */ | |
159 | R_HPPA_PLABEL_11, /* F(Plabel(Symbol,Addend),0) 11 */ | |
160 | R_HPPA_PLABEL_14, /* F(Plabel(Symbol,Addend),0) 14 */ | |
161 | R_HPPA_PLABEL_L21, /* L(Plabel(Symbol,Addend),0) 21 */ | |
162 | R_HPPA_PLABEL_R11, /* R(Plabel(Symbol,Addend),0) 11 */ | |
163 | R_HPPA_PLABEL_R14, /* R(Plabel(Symbol,Addend),0) 14 */ | |
164 | ||
165 | /* 9.3.9. Data linkage table (DLT) relocation types | |
166 | ||
167 | SOM DLT_REL fixup requests are used to for static data references | |
168 | from position-independent code within shared libraries. They are | |
169 | similar to the GOT relocation types in some SVR4 implementations. */ | |
170 | ||
171 | R_HPPA_DLT_32, /* F(DLTOFF) 32 */ | |
172 | R_HPPA_DLT_11, /* F(DLTOFF) 11 */ | |
173 | R_HPPA_DLT_14, /* F(DLTOFF) 14 */ | |
174 | R_HPPA_DLT_L21, /* L(DLTOFF) 21 */ | |
175 | R_HPPA_DLT_R11, /* R(DLTOFF) 11 */ | |
176 | R_HPPA_DLT_R14, /* R(DLTOFF) 14 */ | |
177 | ||
178 | /* 9.3.10. Relocations for unwinder tables | |
179 | ||
180 | The unwinder table consists of a series of four-word entries, the | |
181 | first two of which are a pair of code addresses. While it would be | |
182 | possible to relocate this table using just R_HPPA_32, the amount of | |
183 | relocation data resulting would be very large. To reduce that data, | |
184 | the following relocation types have been defined. | |
185 | ||
186 | The first, R_HPPA_UNWIND_ENTRY, merely compresses two R_HPPA_32 | |
187 | operations into one. It is designed for use in .rel-type | |
188 | relocations, where the two 32-bit addends are taken from the unwind | |
189 | section itself. | |
190 | ||
191 | The second, which is designed for use in .rela-type relocations, is | |
192 | designed to relocate an entire unwinder table with one relocation | |
193 | entry. It has the effect of multiple R_HPPA_UNWIND_ENTRY | |
194 | relocations applied to successive unwinder table entries. The | |
195 | number of entries to be relocated is given in the r_addend field of | |
196 | the relocation entry. The rest of the relocation entry is used in | |
197 | a normal way--r_offset is the offset of the first unwind entry in | |
198 | the section, while ELF32_R_SYM(r_info) is the code section that all | |
199 | the code addresses should be relocated from. | |
200 | ||
201 | Why can't we use begin/end markers + unwind description bits like | |
202 | som? FIXME! */ | |
203 | ||
204 | R_HPPA_UNWIND_ENTRY, /* "128" */ | |
205 | R_HPPA_UNWIND_ENTRIES, /* Addend * "128" */ | |
206 | ||
207 | /* 9.3.11. Relocation types for complex expressions | |
208 | ||
209 | New-format SOM fixups support complex expressions by spreading | |
210 | the parts of the expression across multiple entries. ELF for | |
211 | HPPA will have a similar mechanism, although support for it may | |
212 | be optional. There are two main reasons for defining it: first, | |
213 | the need to translate complex SOM fixup expressions to ELF, and | |
214 | second, to cover combinations of expression, field and format not | |
215 | available with other relocation types. | |
216 | ||
217 | ELF expression relocation entries are interpreted as postfix-form | |
218 | expressions. They may be evaluated using a push-down stack. | |
219 | ||
220 | Usually, the addend field of these expression relocation entries is | |
221 | unused, with the following exceptions: | |
222 | ||
223 | R_HPPA_PUSH_CONST: The addend field contains the constant. | |
224 | ||
225 | R_HPPA_PUSH_PROC: The high-order 10 bits of the addend field | |
226 | contain parameter relocation information. The rest ofthe addend | |
227 | field is unused. | |
228 | ||
229 | R_HPPA_LSHIFT, R_HPPA_ARITH_RSHIFT and R_HPPA_LOGIC_RSHIFT: | |
230 | The addend field normally gives the amount to shift. | |
231 | However, if that amount is zero, the shift amount is | |
232 | popped from the top of the stack prior to popping the | |
233 | amount to be shifted. */ | |
234 | ||
235 | R_HPPA_PUSH_CONST, /* push Addend - - */ | |
236 | R_HPPA_PUSH_PC, /* push PC + Addend - - */ | |
237 | R_HPPA_PUSH_SYM, /* push Symbol + Addend - - */ | |
238 | R_HPPA_PUSH_GOTOFF, /* push Symbol - GOT + Addend - - */ | |
239 | R_HPPA_PUSH_ABS_CALL, /* push Symbol + Addend - - */ | |
240 | R_HPPA_PUSH_PCREL_CALL, /* push Symbol - PC + Addend - - */ | |
241 | R_HPPA_PUSH_PLABEL, /* push Plabel(Symbol) - - */ | |
242 | R_HPPA_MAX, /* pop A and B, push max(B,A) - - */ | |
243 | R_HPPA_MIN, /* pop A and B, push min(B,A) - - */ | |
244 | R_HPPA_ADD, /* pop A and B, push B + A - - */ | |
245 | R_HPPA_SUB, /* pop A and B, push B - A - - */ | |
246 | R_HPPA_MULT, /* pop A and B, push B * A - - */ | |
247 | R_HPPA_DIV, /* pop A and B, push B / A - - */ | |
248 | R_HPPA_MOD, /* pop A and B, push B % A - - */ | |
249 | R_HPPA_AND, /* pop A and B, push B & A - - */ | |
250 | R_HPPA_OR, /* pop A and B, push B | A - - */ | |
251 | R_HPPA_XOR, /* pop A and B, push B ^ A - - */ | |
252 | R_HPPA_NOT, /* pop A, push ~A - - */ | |
253 | R_HPPA_LSHIFT, /* pop A, push A << Addend - - */ | |
254 | R_HPPA_ARITH_RSHIFT, /* pop A, push A >> Addend - - */ | |
255 | R_HPPA_LOGIC_RSHIFT, /* pop A, push A >> Addend - - */ | |
256 | R_HPPA_EXPR_F, /* pop A, push A + Addend F - */ | |
257 | R_HPPA_EXPR_L, /* pop A, push L(A,Addend) L - */ | |
258 | R_HPPA_EXPR_R, /* pop A, push R(A,Addend) R - */ | |
259 | R_HPPA_EXPR_LS, /* pop A, push LS(A,Addend) LS - */ | |
260 | R_HPPA_EXPR_RS, /* pop A, push RS(A,Addend) RS - */ | |
261 | R_HPPA_EXPR_LD, /* pop A, push LD(A,Addend) LD - */ | |
262 | R_HPPA_EXPR_RD, /* pop A, push RD(A,Addend) RD - */ | |
263 | R_HPPA_EXPR_LR, /* pop A, push LR(A,Addend) LR - */ | |
264 | R_HPPA_EXPR_RR, /* pop A, push RR(A,Addend) RR - */ | |
265 | R_HPPA_EXPR_32, /* pop - 32 */ | |
266 | R_HPPA_EXPR_21, /* pop - 21 */ | |
267 | R_HPPA_EXPR_11, /* pop - 11 */ | |
268 | R_HPPA_EXPR_14, /* pop - 14 */ | |
269 | R_HPPA_EXPR_17, /* pop - 17 */ | |
270 | R_HPPA_EXPR_12, /* pop - 12 */ | |
271 | R_HPPA_STUB_CALL_17, /* Symbol + Addend - 17 */ | |
272 | R_HPPA_UNIMPLEMENTED /* N/A */ | |
273 | } | |
274 | elf32_hppa_reloc_type; | |
7050286d KR |
275 | |
276 | #define ELF_HOWTO_TABLE_SIZE R_HPPA_UNIMPLEMENTED + 1 | |
277 | #define N_HPPA_RELOCS R_HPPA_UNIMPLEMENTED + 1 | |
278 | ||
f5bfdacd JL |
279 | /* Define groups of basic relocations. FIXME: These should |
280 | be the only basic relocations created by GAS. The rest | |
281 | should be internal to the BFD backend. | |
282 | ||
283 | The idea is both SOM and ELF define these basic relocation | |
284 | types so they map into a SOM or ELF specific relocation | |
285 | as appropriate. This allows GAS to share much more code | |
286 | between the two target object formats. */ | |
287 | ||
288 | #define R_HPPA R_HPPA_32 | |
289 | #define R_HPPA_GOTOFF R_HPPA_GOTOFF_11 | |
290 | #define R_HPPA_ABS_CALL R_HPPA_ABS_CALL_11 | |
291 | #define R_HPPA_PCREL_CALL R_HPPA_PCREL_CALL_11 | |
292 | #define R_HPPA_PLABEL R_HPPA_PLABEL_32 | |
293 | #define R_HPPA_DLT R_HPPA_DLT_32 | |
294 | #define R_HPPA_UNWIND R_HPPA_UNWIND_ENTRY | |
7050286d KR |
295 | #define R_HPPA_COMPLEX R_HPPA_PUSH_CONST |
296 | #define R_HPPA_COMPLEX_PCREL_CALL R_HPPA_PUSH_CONST + 1 | |
297 | #define R_HPPA_COMPLEX_ABS_CALL R_HPPA_PUSH_CONST + 2 | |
298 | ||
f5bfdacd | 299 | /* HPPA Section types */ |
7050286d KR |
300 | #define SHT_HPPA_SYMEXTN SHT_LOPROC |
301 | ||
f5bfdacd | 302 | /* HPPA Symbol types */ |
7050286d KR |
303 | #define STT_HPPA_PLABEL STT_LOPROC |
304 | ||
f5bfdacd JL |
305 | /* HPPA symbol table extension entry types */ |
306 | enum elf32_hppa_symextn_types | |
307 | { | |
308 | HPPA_SXT_NULL, | |
309 | HPPA_SXT_SYMNDX, | |
310 | HPPA_SXT_ARG_RELOC, | |
311 | }; | |
7050286d | 312 | |
f5bfdacd JL |
313 | /* These macros compose and decompose the value of a symextn entry: |
314 | ||
315 | entry_type = ELF32_HPPA_SX_TYPE(word); | |
316 | entry_value = ELF32_HPPA_SX_VAL(word); | |
317 | word = ELF32_HPPA_SX_WORD(type,val); */ | |
7050286d KR |
318 | |
319 | #define ELF32_HPPA_SX_TYPE(p) ((p) >> 24) | |
320 | #define ELF32_HPPA_SX_VAL(p) ((p) & 0xFFFFFF) | |
321 | #define ELF32_HPPA_SX_WORD(type,val) (((type) << 24) + (val & 0xFFFFFF)) | |
322 | ||
323 | /* The following was added facilitate implementation of the .hppa_symextn | |
324 | section. This section is built after the symbol table is built in the | |
325 | elf_write_object_contents routine (called from bfd_close). It is built | |
326 | so late because it requires information that is not known until | |
327 | the symbol and string table sections have been allocated, and | |
328 | the symbol table has been built. */ | |
329 | ||
f5bfdacd JL |
330 | /* Number of "hand-made" target specific sections. */ |
331 | #define ELF_TC_FAKE_SECTIONS 1 | |
7050286d KR |
332 | #define SYMEXTN_SECTION_NAME ".hppa_symextn" |
333 | ||
f5bfdacd JL |
334 | /* FIXME. Are these external? (For example used by GAS?). If so the |
335 | names need to change to avoid namespace pollution, if not they should | |
336 | be moved into elf32-hppa.c. */ | |
25677b5b | 337 | typedef unsigned long symext_entryS; |
7050286d | 338 | struct symext_chain |
f5bfdacd JL |
339 | { |
340 | symext_entryS entry; | |
341 | struct symext_chain *next; | |
342 | }; | |
7050286d KR |
343 | |
344 | typedef struct symext_chain symext_chainS; | |
345 | ||
e08b9ad7 JL |
346 | void elf_hppa_tc_symbol |
347 | PARAMS ((bfd *, elf_symbol_type *, int, symext_chainS **, symext_chainS **)); | |
348 | ||
349 | elf32_hppa_reloc_type **hppa_elf_gen_reloc_type | |
350 | PARAMS ((bfd *, elf32_hppa_reloc_type, int, int)); | |
351 | ||
6e58a4e5 JL |
352 | asymbol * hppa_look_for_stubs_in_section |
353 | PARAMS ((bfd *, bfd *, bfd *, asection *, | |
e08b9ad7 JL |
354 | int *, struct bfd_link_info *)); |
355 | ||
f5bfdacd | 356 | void elf_hppa_final_processing PARAMS ((void)); |
e08b9ad7 | 357 | void elf_hppa_tc_make_sections PARAMS ((bfd *, symext_chainS *)); |
f5bfdacd | 358 | |
7050286d | 359 | #endif /* _ELF32_HPPA_H */ |