1 /* ELF32/HPPA relocation support
3 This file contains ELF32/HPPA relocation support as specified
4 in the Stratus FTX/Golf Object File Format (SED-1762) dated
10 Copyright (C) 1990-1991 Free Software Foundation, Inc.
14 Center for Software Science
15 Department of Computer Science
18 This file is part of BFD, the Binary File Descriptor library.
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
25 This program is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
39 /* 9.3.3. Parameter relocation information */
41 /* As mentioned previously, relocations of calls must be accompanied */
42 /* by parameter relocation information, indicating which registers the */
43 /* first for parameter words, and the return value, are located in. */
44 /* This information accompanies the R_HPPA_ABS_CALL.., */
45 /* R_HPPA_PCREL_CALL... and R_HPPA_PUSH_PROC relocation types, */
46 /* described below. The information is kept in the high-order 10 bits */
47 /* of Elf32_rela.r_addend, while the low-order 22 bits are a signed */
48 /* constant to be used in calculating the call target. The following */
49 /* macros are used to extract and combine these data in r_addend. */
51 #define ELF32_HPPA_R_ARG_RELOC(a) (((a) >> 22) & 0x3FF)
52 #define ELF32_HPPA_R_CONSTANT(a) ((((Elf32_Sword)(a)) << 10) >> 10)
53 #define ELF32_HPPA_R_ADDEND(r,c) (((r) << 22) + ((c) & 0x3FFFFF))
55 /* ELF/HPPA relocation types */
57 /* name expression format */
58 /* -------------------------------------------------------------- */
61 /* 9.3.4. Address relocation types */
63 /* These relocation types do simple base+offset relocations, and are */
64 /* normally used for absolute references to data. */
66 /* By convention, relocation type zero is always "no relocation", */
67 /* while type one is 32-bit word relocation. */
69 R_HPPA_NONE, /* - - */
71 R_HPPA_32, /* Symbol + Addend 32 */
72 R_HPPA_11, /* Symbol + Addend 11 */
73 R_HPPA_14, /* Symbol + Addend 11 */
74 R_HPPA_17, /* Symbol + Addend 11 */
75 R_HPPA_L21, /* L (Symbol, Addend) 21 */
76 R_HPPA_R11, /* R (Symbol, Addend) 11 */
77 R_HPPA_R14, /* R (Symbol, Addend) 14 */
78 R_HPPA_R17, /* R (Symbol, Addend) 17 */
79 R_HPPA_LS21, /* LS(Symbol, Addend) 21 */
80 R_HPPA_RS11, /* RS(Symbol, Addend) 11 */
81 R_HPPA_RS14, /* RS(Symbol, Addend) 14 */
82 R_HPPA_RS17, /* RS(Symbol, Addend) 17 */
83 R_HPPA_LD21, /* LD(Symbol, Addend) 21 */
84 R_HPPA_RD11, /* RD(Symbol, Addend) 11 */
85 R_HPPA_RD14, /* RD(Symbol, Addend) 14 */
86 R_HPPA_RD17, /* RD(Symbol, Addend) 17 */
87 R_HPPA_LR21, /* LR(Symbol, Addend) 21 */
88 R_HPPA_RR14, /* RR(Symbol, Addend) 14 */
89 R_HPPA_RR17, /* RR(Symbol, Addend) 17 */
91 /* 9.3.5. GOTOFF address relocation types */
93 /* The Global Offset Table (GOT) is a table of pointers to data, but */
94 /* its address can also be used as a base pointer to address data, */
95 /* similar to the way the DP is used in HP/UX. The expression */
96 /* calculation yields a signed offset of an address from the GOT. */
98 R_HPPA_GOTOFF_11, /* Symbol - GOT + Addend 11 */
99 R_HPPA_GOTOFF_14, /* Symbol - GOT + Addend 14 */
100 R_HPPA_GOTOFF_L21, /* L (Sym - GOT, Addend) 21 */
101 R_HPPA_GOTOFF_R11, /* R (Sym - GOT, Addend) 11 */
102 R_HPPA_GOTOFF_R14, /* R (Sym - GOT, Addend) 14 */
103 R_HPPA_GOTOFF_LS21, /* LS(Sym - GOT, Addend) 21 */
104 R_HPPA_GOTOFF_RS11, /* RS(Sym - GOT, Addend) 11 */
105 R_HPPA_GOTOFF_RS14, /* RS(Sym - GOT, Addend) 14 */
106 R_HPPA_GOTOFF_LD21, /* LD(Sym - GOT, Addend) 21 */
107 R_HPPA_GOTOFF_RD11, /* RD(Sym - GOT, Addend) 11 */
108 R_HPPA_GOTOFF_RD14, /* RD(Sym - GOT, Addend) 14 */
109 R_HPPA_GOTOFF_LR21, /* LR(Sym - GOT, Addend) 21 */
110 R_HPPA_GOTOFF_RR14, /* RR(Sym - GOT, Addend) 14 */
112 /* 9.3.6. Absolute call relocation types */
114 /* Relocations of function calls must be accompanied by parameter */
115 /* relocation information. This information is carried in the ten */
116 /* high-order bits of the addend field. The remaining 22 bits of */
117 /* of the addend field are sign-extended to form the Addend. */
119 R_HPPA_ABS_CALL_11, /* Symbol + Addend 11 */
120 R_HPPA_ABS_CALL_14, /* Symbol + Addend 14 */
121 R_HPPA_ABS_CALL_17, /* Symbol + Addend 17 */
122 R_HPPA_ABS_CALL_L21, /* L (Symbol, Addend) 21 */
123 R_HPPA_ABS_CALL_R11, /* R (Symbol, Addend) 11 */
124 R_HPPA_ABS_CALL_R14, /* R (Symbol, Addend) 14 */
125 R_HPPA_ABS_CALL_R17, /* R (Symbol, Addend) 17 */
126 R_HPPA_ABS_CALL_LS21, /* LS(Symbol, Addend) 21 */
127 R_HPPA_ABS_CALL_RS11, /* RS(Symbol, Addend) 11 */
128 R_HPPA_ABS_CALL_RS14, /* RS(Symbol, Addend) 14 */
129 R_HPPA_ABS_CALL_RS17, /* RS(Symbol, Addend) 17 */
130 R_HPPA_ABS_CALL_LD21, /* LD(Symbol, Addend) 21 */
131 R_HPPA_ABS_CALL_RD11, /* RD(Symbol, Addend) 11 */
132 R_HPPA_ABS_CALL_RD14, /* RD(Symbol, Addend) 14 */
133 R_HPPA_ABS_CALL_RD17, /* RD(Symbol, Addend) 17 */
134 R_HPPA_ABS_CALL_LR21, /* LR(Symbol, Addend) 21 */
135 R_HPPA_ABS_CALL_RR14, /* RR(Symbol, Addend) 14 */
136 R_HPPA_ABS_CALL_RR17, /* RR(Symbol, Addend) 17 */
138 /* 9.3.7. PC-relative call relocation types */
140 /* PC-relative relocation calculates the difference between an address */
141 /* and the location being relocated. This is most often used to */
142 /* relocate pc-relative calls. */
144 /* As with the ABS_CALL relocation types, the ten high-order bits of */
145 /* the addend field carry parameter relocation information, while */
146 /* the low-order 22 bits are sign-extended to form the Addend. */
148 R_HPPA_PCREL_CALL_11, /* Symbol - PC + Addend 11 */
149 R_HPPA_PCREL_CALL_14, /* Symbol - PC + Addend 14 */
150 R_HPPA_PCREL_CALL_17, /* Symbol - PC + Addend 17 */
151 R_HPPA_PCREL_CALL_12, /* Symbol - PC + Addend 12 */
152 R_HPPA_PCREL_CALL_L21, /* L (Symbol - PC, Addend) 21 */
153 R_HPPA_PCREL_CALL_R11, /* R (Symbol - PC, Addend) 11 */
154 R_HPPA_PCREL_CALL_R14, /* R (Symbol - PC, Addend) 14 */
155 R_HPPA_PCREL_CALL_R17, /* R (Symbol - PC, Addend) 17 */
156 R_HPPA_PCREL_CALL_LS21, /* LS(Symbol - PC, Addend) 21 */
157 R_HPPA_PCREL_CALL_RS11, /* RS(Symbol - PC, Addend) 11 */
158 R_HPPA_PCREL_CALL_RS14, /* RS(Symbol - PC, Addend) 14 */
159 R_HPPA_PCREL_CALL_RS17, /* RS(Symbol - PC, Addend) 17 */
160 R_HPPA_PCREL_CALL_LD21, /* LD(Symbol - PC, Addend) 21 */
161 R_HPPA_PCREL_CALL_RD11, /* RD(Symbol - PC, Addend) 11 */
162 R_HPPA_PCREL_CALL_RD14, /* RD(Symbol - PC, Addend) 14 */
163 R_HPPA_PCREL_CALL_RD17, /* RD(Symbol - PC, Addend) 17 */
164 R_HPPA_PCREL_CALL_LR21, /* LR(Symbol - PC, Addend) 21 */
165 R_HPPA_PCREL_CALL_RR14, /* RR(Symbol - PC, Addend) 14 */
166 R_HPPA_PCREL_CALL_RR17, /* RR(Symbol - PC, Addend) 17 *//* #69 */
168 /* 9.3.8. Plabel relocation types */
170 /* Plabels are designed to allow code pointers to be passed between */
171 /* spaces. The addend of the relocation should be either 0 (no static */
172 /* link) or 2 (static link required). These relocations correspond to */
173 /* the P%, LP% and RP% field selectors. [Description is incomplete] */
175 R_HPPA_PLABEL_32, /* F(Plabel(Symbol,Addend),0) 32 */
176 R_HPPA_PLABEL_11, /* F(Plabel(Symbol,Addend),0) 11 */
177 R_HPPA_PLABEL_14, /* F(Plabel(Symbol,Addend),0) 14 */
178 R_HPPA_PLABEL_L21, /* L(Plabel(Symbol,Addend),0) 21 */
179 R_HPPA_PLABEL_R11, /* R(Plabel(Symbol,Addend),0) 11 */
180 R_HPPA_PLABEL_R14, /* R(Plabel(Symbol,Addend),0) 14 */
182 /* 9.3.9. Data linkage table (DLT) relocation types */
184 /* SOM DLT_REL fixup requests are used to for static data references */
185 /* from position-independent code within shared libraries. They are */
186 /* similar to the GOT relocation types in some SVR4 implementations. */
187 /* [Prose to come] */
189 R_HPPA_DLT_32, /* F(DLTOFF) 32 */
190 R_HPPA_DLT_11, /* F(DLTOFF) 11 */
191 R_HPPA_DLT_14, /* F(DLTOFF) 14 */
192 R_HPPA_DLT_L21, /* L(DLTOFF) 21 */
193 R_HPPA_DLT_R11, /* R(DLTOFF) 11 */
194 R_HPPA_DLT_R14, /* R(DLTOFF) 14 */
196 /* 9.3.10. Relocations for unwinder tables */
198 /* As described above, the unwinder table consists of a series of */
199 /* four-word entries, the first two of which are a pair of code */
200 /* addresses. While it would be possible to relocate this table using */
201 /* just R_HPPA_32, the amount of relocation data resulting would be */
202 /* very large. To reduce that data, the following relocation types */
203 /* have been defined. */
205 /* The first, R_HPPA_UNWIND_ENTRY, merely compresses two R_HPPA_32 */
206 /* operations into one. It is designed for use in .rel-type */
207 /* relocations, where the two 32-bit addends are taken from the unwind */
208 /* section itself. */
210 /* The second, which is designed for use in .rela-type relocations, is */
211 /* designed to relocate an entire unwinder table with one relocation */
212 /* entry. It has the effect of multiple R_HPPA_UNWIND_ENTRY */
213 /* relocations applied to successive unwinder table entries. The */
214 /* number of entries to be relocated is given in the r_addend field of */
215 /* the relocation entry. The rest of the relocation entry is used in */
216 /* a normal way--r_offset is the offset of the first unwind entry in */
217 /* the section, while ELF32_R_SYM(r_info) is the code section that all */
218 /* the code addresses should be relocated from. */
220 R_HPPA_UNWIND_ENTRY, /* "128" */
221 R_HPPA_UNWIND_ENTRIES, /* Addend * "128" */
223 /* 9.3.11. Relocation types for complex expressions */
225 /* As described above, new-format SOM fixups support complex */
226 /* expressions by spreading the parts of the expression across */
227 /* multiple entries. ELF for HPPA will have a similar mechanism, */
228 /* although support for it may be optional. There are two main */
229 /* reasons for defining it: first, the need to translate complex */
230 /* SOM fixup expressions to ELF, and second, to cover combinations */
231 /* of expression, field and format not available with other */
232 /* relocation types. */
234 /* ELF expression relocation entries are interpreted as postfix-form */
235 /* expressions. They may be evaluated using a push-down stack. */
237 /* Usually, the addend field of these expression relocation entries is */
238 /* unused, with the following exceptions: */
240 /* R_HPPA_PUSH_CONST: The addend field contains the constant. */
242 /* R_HPPA_PUSH_PROC: The high-order 10 bits of the addend field */
243 /* contain parameter relocation information. The rest of */
244 /* the addend field is unused. */
246 /* R_HPPA_LSHIFT, R_HPPA_ARITH_RSHIFT and R_HPPA_LOGIC_RSHIFT: */
247 /* The addend field normally gives the amount to shift. */
248 /* However, if that amount is zero, the shift amount is */
249 /* popped from the top of the stack prior to popping the */
250 /* amount to be shifted. */
252 /* name expression fld/fmt */
253 /* ------------------------------------------------------------------- */
254 R_HPPA_PUSH_CONST, /* push Addend - - */
255 R_HPPA_PUSH_PC, /* push PC + Addend - - */
256 R_HPPA_PUSH_SYM, /* push Symbol + Addend - - */
257 R_HPPA_PUSH_GOTOFF, /* push Symbol - GOT + Addend - - */
258 R_HPPA_PUSH_ABS_CALL, /* push Symbol + Addend - - */
259 R_HPPA_PUSH_PCREL_CALL, /* push Symbol - PC + Addend - - */
260 R_HPPA_PUSH_PLABEL, /* push Plabel(Symbol) - - */
261 R_HPPA_MAX, /* pop A and B, push max(B,A) - - */
262 R_HPPA_MIN, /* pop A and B, push min(B,A) - - */
263 R_HPPA_ADD, /* pop A and B, push B + A - - */
264 R_HPPA_SUB, /* pop A and B, push B - A - - */
265 R_HPPA_MULT, /* pop A and B, push B * A - - */
266 R_HPPA_DIV, /* pop A and B, push B / A - - */
267 R_HPPA_MOD, /* pop A and B, push B % A - - */
268 R_HPPA_AND, /* pop A and B, push B & A - - */
269 R_HPPA_OR, /* pop A and B, push B | A - - */
270 R_HPPA_XOR, /* pop A and B, push B ^ A - - */
271 R_HPPA_NOT, /* pop A, push ~A - - */
272 R_HPPA_LSHIFT, /* pop A, push A << Addend - - */
273 R_HPPA_ARITH_RSHIFT, /* pop A, push A >> Addend - - */
274 R_HPPA_LOGIC_RSHIFT, /* pop A, push A >> Addend - - */
275 R_HPPA_EXPR_F, /* pop A, push A + Addend F - */
276 R_HPPA_EXPR_L, /* pop A, push L(A,Addend) L - */
277 R_HPPA_EXPR_R, /* pop A, push R(A,Addend) R - */
278 R_HPPA_EXPR_LS, /* pop A, push LS(A,Addend) LS - */
279 R_HPPA_EXPR_RS, /* pop A, push RS(A,Addend) RS - */
280 R_HPPA_EXPR_LD, /* pop A, push LD(A,Addend) LD - */
281 R_HPPA_EXPR_RD, /* pop A, push RD(A,Addend) RD - */
282 R_HPPA_EXPR_LR, /* pop A, push LR(A,Addend) LR - */
283 R_HPPA_EXPR_RR, /* pop A, push RR(A,Addend) RR - */
285 R_HPPA_EXPR_32, /* pop - 32 */
286 R_HPPA_EXPR_21, /* pop - 21 */
287 R_HPPA_EXPR_11, /* pop - 11 */
288 R_HPPA_EXPR_14, /* pop - 14 */
289 R_HPPA_EXPR_17, /* pop - 17 */
290 R_HPPA_EXPR_12, /* pop - 12 */
291 R_HPPA_UNIMPLEMENTED /* N/A */
292 } elf32_hppa_reloc_type;
294 #define ELF_HOWTO_TABLE_SIZE R_HPPA_UNIMPLEMENTED + 1
295 #define N_HPPA_RELOCS R_HPPA_UNIMPLEMENTED + 1
297 /* Groups of relocations. Serves as an expression type. */
299 #define R_HPPA R_HPPA_32
300 #define R_HPPA_GOTOFF R_HPPA_GOTOFF_11
301 #define R_HPPA_ABS_CALL R_HPPA_ABS_CALL_11
302 #define R_HPPA_PCREL_CALL R_HPPA_PCREL_CALL_11
303 #define R_HPPA_PLABEL R_HPPA_PLABEL_32
304 #define R_HPPA_DLT R_HPPA_DLT_32
305 #define R_HPPA_UNWIND R_HPPA_UNWIND_ENTRY
306 #define R_HPPA_COMPLEX R_HPPA_PUSH_CONST
307 #define R_HPPA_COMPLEX_PCREL_CALL R_HPPA_PUSH_CONST + 1
308 #define R_HPPA_COMPLEX_ABS_CALL R_HPPA_PUSH_CONST + 2
311 enum hppa_reloc_field_selector_type
322 R_HPPA_PSEL = 0x9, /* P' : procedure address for shlib's */
323 R_HPPA_LPSEL = 0xa, /* LP' : L' for procedure addresses */
324 R_HPPA_RPSEL = 0xb, /* RP' : R' for procedure addresses */
326 R_HPPA_TSEL = 0xc, /* T' : DLT-relative offset for shlib's */
327 R_HPPA_LTSEL = 0xd, /* LT' : L' for DLT-relative offsets */
328 R_HPPA_RTSEL = 0xe /* RT' : R' for DLT-relative offsets */
332 #define N_HPPA_FIELD_SELECTORS 15
334 /* for compatibility */
335 enum hppa_reloc_field_selector_type_alt
337 e_fsel = R_HPPA_FSEL,
338 e_lssel = R_HPPA_LSSEL,
339 e_rssel = R_HPPA_RSSEL,
340 e_lsel = R_HPPA_LSEL,
341 e_rsel = R_HPPA_RSEL,
342 e_ldsel = R_HPPA_LDSEL,
343 e_rdsel = R_HPPA_RDSEL,
344 e_lrsel = R_HPPA_LRSEL,
345 e_rrsel = R_HPPA_RRSEL,
346 e_psel = R_HPPA_PSEL, /* P' : procedure address for shlib's */
347 e_lpsel = R_HPPA_LPSEL, /* LP' : L' for procedure addresses */
348 e_rpsel = R_HPPA_RPSEL, /* RP' : R' for procedure addresses */
350 e_tsel = R_HPPA_TSEL, /* T' : DLT-relative offset for shlib's */
351 e_ltsel = R_HPPA_LTSEL, /* LT' : L' for DLT-relative offsets */
352 e_rtsel = R_HPPA_RTSEL /* RT' : R' for DLT-relative offsets */
355 /* PA-RISC OPCODES */
357 #define get_opcode(insn) ((insn) & 0xfc000000) >> 26
359 /* XXX: this list is incomplete */
398 elf32_hppa_reloc_type **hppa_elf_gen_reloc_type (bfd * abfd, elf32_hppa_reloc_type base_type, int format, int field);
400 elf32_hppa_reloc_type **hppa_elf_gen_reloc_type ();
407 #define SHT_HPPA_SYMEXTN SHT_LOPROC
414 #define STT_HPPA_PLABEL STT_LOPROC
418 * HPPA symbol table extension entry types
421 #define HPPA_SXT_NULL 0x00
422 #define HPPA_SXT_SYMNDX 0x01
423 #define HPPA_SXT_ARG_RELOC 0x02
426 * These macros compose and decompose the value of a symextn entry:
428 * entry_type = ELF32_HPPA_SX_TYPE(word);
429 * entry_value = ELF32_HPPA_SX_VAL(word);
430 * word = ELF32_HPPA_SX_WORD(type,val);
431 * Se.hppa_se_info = ELF32_HPPA_SE_INFO(arg_reloc)
434 #define ELF32_HPPA_SX_TYPE(p) ((p) >> 24)
435 #define ELF32_HPPA_SX_VAL(p) ((p) & 0xFFFFFF)
436 #define ELF32_HPPA_SX_WORD(type,val) (((type) << 24) + (val & 0xFFFFFF))
438 /* The following was added facilitate implementation of the .hppa_symextn
439 section. This section is built after the symbol table is built in the
440 elf_write_object_contents routine (called from bfd_close). It is built
441 so late because it requires information that is not known until
442 the symbol and string table sections have been allocated, and
443 the symbol table has been built. */
445 #define ELF_TC_FAKE_SECTIONS 1 /* # of "hand_made" tc-specific sections */
446 #define SYMEXTN_SECTION_NAME ".hppa_symextn"
448 extern void EXFUN (elf_hppa_tc_symbol, (bfd *, elf32_symbol_type *, int));
449 extern void EXFUN (elf_hppa_tc_make_sections, (bfd *, PTR));
451 typedef Elf32_Word symext_entryS;
456 struct symext_chain *next;
459 typedef struct symext_chain symext_chainS;
461 extern symext_chainS *symext_rootP;
462 extern symext_chainS *symext_lastP;
464 #endif /* _ELF32_HPPA_H */