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