1 /* BFD back-end for HP PA-RISC ELF files.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
6 Center for Software Science
7 Department of Computer Science
10 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
32 /* ELF32/HPPA relocation support
34 This file contains ELF32/HPPA relocation support as specified
35 in the Stratus FTX/Golf Object File Format (SED-1762) dated
42 Center for Software Science
43 Department of Computer Science
47 #include "elf32-hppa.h"
49 #include "aout/aout64.h"
50 #include "hppa_stubs.h"
52 /* ELF/PA relocation howto entries */
54 static bfd_reloc_status_type hppa_elf_reloc ();
56 static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
58 /* 'bitpos' and 'abs' are obsolete */
59 /* type rs sz bsz pcrel bpos abs ovrf sf name */
60 /* 9.3.4. Address relocation types */
61 {R_HPPA_NONE, 0, 3, 19, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NONE"},
62 {R_HPPA_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_32"},
63 {R_HPPA_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_11"},
64 {R_HPPA_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_14"},
65 {R_HPPA_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_17"},
66 {R_HPPA_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L21"},
67 {R_HPPA_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R11"},
68 {R_HPPA_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R14"},
69 {R_HPPA_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R17"},
70 {R_HPPA_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LS21"},
71 {R_HPPA_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS11"},
72 {R_HPPA_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS14"},
73 {R_HPPA_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS17"},
74 {R_HPPA_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LD21"},
75 {R_HPPA_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD11"},
76 {R_HPPA_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD14"},
77 {R_HPPA_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD17"},
78 {R_HPPA_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LR21"},
79 {R_HPPA_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR14"},
80 {R_HPPA_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR17"},
81 /* 9.3.5. GOTOFF address relocation types */
82 {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_11"},
83 {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_14"},
84 {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"},
85 {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"},
86 {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"},
87 {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"},
88 {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"},
89 {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"},
90 {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"},
91 {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"},
92 {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"},
93 {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"},
94 {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"},
95 /* 9.3.6. Absolute call relocation types */
96 {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"},
97 {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"},
98 {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"},
99 {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"},
100 {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"},
101 {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"},
102 {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"},
103 {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"},
104 {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"},
105 {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"},
106 {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"},
107 {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"},
108 {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"},
109 {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"},
110 {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"},
111 {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"},
112 {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"},
113 {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"},
114 /* 9.3.7. PC-relative call relocation types */
115 {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"},
116 {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"},
117 {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"},
118 {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"},
119 {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"},
120 {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"},
121 {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"},
122 {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"},
123 {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"},
124 {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"},
125 {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"},
126 {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"},
127 {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"},
128 {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"},
129 {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"},
130 {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"},
131 {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"},
132 {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"},
133 {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"},
135 /* 9.3.8. Plabel relocation types */
136 {R_HPPA_PLABEL_32, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_32"},
137 {R_HPPA_PLABEL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_11"},
138 {R_HPPA_PLABEL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_14"},
139 {R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_L21"},
140 {R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R11"},
141 {R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R14"},
143 /* 9.3.9. Data linkage table (DLT) relocation types */
144 {R_HPPA_DLT_32, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_32"},
145 {R_HPPA_DLT_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_11"},
146 {R_HPPA_DLT_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_14"},
147 {R_HPPA_DLT_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_L21"},
148 {R_HPPA_DLT_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R11"},
149 {R_HPPA_DLT_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R14"},
151 /* 9.3.10. Relocations for unwinder tables */
152 {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
153 {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"},
155 /* 9.3.11. Relocation types for complex expressions */
156 {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_CONST"},
157 {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PC"},
158 {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_SYM"},
159 {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"},
160 {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"},
161 {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"},
162 {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"},
163 {R_HPPA_MAX, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MAX"},
164 {R_HPPA_MIN, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MIN"},
165 {R_HPPA_ADD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ADD"},
166 {R_HPPA_SUB, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_SUB"},
167 {R_HPPA_MULT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MULT"},
168 {R_HPPA_DIV, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_DIV"},
169 {R_HPPA_MOD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MOD"},
170 {R_HPPA_AND, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_AND"},
171 {R_HPPA_OR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_OR"},
172 {R_HPPA_XOR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_XOR"},
173 {R_HPPA_NOT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NOT"},
174 {R_HPPA_LSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LSHIFT"},
175 {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"},
176 {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"},
177 {R_HPPA_EXPR_F, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L"},
178 {R_HPPA_EXPR_L, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_L"},
179 {R_HPPA_EXPR_R, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_R"},
180 {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LS"},
181 {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RS"},
182 {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LD"},
183 {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RD"},
184 {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LR"},
185 {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RR"},
187 {R_HPPA_EXPR_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_32"},
188 {R_HPPA_EXPR_21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_21"},
189 {R_HPPA_EXPR_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_11"},
190 {R_HPPA_EXPR_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_14"},
191 {R_HPPA_EXPR_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_17"},
192 {R_HPPA_EXPR_12, 0, 3, 12, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_12"},
193 {R_HPPA_STUB_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_STUB_CALL_17"},
194 {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_HPPA_UNIMPLEMENTED"},
197 static symext_chainS *symext_rootP;
198 static symext_chainS *symext_lastP;
201 DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format),
203 unsigned long insn AND
204 unsigned long value AND
205 unsigned short r_type AND
206 unsigned short r_field AND
207 unsigned short r_format)
209 unsigned long const_part; /* part of the instruction that does not change */
210 unsigned long rebuilt_part;
218 const_part = insn & 0xffffe002;
219 dis_assemble_12 (value, &w1, &w);
220 rebuilt_part = (w1 << 2) | w;
221 return const_part | rebuilt_part;
228 const_part = insn & 0xffffe002;
229 dis_assemble_12 (value, &w1, &w);
230 rebuilt_part = (w1 << 2) | w;
231 return const_part | rebuilt_part;
235 const_part = insn & 0xffffc000;
236 low_sign_unext (value, 14, &rebuilt_part);
237 return const_part | rebuilt_part;
243 const_part = insn & 0xffe0e002;
244 dis_assemble_17 (value, &w1, &w2, &w);
245 rebuilt_part = (w2 << 2) | (w1 << 16) | w;
246 return const_part | rebuilt_part;
250 const_part = insn & 0xffe00000;
251 dis_assemble_21 (value, &rebuilt_part);
252 return const_part | rebuilt_part;
259 fprintf (stderr, "Relocation problem : ");
261 "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
262 r_type, r_format, r_field, abfd->filename);
268 DEFUN (hppa_elf_relocate_insn,
270 insn, address, symp, sym_value, r_addend,
271 r_type, r_format, r_field, pcrel),
273 asection * input_sect AND
274 unsigned long insn AND
275 unsigned long address AND
279 unsigned short r_type AND
280 unsigned short r_format AND
281 unsigned short r_field AND
284 unsigned char opcode = get_opcode (insn);
299 constant_value = ELF32_HPPA_R_CONSTANT (r_addend);
300 BFD_ASSERT (r_format == 14);
303 sym_value -= address;
304 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
305 return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
308 case SUBI: /* case SUBIO: */
309 case ADDIT: /* case ADDITO: */
310 case ADDI: /* case ADDIO: */
311 BFD_ASSERT (r_format == 11);
313 constant_value = ((insn & 0x1) << 10) | ((insn & 0xffe) >> 1);
314 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
315 return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
319 BFD_ASSERT (r_format == 21);
321 constant_value = assemble_21 (insn);
322 constant_value += ELF32_HPPA_R_CONSTANT (r_addend);
323 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
324 return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
329 arg_reloc = ELF32_HPPA_R_ARG_RELOC (r_addend);
331 BFD_ASSERT (r_format == 17);
333 /* XXX computing constant_value is not needed??? */
334 constant_value = assemble_17 ((insn & 0x001f0000) >> 16,
335 (insn & 0x00001ffc) >> 2,
337 /* @@ Assumes only 32 bits. */
338 constant_value = (constant_value << 15) >> 15;
342 address + input_sect->output_offset
343 + input_sect->output_section->vma;
344 sym_value = hppa_field_adjust (sym_value, -8, r_field);
347 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
349 return hppa_elf_rebuild_insn (abfd, insn, sym_value >> 2, r_type, r_field, r_format);
354 BFD_ASSERT (r_format == 32);
355 constant_value = insn;
356 constant_value += ELF32_HPPA_R_CONSTANT (r_addend);
358 return hppa_field_adjust (sym_value, constant_value, r_field);
363 "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
364 opcode, r_format, r_field);
371 DEFUN (hppa_elf_relocate_unwind_table,
373 data, address, symp, sym_value, r_addend,
374 r_type, r_format, r_field, pcrel),
376 asection * input_sect AND
378 unsigned long address AND
382 unsigned short r_type AND
383 unsigned short r_format AND
384 unsigned short r_field AND
387 bfd_byte *hit_data = address + (bfd_byte *) (data);
390 long relocated_value;
393 BFD_ASSERT (r_format == 32);
394 BFD_ASSERT (r_field == e_fsel);
397 case R_HPPA_UNWIND_ENTRY:
398 start_offset = bfd_get_32 (abfd, hit_data);
399 relocated_value = hppa_field_adjust (sym_value, start_offset, r_field);
400 bfd_put_32 (abfd, relocated_value, hit_data);
402 hit_data += sizeof (unsigned long);
403 end_offset = bfd_get_32 (abfd, hit_data);
404 relocated_value = hppa_field_adjust (sym_value, end_offset, r_field);
405 bfd_put_32 (abfd, relocated_value, hit_data);
408 case R_HPPA_UNWIND_ENTRIES:
409 for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long))
411 unsigned int adjustment;
412 start_offset = bfd_get_32 (abfd, hit_data);
413 /* Stuff the symbol value into the first word */
414 /* of the unwind descriptor */
415 bfd_put_32 (abfd, sym_value, hit_data);
416 adjustment = sym_value - start_offset;
418 hit_data += sizeof (unsigned long);
419 end_offset = adjustment + bfd_get_32 (abfd, hit_data);
420 bfd_put_32 (abfd, end_offset, hit_data);
422 /* If this is not the last unwind entry, */
423 /* adjust the symbol value. */
424 if (i + 1 < r_addend)
426 start_offset = bfd_get_32 (abfd, hit_data + 3 * sizeof (unsigned long));
427 sym_value = start_offset + adjustment;
434 "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
435 r_type, r_format, r_field);
439 /* Provided the symbol, returns the value reffed */
441 get_symbol_value (symbol)
446 if (symbol == (asymbol *) NULL)
448 else if (symbol->section == &bfd_com_section)
454 relocation = symbol->value +
455 symbol->section->output_section->vma +
456 symbol->section->output_offset;
462 /* This function provides a pretty straight-forward mapping between a */
463 /* base relocation type, format and field into the relocation type */
464 /* that will be emitted in an object file. The only wrinkle in the */
465 /* mapping is that when the T, TR, TL, P, PR, or PL expression */
466 /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
467 /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
468 /* (in the case of P, PR, and PL). */
470 /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
474 hppa_elf_gen_reloc_error (base_type, fmt, field)
475 elf32_hppa_reloc_type base_type;
479 fprintf (stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
480 base_type, fmt, field);
483 elf32_hppa_reloc_type **
484 hppa_elf_gen_reloc_type (abfd, base_type, format, field)
486 elf32_hppa_reloc_type base_type;
490 #define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field)
492 elf32_hppa_reloc_type *finaltype;
493 elf32_hppa_reloc_type **final_types;
496 final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2);
497 BFD_ASSERT (final_types != 0);
499 finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type));
500 BFD_ASSERT (finaltype != 0);
502 final_types[0] = finaltype;
503 final_types[1] = NULL;
505 #define final_type finaltype[0]
507 final_type = base_type;
518 final_type = R_HPPA_11;
521 final_type = R_HPPA_R11;
524 final_type = R_HPPA_RS11;
527 final_type = R_HPPA_RD11;
531 final_type = R_HPPA_PLABEL_11;
534 final_type = R_HPPA_PLABEL_R11;
547 final_type = base_type;
558 final_type = R_HPPA_R14;
561 final_type = R_HPPA_RS14;
564 final_type = R_HPPA_RD14;
567 final_type = R_HPPA_RR14;
571 final_type = R_HPPA_PLABEL_14;
574 final_type = R_HPPA_PLABEL_R14;
588 final_type = base_type;
596 final_type = R_HPPA_17;
599 final_type = R_HPPA_R17;
602 final_type = R_HPPA_RS17;
605 final_type = R_HPPA_RD17;
608 final_type = R_HPPA_RR17;
616 final_type = base_type;
624 final_type = R_HPPA_L21;
627 final_type = R_HPPA_LS21;
630 final_type = R_HPPA_LD21;
633 final_type = R_HPPA_LR21;
636 final_type = R_HPPA_PLABEL_L21;
645 final_type = base_type;
653 final_type = R_HPPA_32;
656 final_type = R_HPPA_PLABEL_32;
660 final_type = base_type;
666 final_type = base_type;
677 final_type = R_HPPA_GOTOFF_R11;
680 final_type = R_HPPA_GOTOFF_RS11;
683 final_type = R_HPPA_GOTOFF_RD11;
686 final_type = R_HPPA_GOTOFF_11;
694 final_type = base_type;
700 final_type = base_type;
706 final_type = R_HPPA_GOTOFF_R14;
709 final_type = R_HPPA_GOTOFF_RS14;
712 final_type = R_HPPA_GOTOFF_RD14;
715 final_type = R_HPPA_GOTOFF_RR14;
718 final_type = R_HPPA_GOTOFF_14;
726 final_type = base_type;
732 final_type = base_type;
738 final_type = R_HPPA_GOTOFF_L21;
741 final_type = R_HPPA_GOTOFF_LS21;
744 final_type = R_HPPA_GOTOFF_LD21;
747 final_type = R_HPPA_GOTOFF_LR21;
756 final_type = base_type;
762 final_type = base_type;
766 final_type = base_type;
770 case R_HPPA_PCREL_CALL:
777 final_type = R_HPPA_PCREL_CALL_R11;
780 final_type = R_HPPA_PCREL_CALL_RS11;
783 final_type = R_HPPA_PCREL_CALL_RD11;
786 final_type = R_HPPA_PCREL_CALL_11;
794 final_type = base_type;
800 final_type = base_type;
806 final_type = R_HPPA_PCREL_CALL_R14;
809 final_type = R_HPPA_PCREL_CALL_RS14;
812 final_type = R_HPPA_PCREL_CALL_RD14;
815 final_type = R_HPPA_PCREL_CALL_RR14;
818 final_type = R_HPPA_PCREL_CALL_14;
826 final_type = base_type;
834 final_type = R_HPPA_PCREL_CALL_R17;
837 final_type = R_HPPA_PCREL_CALL_RS17;
840 final_type = R_HPPA_PCREL_CALL_RD17;
843 final_type = R_HPPA_PCREL_CALL_RR17;
846 final_type = R_HPPA_PCREL_CALL_17;
854 final_type = base_type;
862 final_type = R_HPPA_PCREL_CALL_L21;
865 final_type = R_HPPA_PCREL_CALL_LS21;
868 final_type = R_HPPA_PCREL_CALL_LD21;
871 final_type = R_HPPA_PCREL_CALL_LR21;
880 final_type = base_type;
886 final_type = base_type;
890 final_type = base_type;
901 final_type = R_HPPA_PLABEL_11;
904 final_type = R_HPPA_PLABEL_R11;
908 final_type = base_type;
916 final_type = R_HPPA_PLABEL_14;
919 final_type = R_HPPA_PLABEL_R14;
923 final_type = base_type;
931 final_type = R_HPPA_PLABEL_L21;
935 final_type = base_type;
943 final_type = R_HPPA_PLABEL_32;
947 final_type = base_type;
953 final_type = base_type;
956 case R_HPPA_ABS_CALL:
963 final_type = R_HPPA_ABS_CALL_R11;
966 final_type = R_HPPA_ABS_CALL_RS11;
969 final_type = R_HPPA_ABS_CALL_RD11;
972 final_type = R_HPPA_ABS_CALL_11;
980 final_type = base_type;
986 final_type = base_type;
992 final_type = R_HPPA_ABS_CALL_R14;
995 final_type = R_HPPA_ABS_CALL_RS14;
998 final_type = R_HPPA_ABS_CALL_RD14;
1001 final_type = R_HPPA_ABS_CALL_RR14;
1004 final_type = R_HPPA_ABS_CALL_14;
1012 final_type = base_type;
1020 final_type = R_HPPA_ABS_CALL_R17;
1023 final_type = R_HPPA_ABS_CALL_RS17;
1026 final_type = R_HPPA_ABS_CALL_RD17;
1029 final_type = R_HPPA_ABS_CALL_RR17;
1032 final_type = R_HPPA_ABS_CALL_17;
1040 final_type = base_type;
1048 final_type = R_HPPA_ABS_CALL_L21;
1051 final_type = R_HPPA_ABS_CALL_LS21;
1054 final_type = R_HPPA_ABS_CALL_LD21;
1057 final_type = R_HPPA_ABS_CALL_LR21;
1066 final_type = base_type;
1072 final_type = base_type;
1076 final_type = base_type;
1081 final_type = R_HPPA_UNWIND_ENTRY;
1083 case R_HPPA_COMPLEX:
1084 case R_HPPA_COMPLEX_PCREL_CALL:
1085 case R_HPPA_COMPLEX_ABS_CALL:
1086 final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 6);
1087 BFD_ASSERT (final_types != 0);
1089 finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type) * 5);
1090 BFD_ASSERT (finaltype != 0);
1092 for (i = 0; i < 5; i++)
1093 final_types[i] = &finaltype[i];
1095 final_types[5] = NULL;
1097 finaltype[0] = R_HPPA_PUSH_SYM;
1099 if (base_type == R_HPPA_COMPLEX)
1100 finaltype[1] = R_HPPA_PUSH_SYM;
1101 else if (base_type == R_HPPA_COMPLEX_PCREL_CALL)
1102 finaltype[1] = R_HPPA_PUSH_PCREL_CALL;
1103 else /* base_type == R_HPPA_COMPLEX_ABS_CALL */
1104 finaltype[1] = R_HPPA_PUSH_ABS_CALL;
1106 finaltype[2] = R_HPPA_SUB;
1111 finaltype[3] = R_HPPA_EXPR_F;
1114 finaltype[3] = R_HPPA_EXPR_L;
1117 finaltype[3] = R_HPPA_EXPR_R;
1120 finaltype[3] = R_HPPA_EXPR_LS;
1123 finaltype[3] = R_HPPA_EXPR_RS;
1126 finaltype[3] = R_HPPA_EXPR_LD;
1129 finaltype[3] = R_HPPA_EXPR_RD;
1132 finaltype[3] = R_HPPA_EXPR_LR;
1135 finaltype[3] = R_HPPA_EXPR_RR;
1142 finaltype[4] = R_HPPA_EXPR_11;
1145 finaltype[4] = R_HPPA_EXPR_12;
1148 finaltype[4] = R_HPPA_EXPR_14;
1151 finaltype[4] = R_HPPA_EXPR_17;
1154 finaltype[4] = R_HPPA_EXPR_21;
1157 finaltype[4] = R_HPPA_EXPR_32;
1164 final_type = base_type;
1173 /* 12.4.4. Derive format from instruction
1175 Given a machine instruction, this function determines its format.
1176 The format can be determined solely from looking at the first six
1177 bits (the major opcode) of the instruction. Several major opcodes
1178 map to the same format. Opcodes which do not map to a known format
1179 should probably be reported as an error. */
1182 hppa_elf_insn2fmt (type, insn)
1183 elf32_hppa_reloc_type type;
1186 unsigned char fmt = 0; /* XXX: is this a proper default? */
1187 unsigned char op = get_opcode (insn);
1189 if (type == R_HPPA_NONE)
1243 /* this function is in charge of performing all the HP PA relocations */
1244 static long global_value;
1245 static long GOT_value; /* XXX: need to calculate this! For HPUX, GOT == DP */
1246 static asymbol *global_symbol;
1247 static int global_sym_defined;
1249 static bfd_reloc_status_type
1250 DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
1252 arelent * reloc_entry AND
1253 asymbol * symbol_in AND
1255 asection * input_section AND
1261 unsigned long addr = reloc_entry->address; /*+ input_section->vma*/
1262 bfd_byte *hit_data = addr + (bfd_byte *) (data);
1263 unsigned short r_type = reloc_entry->howto->type & 0xFF;
1264 unsigned short r_field = e_fsel;
1265 boolean r_pcrel = reloc_entry->howto->pc_relative;
1267 /* howto->bitsize contains the format (11, 14, 21, etc) information */
1268 unsigned r_format = reloc_entry->howto->bitsize;
1269 long r_addend = reloc_entry->addend;
1274 /* Partial linking - do nothing */
1275 reloc_entry->address += input_section->output_offset;
1276 return bfd_reloc_ok;
1279 if (symbol_in && symbol_in->section == &bfd_und_section)
1280 return bfd_reloc_undefined;
1282 /* Check for stubs that might be required. */
1283 /* symbol_in = hppa_elf_stub_check (abfd, input_section->output_section->owner, reloc_entry); */
1285 sym_value = get_symbol_value (symbol_in);
1287 /* compute value of $global$ if it is there. */
1289 if (!global_sym_defined)
1293 global_value = (global_symbol->value
1294 + global_symbol->section->output_section->vma
1295 + global_symbol->section->output_offset);
1296 GOT_value = global_value; /* XXX: For HP-UX, GOT==DP */
1297 global_sym_defined++;
1301 /* get the instruction word */
1302 insn = bfd_get_32 (abfd, hit_data);
1304 /* relocate the value based on the relocation type */
1306 /* basic_type_1: relocation is relative to $global$ */
1307 /* basic_type_2: relocation is relative to the current GOT */
1308 /* basic_type_3: relocation is an absolute call */
1309 /* basic_type_4: relocation is an PC-relative call */
1310 /* basic_type_5: relocation is plabel reference */
1311 /* basic_type_6: relocation is an unwind table relocation */
1312 /* extended_type: unimplemented */
1318 case R_HPPA_32: /* Symbol + Addend 32 */
1320 goto do_basic_type_1;
1321 case R_HPPA_11: /* Symbol + Addend 11 */
1323 goto do_basic_type_1;
1324 case R_HPPA_14: /* Symbol + Addend 14 */
1326 goto do_basic_type_1;
1327 case R_HPPA_17: /* Symbol + Addend 17 */
1329 goto do_basic_type_1;
1330 case R_HPPA_L21: /* L (Symbol, Addend) 21 */
1332 goto do_basic_type_1;
1333 case R_HPPA_R11: /* R (Symbol, Addend) 11 */
1335 goto do_basic_type_1;
1336 case R_HPPA_R14: /* R (Symbol, Addend) 14 */
1338 goto do_basic_type_1;
1339 case R_HPPA_R17: /* R (Symbol, Addend) 17 */
1341 goto do_basic_type_1;
1342 case R_HPPA_LS21: /* LS(Symbol, Addend) 21 */
1344 goto do_basic_type_1;
1345 case R_HPPA_RS11: /* RS(Symbol, Addend) 11 */
1347 goto do_basic_type_1;
1348 case R_HPPA_RS14: /* RS(Symbol, Addend) 14 */
1350 goto do_basic_type_1;
1351 case R_HPPA_RS17: /* RS(Symbol, Addend) 17 */
1353 goto do_basic_type_1;
1354 case R_HPPA_LD21: /* LD(Symbol, Addend) 21 */
1356 goto do_basic_type_1;
1357 case R_HPPA_RD11: /* RD(Symbol, Addend) 11 */
1359 goto do_basic_type_1;
1360 case R_HPPA_RD14: /* RD(Symbol, Addend) 14 */
1362 goto do_basic_type_1;
1363 case R_HPPA_RD17: /* RD(Symbol, Addend) 17 */
1365 goto do_basic_type_1;
1366 case R_HPPA_LR21: /* LR(Symbol, Addend) 21 */
1368 goto do_basic_type_1;
1369 case R_HPPA_RR14: /* RR(Symbol, Addend) 14 */
1371 goto do_basic_type_1;
1372 case R_HPPA_RR17: /* RR(Symbol, Addend) 17 */
1376 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1377 symbol_in, sym_value, r_addend,
1378 r_type, r_format, r_field, r_pcrel);
1381 case R_HPPA_GOTOFF_11: /* Symbol - GOT + Addend 11 */
1383 goto do_basic_type_2;
1384 case R_HPPA_GOTOFF_14: /* Symbol - GOT + Addend 14 */
1386 goto do_basic_type_2;
1387 case R_HPPA_GOTOFF_L21: /* L (Sym - GOT, Addend) 21 */
1389 goto do_basic_type_2;
1390 case R_HPPA_GOTOFF_R11: /* R (Sym - GOT, Addend) 11 */
1392 goto do_basic_type_2;
1393 case R_HPPA_GOTOFF_R14: /* R (Sym - GOT, Addend) 14 */
1395 goto do_basic_type_2;
1396 case R_HPPA_GOTOFF_LS21: /* LS(Sym - GOT, Addend) 21 */
1398 goto do_basic_type_2;
1399 case R_HPPA_GOTOFF_RS11: /* RS(Sym - GOT, Addend) 11 */
1401 goto do_basic_type_2;
1402 case R_HPPA_GOTOFF_RS14: /* RS(Sym - GOT, Addend) 14 */
1404 goto do_basic_type_2;
1405 case R_HPPA_GOTOFF_LD21: /* LD(Sym - GOT, Addend) 21 */
1407 goto do_basic_type_2;
1408 case R_HPPA_GOTOFF_RD11: /* RD(Sym - GOT, Addend) 11 */
1410 goto do_basic_type_2;
1411 case R_HPPA_GOTOFF_RD14: /* RD(Sym - GOT, Addend) 14 */
1413 goto do_basic_type_2;
1414 case R_HPPA_GOTOFF_LR21: /* LR(Sym - GOT, Addend) 21 */
1416 goto do_basic_type_2;
1417 case R_HPPA_GOTOFF_RR14: /* RR(Sym - GOT, Addend) 14 */
1420 sym_value -= GOT_value;
1421 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1422 symbol_in, sym_value, r_addend,
1423 r_type, r_format, r_field, r_pcrel);
1426 case R_HPPA_ABS_CALL_11: /* Symbol + Addend 11 */
1428 goto do_basic_type_3;
1429 case R_HPPA_ABS_CALL_14: /* Symbol + Addend 14 */
1431 goto do_basic_type_3;
1432 case R_HPPA_ABS_CALL_17: /* Symbol + Addend 17 */
1434 goto do_basic_type_3;
1435 case R_HPPA_ABS_CALL_L21: /* L (Symbol, Addend) 21 */
1437 goto do_basic_type_3;
1438 case R_HPPA_ABS_CALL_R11: /* R (Symbol, Addend) 11 */
1440 goto do_basic_type_3;
1441 case R_HPPA_ABS_CALL_R14: /* R (Symbol, Addend) 14 */
1443 goto do_basic_type_3;
1444 case R_HPPA_ABS_CALL_R17: /* R (Symbol, Addend) 17 */
1446 goto do_basic_type_3;
1447 case R_HPPA_ABS_CALL_LS21: /* LS(Symbol, Addend) 21 */
1449 goto do_basic_type_3;
1450 case R_HPPA_ABS_CALL_RS11: /* RS(Symbol, Addend) 11 */
1452 goto do_basic_type_3;
1453 case R_HPPA_ABS_CALL_RS14: /* RS(Symbol, Addend) 14 */
1455 goto do_basic_type_3;
1456 case R_HPPA_ABS_CALL_RS17: /* RS(Symbol, Addend) 17 */
1458 goto do_basic_type_3;
1459 case R_HPPA_ABS_CALL_LD21: /* LD(Symbol, Addend) 21 */
1461 goto do_basic_type_3;
1462 case R_HPPA_ABS_CALL_RD11: /* RD(Symbol, Addend) 11 */
1464 goto do_basic_type_3;
1465 case R_HPPA_ABS_CALL_RD14: /* RD(Symbol, Addend) 14 */
1467 goto do_basic_type_3;
1468 case R_HPPA_ABS_CALL_RD17: /* RD(Symbol, Addend) 17 */
1470 goto do_basic_type_3;
1471 case R_HPPA_ABS_CALL_LR21: /* LR(Symbol, Addend) 21 */
1473 goto do_basic_type_3;
1474 case R_HPPA_ABS_CALL_RR14: /* RR(Symbol, Addend) 14 */
1476 goto do_basic_type_3;
1477 case R_HPPA_ABS_CALL_RR17: /* RR(Symbol, Addend) 17 */
1480 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1481 symbol_in, sym_value, r_addend,
1482 r_type, r_format, r_field, r_pcrel);
1485 case R_HPPA_PCREL_CALL_11: /* Symbol - PC + Addend 11 */
1487 goto do_basic_type_4;
1488 case R_HPPA_PCREL_CALL_14: /* Symbol - PC + Addend 14 */
1490 goto do_basic_type_4;
1491 case R_HPPA_PCREL_CALL_17: /* Symbol - PC + Addend 17 */
1493 goto do_basic_type_4;
1494 case R_HPPA_PCREL_CALL_L21:/* L (Symbol - PC, Addend) 21 */
1496 goto do_basic_type_4;
1497 case R_HPPA_PCREL_CALL_R11:/* R (Symbol - PC, Addend) 11 */
1499 goto do_basic_type_4;
1500 case R_HPPA_PCREL_CALL_R14:/* R (Symbol - PC, Addend) 14 */
1502 goto do_basic_type_4;
1503 case R_HPPA_PCREL_CALL_R17:/* R (Symbol - PC, Addend) 17 */
1505 goto do_basic_type_4;
1506 case R_HPPA_PCREL_CALL_LS21: /* LS(Symbol - PC, Addend) 21 */
1508 goto do_basic_type_4;
1509 case R_HPPA_PCREL_CALL_RS11: /* RS(Symbol - PC, Addend) 11 */
1511 goto do_basic_type_4;
1512 case R_HPPA_PCREL_CALL_RS14: /* RS(Symbol - PC, Addend) 14 */
1514 goto do_basic_type_4;
1515 case R_HPPA_PCREL_CALL_RS17: /* RS(Symbol - PC, Addend) 17 */
1517 goto do_basic_type_4;
1518 case R_HPPA_PCREL_CALL_LD21: /* LD(Symbol - PC, Addend) 21 */
1520 goto do_basic_type_4;
1521 case R_HPPA_PCREL_CALL_RD11: /* RD(Symbol - PC, Addend) 11 */
1523 goto do_basic_type_4;
1524 case R_HPPA_PCREL_CALL_RD14: /* RD(Symbol - PC, Addend) 14 */
1526 goto do_basic_type_4;
1527 case R_HPPA_PCREL_CALL_RD17: /* RD(Symbol - PC, Addend) 17 */
1529 goto do_basic_type_4;
1530 case R_HPPA_PCREL_CALL_LR21: /* LR(Symbol - PC, Addend) 21 */
1532 goto do_basic_type_4;
1533 case R_HPPA_PCREL_CALL_RR14: /* RR(Symbol - PC, Addend) 14 */
1535 goto do_basic_type_4;
1536 case R_HPPA_PCREL_CALL_RR17: /* RR(Symbol - PC, Addend) 17 *//* #69 */
1539 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1540 symbol_in, sym_value, r_addend,
1541 r_type, r_format, r_field, r_pcrel);
1544 case R_HPPA_PLABEL_32:
1545 case R_HPPA_PLABEL_11:
1546 case R_HPPA_PLABEL_14:
1548 goto do_basic_type_5;
1549 case R_HPPA_PLABEL_L21:
1551 goto do_basic_type_5;
1552 case R_HPPA_PLABEL_R11:
1553 case R_HPPA_PLABEL_R14:
1556 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1557 symbol_in, sym_value, r_addend,
1558 r_type, r_format, r_field, r_pcrel);
1561 case R_HPPA_UNWIND_ENTRY:
1562 case R_HPPA_UNWIND_ENTRIES:
1563 hppa_elf_relocate_unwind_table (abfd, input_section, data, addr,
1564 symbol_in, sym_value, r_addend,
1565 r_type, r_format, r_field, r_pcrel);
1566 return (bfd_reloc_ok);
1568 case R_HPPA_PUSH_CONST: /* push Addend - - */
1569 case R_HPPA_PUSH_PC: /* push PC + Addend - - */
1570 case R_HPPA_PUSH_SYM: /* push Symbol + Addend - - */
1571 case R_HPPA_PUSH_GOTOFF: /* push Symbol - GOT + Addend - - */
1572 case R_HPPA_PUSH_ABS_CALL: /* push Symbol + Addend - - */
1573 case R_HPPA_PUSH_PCREL_CALL: /* push Symbol - PC + Addend - - */
1574 case R_HPPA_PUSH_PLABEL: /* [TBD] - - */
1575 case R_HPPA_MAX: /* pop A and B, push max(B,A) - - */
1576 case R_HPPA_MIN: /* pop A and B, push min(B,A) - - */
1577 case R_HPPA_ADD: /* pop A and B, push B + A - - */
1578 case R_HPPA_SUB: /* pop A and B, push B - A - - */
1579 case R_HPPA_MULT: /* pop A and B, push B * A - - */
1580 case R_HPPA_DIV: /* pop A and B, push B / A - - */
1581 case R_HPPA_MOD: /* pop A and B, push B % A - - */
1582 case R_HPPA_AND: /* pop A and B, push B & A - - */
1583 case R_HPPA_OR: /* pop A and B, push B | A - - */
1584 case R_HPPA_XOR: /* pop A and B, push B ^ A - - */
1585 case R_HPPA_NOT: /* pop A, push ~A - - */
1586 case R_HPPA_LSHIFT: /* pop A, push A << Addend - - */
1587 case R_HPPA_ARITH_RSHIFT: /* pop A, push A >> Addend - - */
1588 case R_HPPA_LOGIC_RSHIFT: /* pop A, push A >> Addend - - */
1589 case R_HPPA_EXPR_F: /* pop A, push A + Addend L - */
1590 case R_HPPA_EXPR_L: /* pop A, push L(A,Addend) L - */
1591 case R_HPPA_EXPR_R: /* pop A, push R(A,Addend) R - */
1592 case R_HPPA_EXPR_LS: /* pop A, push LS(A,Addend) LS - */
1593 case R_HPPA_EXPR_RS: /* pop A, push RS(A,Addend) RS - */
1594 case R_HPPA_EXPR_LD: /* pop A, push LD(A,Addend) LD - */
1595 case R_HPPA_EXPR_RD: /* pop A, push RD(A,Addend) RD - */
1596 case R_HPPA_EXPR_LR: /* pop A, push LR(A,Addend) LR - */
1597 case R_HPPA_EXPR_RR: /* pop A, push RR(A,Addend) RR - */
1599 case R_HPPA_EXPR_32: /* pop - 32 */
1600 case R_HPPA_EXPR_21: /* pop - 21 */
1601 case R_HPPA_EXPR_11: /* pop - 11 */
1602 case R_HPPA_EXPR_14: /* pop - 14 */
1603 case R_HPPA_EXPR_17: /* pop - 17 */
1604 case R_HPPA_EXPR_12: /* pop - 12 */
1605 fprintf (stderr, "Relocation problem: ");
1606 fprintf (stderr, "Unimplemented reloc type %d, in module %s\n",
1607 r_type, abfd->filename);
1608 return (bfd_reloc_notsupported);
1609 case R_HPPA_STUB_CALL_17:
1610 /* yes, a branch to a long branch stub. Change instruction to a BLE */
1612 if ( *(unsigned *)hit_data & 2 )
1613 insn = BLE_N_XXX_0_0;
1616 bfd_put_32 (abfd, insn, hit_data);
1617 r_type = R_HPPA_ABS_CALL_17;
1619 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1620 symbol_in, sym_value, r_addend,
1621 r_type, r_format, r_field, r_pcrel);
1625 fprintf (stderr, "Relocation problem : ");
1626 fprintf (stderr, "Unrecognized reloc type %d, in module %s\n",
1627 r_type, abfd->filename);
1628 return (bfd_reloc_dangerous);
1631 /* update the instruction word */
1632 bfd_put_32 (abfd, insn, hit_data);
1634 return (bfd_reloc_ok);
1638 static reloc_howto_type *
1639 elf_hppa_reloc_type_lookup (arch, code)
1640 bfd_arch_info_type *arch;
1641 bfd_reloc_code_real_type code;
1643 if ((int) code < (int) R_HPPA_UNIMPLEMENTED)
1645 BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
1646 return &elf_hppa_howto_table[(int) code];
1649 return (reloc_howto_type *) 0;
1652 #define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
1656 DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx),
1658 elf32_symbol_type * symbolP AND
1661 symext_chainS *symextP;
1662 unsigned int arg_reloc;
1664 if (!(symbolP->symbol.flags & BSF_FUNCTION))
1667 if (!((symbolP->symbol.flags & BSF_EXPORT) ||
1668 (symbolP->symbol.flags & BSF_GLOBAL)))
1671 arg_reloc = symbolP->tc_data.hppa_arg_reloc;
1673 symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
1675 symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
1676 symextP[0].next = &symextP[1];
1678 symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
1679 symextP[1].next = NULL;
1681 if (symext_rootP == NULL)
1683 symext_rootP = &symextP[0];
1684 symext_lastP = &symextP[1];
1688 symext_lastP->next = &symextP[0];
1689 symext_lastP = &symextP[1];
1693 /* Accessor function for the list of symbol extension records. */
1694 symext_chainS *elf32_hppa_get_symextn_chain()
1696 return symext_rootP;
1699 static symext_entryS *symextn_contents;
1700 static unsigned int symextn_contents_real_size;
1703 DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
1707 symext_chainS *symextP;
1711 void hppa_elf_stub_finish (); /* forward declaration */
1712 asection *symextn_sec;
1714 hppa_elf_stub_finish (abfd);
1716 if (symext_rootP == NULL)
1719 for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
1722 size = sizeof (symext_entryS) * n;
1723 symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
1724 if (symextn_sec == (asection *) 0)
1726 symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
1727 bfd_set_section_flags (abfd,
1729 SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE | SEC_READONLY);
1730 symextn_sec->output_section = symextn_sec;
1731 symextn_sec->output_offset = 0;
1732 bfd_set_section_alignment (abfd, symextn_sec, 2);
1734 symextn_contents = (symext_entryS *) bfd_alloc (abfd, size);
1736 for (i = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++i)
1737 symextn_contents[i] = symextP->entry;
1738 symextn_contents_real_size = size;
1739 bfd_set_section_size (abfd, symextn_sec, symextn_contents_real_size);
1744 /* Support for HP PA-RISC stub generation.
1748 Center for Software Science
1749 Department of Computer Science
1755 HP-PA calling conventions state:
1757 1. an argument relocation stub is required whenever the callee and
1758 caller argument relocation bits do not match exactly. The exception
1759 to this rule is if either the caller or callee argument relocation
1760 bit are 00 (do not relocate).
1762 2. The linker can optionally add a symbol record for the stub so that
1763 the stub can be reused. The symbol record will be the same as the
1764 original export symbol record, except that the relocation bits will
1765 reflect the input of the stub, the type would be STUB and the symbol
1766 value will be the location of the relocation stub.
1770 Stubs can be inserted *before* the section of the caller. The stubs
1771 can be treated as calls to code that manipulates the arguments.
1778 HPPA_STUB_ARG_RELOC,
1779 HPPA_STUB_LONG_BRANCH
1783 elf32_hppa_get_sym_extn (abfd, sym, type)
1788 /* This function finds the symbol extension record of the */
1789 /* specified type for the specified symbol. It returns the */
1790 /* value of the symbol extension record. */
1791 symext_entryS retval;
1796 retval = (symext_entryS) 0;
1798 case HPPA_SXT_SYMNDX:
1799 retval = (symext_entryS) 0; /* XXX: need to fix this */
1801 case HPPA_SXT_ARG_RELOC:
1803 elf32_symbol_type *esymP = (elf32_symbol_type *) sym;
1805 retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
1808 /* This should never happen. */
1816 typedef struct Elf32_hppa_Stub_description_struct
1818 bfd *this_bfd; /* bfd to which this stub */
1820 asection *stub_sec; /* stub section for this bfd */
1821 unsigned relocs_allocated_cnt; /* count of relocations for this stub section */
1823 unsigned allocated_size;
1824 int *stub_secp; /* pointer to the next available location in the buffer */
1825 char *stub_contents; /* contents of the stubs for this bfd */
1828 Elf32_hppa_Stub_description;
1830 typedef struct Elf32_hppa_Stub_list_struct
1832 Elf32_hppa_Stub_description *stub;
1833 struct Elf32_hppa_Stub_list_struct *next;
1834 } Elf32_hppa_Stub_list;
1836 static Elf32_hppa_Stub_list *elf_hppa_stub_rootP;
1838 /* Locate the stub section information for the given bfd. */
1839 static Elf32_hppa_Stub_description *
1840 find_stubs (abfd, stub_sec)
1844 Elf32_hppa_Stub_list *stubP;
1846 for (stubP = elf_hppa_stub_rootP; stubP; stubP = stubP->next)
1848 if (stubP->stub->this_bfd == abfd
1849 && stubP->stub->stub_sec == stub_sec)
1853 return (Elf32_hppa_Stub_description *) NULL;
1856 static Elf32_hppa_Stub_description *
1857 new_stub (abfd, stub_sec)
1861 Elf32_hppa_Stub_description *stub = find_stubs (abfd, stub_sec);
1866 stub = (Elf32_hppa_Stub_description *) bfd_zalloc (abfd, sizeof (Elf32_hppa_Stub_description));
1867 stub->this_bfd = abfd;
1868 stub->stub_sec = stub_sec;
1869 stub->real_size = 0;
1870 stub->allocated_size = 0;
1871 stub->stub_contents = NULL;
1872 stub->stub_secp = NULL;
1879 Elf32_hppa_Stub_description *stub;
1881 Elf32_hppa_Stub_list *new_entry;
1883 new_entry = (Elf32_hppa_Stub_list *) bfd_zalloc (stub->this_bfd, sizeof (Elf32_hppa_Stub_list));
1887 new_entry->stub = stub;
1889 if (elf_hppa_stub_rootP)
1891 new_entry->next = elf_hppa_stub_rootP;
1892 elf_hppa_stub_rootP = new_entry;
1896 new_entry->next = (Elf32_hppa_Stub_list *) NULL;
1897 elf_hppa_stub_rootP = new_entry;
1902 bfd_error = no_memory;
1903 bfd_perror ("add_stub");
1908 #define RETURN_VALUE 1
1910 #define NO_ARG_RELOC 0
1917 #define ARG_RELOC_ERR 7
1929 /* FP register in arg0/arg1. This value can only appear in the arg0 location. */
1931 /* FP register in arg2/arg3. This value can only appear in the arg2 location. */
1934 #define AR_WARN(type,loc) \
1935 fprintf(stderr,"WARNING: Illegal argument relocation: %s for %s\n", \
1936 reloc_type_strings[type],reloc_loc_strings[loc])
1938 static CONST char *CONST reloc_type_strings[] =
1940 "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
1943 static CONST char *CONST reloc_loc_strings[] =
1945 "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
1948 static CONST char mismatches[6][6] =
1949 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
1951 {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
1953 {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
1955 {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR},
1957 {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
1959 {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
1961 {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
1964 static CONST char retval_mismatches[6][6] =
1965 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
1967 {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
1969 {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
1971 {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
1973 {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
1975 {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
1977 {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
1981 type_of_mismatch (caller_bits, callee_bits, type)
1989 return mismatches[caller_bits][callee_bits];
1991 return retval_mismatches[caller_bits][callee_bits];
1997 #define EXTRACT_ARBITS(ar,which) ((ar) >> (8-(which*2))) & 3
1999 #define NEW_INSTRUCTION(desc,insn) \
2000 *((desc)->stub_secp)++ = (insn); \
2001 (desc)->real_size += sizeof(int); \
2002 bfd_set_section_size((desc)->this_bfd,(desc)->stub_sec,(desc)->real_size);
2004 #define CURRENT_STUB_OFFSET(desc) \
2005 ((int)(desc)->stub_secp - (int)(desc)->stub_contents - 4)
2007 static boolean stubs_finished = false;
2010 hppa_elf_stub_finish (output_bfd)
2013 extern bfd_error_vector_type bfd_error_vector;
2014 Elf32_hppa_Stub_list *stub_list = elf_hppa_stub_rootP;
2015 /* All the stubs have been built. Finish up building */
2016 /* stub section. Apply relocations to the section. */
2018 if ( stubs_finished )
2021 for (; stub_list; stub_list = stub_list->next)
2023 if (stub_list->stub->real_size)
2025 bfd *stub_bfd = stub_list->stub->this_bfd;
2026 asection *stub_sec = bfd_get_section_by_name (stub_bfd, ".hppa_linker_stubs");
2027 bfd_size_type reloc_size;
2028 arelent **reloc_vector;
2030 BFD_ASSERT (stub_sec == stub_list->stub->stub_sec);
2031 reloc_size = bfd_get_reloc_upper_bound (stub_bfd, stub_sec);
2032 reloc_vector = (arelent **) alloca (reloc_size);
2034 BFD_ASSERT (stub_sec);
2036 /* We are not relaxing the section, so just copy the size info */
2037 stub_sec->_cooked_size = stub_sec->_raw_size;
2038 stub_sec->reloc_done = true;
2041 if (bfd_canonicalize_reloc (stub_bfd,
2044 output_bfd->outsymbols))
2047 for (parent = reloc_vector; *parent != (arelent *) NULL;
2050 bfd_reloc_status_type r =
2051 bfd_perform_relocation (stub_bfd,
2053 stub_list->stub->stub_contents,
2057 if (r != bfd_reloc_ok)
2061 case bfd_reloc_undefined:
2062 bfd_error_vector.undefined_symbol (*parent, NULL);
2064 case bfd_reloc_dangerous:
2065 bfd_error_vector.reloc_dangerous (*parent, NULL);
2067 case bfd_reloc_outofrange:
2068 case bfd_reloc_overflow:
2069 bfd_error_vector.reloc_value_truncated (*parent, NULL);
2079 bfd_set_section_contents (output_bfd,
2081 stub_list->stub->stub_contents,
2083 stub_list->stub->real_size);
2085 free (reloc_vector);
2088 stubs_finished = true;
2092 hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */
2093 output_bfd, /* the output bfd */
2094 target_sym, /* the target symbol */
2095 offset) /* the offset within the stub buffer (pre-calculated) */
2096 Elf32_hppa_Stub_description *stub_desc;
2098 asymbol *target_sym;
2101 /* Allocate a new relocation entry. */
2105 if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2107 if (stub_desc->stub_sec->relocation == NULL)
2109 stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2110 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2111 stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
2115 stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2116 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2117 stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2122 /* Fill in the details. */
2123 relent.address = offset;
2125 relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2126 BFD_ASSERT (relent.sym_ptr_ptr);
2128 relent.sym_ptr_ptr[0] = target_sym;
2129 relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_PCREL_CALL_17);
2131 /* Save it in the array of relocations for the stub section. */
2133 memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2139 hppa_elf_stub_reloc (stub_desc, /* the bfd */
2140 output_bfd, /* the output bfd */
2141 target_sym, /* the target symbol */
2142 offset, /* the offset within the stub buffer (pre-calculated) */
2144 Elf32_hppa_Stub_description *stub_desc;
2146 asymbol *target_sym;
2148 elf32_hppa_reloc_type type;
2150 /* Allocate a new relocation entry. */
2153 Elf_Internal_Shdr *rela_hdr;
2155 if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2157 if (stub_desc->stub_sec->relocation == NULL)
2159 stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2160 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2161 stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
2165 stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2166 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2167 stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2172 rela_hdr = &elf_section_data(stub_desc->stub_sec)->rel_hdr;
2173 rela_hdr->sh_size += sizeof(Elf32_External_Rela);
2175 /* Fill in the details. */
2176 relent.address = offset;
2178 relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2179 BFD_ASSERT (relent.sym_ptr_ptr);
2181 relent.sym_ptr_ptr[0] = target_sym;
2182 relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, type);
2184 /* Save it in the array of relocations for the stub section. */
2186 memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2192 hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types)
2195 arelent *reloc_entry;
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 asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
2202 asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2204 char stub_sym_name[128];
2208 BFD_ASSERT (stub_desc == NULL);
2209 stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2210 bfd_set_section_flags (abfd,
2212 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_READONLY);
2213 stub_sec->output_section = output_text_section->output_section;
2214 stub_sec->output_offset = 0;
2215 bfd_set_section_alignment (abfd, stub_sec, 2);
2216 stub_desc = new_stub (abfd, stub_sec);
2217 add_stub (stub_desc);
2220 /* make sure we have a stub descriptor structure */
2224 stub_desc = new_stub (abfd, stub_sec);
2225 add_stub (stub_desc);
2228 /* allocate some space to write the stub */
2230 if (!stub_desc->stub_contents)
2232 stub_desc->allocated_size = STUB_BUFFER_INCR;
2233 stub_desc->stub_contents = (char *) xmalloc (STUB_BUFFER_INCR);
2235 else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2237 stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2238 stub_desc->stub_contents = (char *) xrealloc (stub_desc->stub_contents,
2239 stub_desc->allocated_size);
2242 stub_desc->stub_secp = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2244 /* create a symbol to point to this stub */
2245 stub_sym = bfd_make_empty_symbol (abfd);
2246 sprintf (stub_sym_name,
2247 "_stub_%s_%02d_%02d_%02d_%02d_%02d\000",
2248 reloc_entry->sym_ptr_ptr[0]->name,
2249 stub_types[0], stub_types[1], stub_types[2], stub_types[3], stub_types[4]);
2250 stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2251 strcpy ((char *) stub_sym->name, stub_sym_name);
2252 stub_sym->value = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
2253 stub_sym->section = stub_sec;
2254 stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
2256 /* redirect the original relocation from the old symbol (a function) */
2257 /* to the stub (the stub calls the function). */
2258 /* XXX do we need to change the relocation type? */
2259 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2260 reloc_entry->sym_ptr_ptr[0] = stub_sym;
2262 /* generate the beginning common section for all stubs */
2264 NEW_INSTRUCTION (stub_desc, ADDI_8_SP);
2266 /* generate the code to move the arguments around */
2267 for (i = ARG0; i < ARG3; i++)
2269 if (stub_types[i] != NO_ARG_RELOC)
2271 /* A stub is needed */
2272 switch (stub_types[i])
2278 NEW_INSTRUCTION (stub_desc, STWS_ARG0_M8SP);
2279 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG0);
2282 NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP);
2283 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1);
2286 NEW_INSTRUCTION (stub_desc, STWS_ARG2_M8SP);
2287 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG2);
2290 NEW_INSTRUCTION (stub_desc, STWS_ARG3_M8SP);
2291 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG3);
2300 NEW_INSTRUCTION(stub_desc, STWS_ARG0_M4SP);
2301 NEW_INSTRUCTION(stub_desc, STWS_ARG1_M8SP);
2302 NEW_INSTRUCTION(stub_desc, FLDDS_M8SP_FARG1);
2305 AR_WARN(stub_types[i],i);
2314 NEW_INSTRUCTION(stub_desc, STWS_ARG2_M4SP);
2315 NEW_INSTRUCTION(stub_desc, STWS_ARG3_M8SP);
2316 NEW_INSTRUCTION(stub_desc, FLDDS_M8SP_FARG3);
2319 AR_WARN(stub_types[i],i);
2328 NEW_INSTRUCTION (stub_desc, FSTWS_FARG0_M8SP);
2329 NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG0);
2332 NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP);
2333 NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG1);
2336 NEW_INSTRUCTION (stub_desc, FSTWS_FARG2_M8SP);
2337 NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG2);
2340 NEW_INSTRUCTION (stub_desc, FSTWS_FARG3_M8SP);
2341 NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG3);
2350 NEW_INSTRUCTION(stub_desc, FSTDS_FARG1_M8SP);
2351 NEW_INSTRUCTION(stub_desc, LDWS_M4SP_ARG0);
2352 NEW_INSTRUCTION(stub_desc, LDWS_M8SP_ARG1);
2355 AR_WARN(stub_types[i],i);
2364 NEW_INSTRUCTION(stub_desc, FSTDS_FARG3_M8SP);
2365 NEW_INSTRUCTION(stub_desc, LDWS_M4SP_ARG2);
2366 NEW_INSTRUCTION(stub_desc, LDWS_M8SP_ARG3);
2369 AR_WARN(stub_types[i],i);
2378 NEW_INSTRUCTION (stub_desc, ADDI_M8_SP);
2380 /* generate the branch to the target routine */
2381 NEW_INSTRUCTION (stub_desc, STW_RP_M8SP); /* First, save the return address */
2383 /* Branch to the target function. */
2384 /* (Make it a long call, so we do not */
2385 /* have to worry about generating a */
2386 /* long call stub.) */
2387 NEW_INSTRUCTION(stub_desc, LDIL_XXX_31);
2388 hppa_elf_stub_reloc (stub_desc,
2389 abfd, /* the output bfd */
2390 target_sym, /* the target symbol */
2391 CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
2393 NEW_INSTRUCTION(stub_desc,BLE_XXX_0_31);
2394 hppa_elf_stub_reloc (stub_desc,
2395 abfd, /* the output bfd */
2396 target_sym, /* the target symbol */
2397 CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
2398 R_HPPA_ABS_CALL_R17);
2399 NEW_INSTRUCTION(stub_desc,COPY_31_2);
2401 /* generate the code to move the return value around */
2403 if (stub_types[i] != NO_ARG_RELOC)
2405 /* A stub is needed */
2406 switch (stub_types[i])
2409 NEW_INSTRUCTION (stub_desc, STWS_RET0_M8SP);
2410 NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FRET0);
2414 NEW_INSTRUCTION (stub_desc, FSTWS_FRET0_M8SP);
2415 NEW_INSTRUCTION (stub_desc, LDWS_M4SP_RET0);
2420 /* generate the ending common section for all stubs */
2422 NEW_INSTRUCTION (stub_desc, LDW_M8SP_RP); /* restore return address */
2424 /* XXX: can we assume this is a save return? */
2425 NEW_INSTRUCTION (stub_desc, BV_N_0RP);
2431 hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)
2433 arelent *reloc_entry;
2436 /* If the symbol is still undefined, there is */
2437 /* no way to know if a stub is required. */
2439 if (reloc_entry->sym_ptr_ptr[0] && reloc_entry->sym_ptr_ptr[0]->section != &bfd_und_section)
2441 symext_entryS caller_ar = (symext_entryS) ELF32_HPPA_R_ARG_RELOC (reloc_entry->addend);
2442 symext_entryS callee_ar = elf32_hppa_get_sym_extn (abfd,
2443 reloc_entry->sym_ptr_ptr[0],
2444 HPPA_SXT_ARG_RELOC);
2446 /* Now, determine if a stub is */
2447 /* required. A stub is required if they the callee and caller */
2448 /* argument relocation bits are both nonzero and not equal. */
2450 if (caller_ar && callee_ar)
2452 /* Both are non-zero, we need to do further checking. */
2453 /* First, check if there is a return value relocation to be done */
2457 callee_loc[RETVAL] = EXTRACT_ARBITS (callee_ar, RETVAL);
2458 caller_loc[RETVAL] = EXTRACT_ARBITS (caller_ar, RETVAL);
2459 callee_loc[ARG0] = EXTRACT_ARBITS (callee_ar, ARG0);
2460 caller_loc[ARG0] = EXTRACT_ARBITS (caller_ar, ARG0);
2461 callee_loc[ARG1] = EXTRACT_ARBITS (callee_ar, ARG1);
2462 caller_loc[ARG1] = EXTRACT_ARBITS (caller_ar, ARG1);
2463 callee_loc[ARG2] = EXTRACT_ARBITS (callee_ar, ARG2);
2464 caller_loc[ARG2] = EXTRACT_ARBITS (caller_ar, ARG2);
2465 callee_loc[ARG3] = EXTRACT_ARBITS (callee_ar, ARG3);
2466 caller_loc[ARG3] = EXTRACT_ARBITS (caller_ar, ARG3);
2468 /* Check some special combinations. For */
2469 /* example, if FU appears in ARG1 or ARG3, we */
2470 /* can move it to ARG0 or ARG2, respectively. */
2472 if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
2474 caller_loc[ARG0] = AR_DBL01;
2475 caller_loc[ARG1] = AR_NO;
2477 if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
2479 caller_loc[ARG2] = AR_DBL23;
2480 caller_loc[ARG3] = AR_NO;
2482 if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
2484 callee_loc[ARG0] = AR_DBL01;
2485 callee_loc[ARG1] = AR_NO;
2487 if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
2489 callee_loc[ARG2] = AR_DBL23;
2490 callee_loc[ARG3] = AR_NO;
2493 stub_types[ARG0] = type_of_mismatch (caller_loc[ARG0], callee_loc[ARG0], ARGUMENTS);
2494 stub_types[ARG1] = type_of_mismatch (caller_loc[ARG1], callee_loc[ARG1], ARGUMENTS);
2495 stub_types[ARG2] = type_of_mismatch (caller_loc[ARG2], callee_loc[ARG2], ARGUMENTS);
2496 stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS);
2497 stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE);
2499 /* Steps involved in building stubs: */
2500 /* 1. Determine what argument registers need to relocated. This */
2501 /* step is already done here. */
2502 /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
2503 /* This section should never appear in an object file. It is */
2504 /* only used internally. The output_section of the */
2505 /* .hppa_linker_stubs section is the .text section of the */
2507 /* 3. Build a symbol that is used (internally only) as the entry */
2508 /* point of the stub. */
2509 /* 4. Change the instruction of the original branch into a branch to */
2510 /* the stub routine. */
2511 /* 5. Build a relocation entry for the instruction of the original */
2512 /* branch to be R_HPPA_PCREL_CALL to the stub routine. */
2522 fprintf (stderr, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
2523 reloc_entry->sym_ptr_ptr[0]->name,
2524 abfd->filename, reloc_entry->address,
2525 callee_ar, caller_ar);
2526 for (i = ARG0; i < RETVAL; i++)
2528 if (stub_types[i] != NO_ARG_RELOC)
2530 fprintf (stderr, "%s%d: %s ",
2531 i == RETVAL ? "ret" : "arg",
2532 i == RETVAL ? 0 : i,
2533 reloc_type_strings[stub_types[i]]);
2536 fprintf (stderr, "\n");
2547 hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
2550 arelent *reloc_entry;
2554 asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
2555 Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, stub_sec);
2556 asymbol *stub_sym = NULL;
2557 asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
2558 asymbol *return_sym = NULL;
2559 asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2560 char stub_sym_name[128];
2565 BFD_ASSERT (stub_desc == NULL);
2566 stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2567 bfd_set_section_flags (abfd,
2569 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_READONLY);
2570 stub_sec->output_section = output_text_section->output_section;
2571 stub_sec->output_offset = 0;
2572 /* set up the ELF section header for this new section. */
2573 /* This is basically the same processing as elf_make_sections() */
2574 /* (elf_make_sections() is static so it is not accessible from */
2578 Elf_Internal_Shdr *this_hdr;
2579 this_hdr = &elf_section_data (stub_sec)->this_hdr;
2581 this_hdr->sh_addr = stub_sec->vma;
2582 this_hdr->sh_size = stub_sec->_raw_size;
2583 /* contents already set by elf_set_section_contents */
2585 if (stub_sec->flags & SEC_RELOC)
2587 /* emit a reloc section, and thus strtab and symtab... */
2588 Elf_Internal_Shdr *rela_hdr;
2589 int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
2591 rela_hdr = &elf_section_data (stub_sec)->rel_hdr;
2593 /* orelocation has the data, reloc_count has the count... */
2596 rela_hdr->sh_type = SHT_RELA;
2597 rela_hdr->sh_entsize = sizeof (Elf32_External_Rela);
2600 /* REL relocations */
2602 rela_hdr->sh_type = SHT_REL;
2603 rela_hdr->sh_entsize = sizeof (Elf32_External_Rel);
2605 rela_hdr->sh_flags = 0;
2606 rela_hdr->sh_addr = 0;
2607 rela_hdr->sh_offset = 0;
2608 rela_hdr->sh_addralign = 0;
2611 if (stub_sec->flags & SEC_ALLOC)
2613 this_hdr->sh_flags |= SHF_ALLOC;
2614 if (stub_sec->flags & SEC_LOAD)
2616 /* @@ Do something with sh_type? */
2619 if (!(stub_sec->flags & SEC_READONLY))
2620 this_hdr->sh_flags |= SHF_WRITE;
2622 if (stub_sec->flags & SEC_CODE)
2623 this_hdr->sh_flags |= SHF_EXECINSTR;
2626 bfd_set_section_alignment (abfd, stub_sec, 2);
2627 stub_desc = new_stub (abfd, stub_sec);
2628 add_stub (stub_desc);
2633 stub_desc = new_stub (abfd, stub_sec);
2634 add_stub (stub_desc);
2637 /* allocate some space to write the stub */
2639 if (!stub_desc->stub_contents)
2641 stub_desc->allocated_size = STUB_BUFFER_INCR;
2642 stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR);
2644 else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2646 stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2647 stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
2648 stub_desc->allocated_size);
2651 stub_desc->stub_secp = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2653 /* create a symbol to point to this stub */
2654 stub_sym = bfd_make_empty_symbol (abfd);
2655 sprintf (stub_sym_name,
2656 "_lb_stub_%s\000", reloc_entry->sym_ptr_ptr[0]->name);
2657 stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2658 strcpy ((char *) stub_sym->name, stub_sym_name);
2659 stub_sym->value = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
2660 stub_sym->section = stub_sec;
2661 stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
2663 /* create a symbol to point to the return location */
2664 return_sym = bfd_make_empty_symbol (abfd);
2665 sprintf (stub_sym_name,
2666 "_lb_rtn_%s\000", reloc_entry->sym_ptr_ptr[0]->name);
2667 return_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2668 strcpy ((char *) return_sym->name, stub_sym_name);
2669 return_sym->value = reloc_entry->address + 8;
2670 return_sym->section = stub_sec;
2671 return_sym->flags = BSF_LOCAL | BSF_FUNCTION;
2673 /* redirect the original relocation from the old symbol (a function) */
2674 /* to the stub (the stub calls the function). */
2675 /* XXX do we need to change the relocation type? */
2676 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2677 reloc_entry->sym_ptr_ptr[0] = stub_sym;
2678 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2680 /* Build the stub */
2682 /* A millicode call? */
2683 /* If so, the return address comes in on r31 rather than r2 (rp) so a */
2684 /* slightly different code sequence is needed. */
2685 if ( ((*data & 0x03e00000) >> 21) == 31 )
2688 /* 1. initialization for the call. */
2690 NEW_INSTRUCTION(stub_desc, LDSID_31_RP);
2691 NEW_INSTRUCTION(stub_desc, MTSP_RP_SR0);
2694 NEW_INSTRUCTION(stub_desc, COPY_31_2);
2696 NEW_INSTRUCTION(stub_desc, LDIL_XXX_31);
2697 hppa_elf_stub_reloc (stub_desc,
2698 abfd, /* the output bfd */
2699 target_sym, /* the target symbol */
2700 CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
2703 /* 2. Make the call. */
2705 NEW_INSTRUCTION(stub_desc,BE_N_XXX_0_31);
2706 hppa_elf_stub_reloc (stub_desc,
2707 abfd, /* the output bfd */
2708 target_sym, /* the target symbol */
2709 CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
2710 R_HPPA_ABS_CALL_R17);
2711 /* 3. Branch back to the original location. */
2712 /* (accomplished with the COPY_31_2 instruction) */
2716 NEW_INSTRUCTION(stub_desc, STW_31_M24SP);
2717 NEW_INSTRUCTION(stub_desc, LDIL_XXX_RP);
2718 hppa_elf_stub_reloc (stub_desc,
2719 abfd, /* the output bfd */
2720 target_sym, /* the target symbol */
2721 CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
2724 /* 2. Make the call. */
2726 NEW_INSTRUCTION(stub_desc,BLE_XXX_0_RP);
2727 hppa_elf_stub_reloc (stub_desc,
2728 abfd, /* the output bfd */
2729 target_sym, /* the target symbol */
2730 CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */
2731 R_HPPA_ABS_CALL_R17);
2732 NEW_INSTRUCTION(stub_desc,COPY_31_2);
2734 /* 3. Branch back to the original location. */
2735 NEW_INSTRUCTION(stub_desc, LDW_M24SP_RP);
2736 NEW_INSTRUCTION(stub_desc, BV_N_0RP);
2743 hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
2746 arelent *reloc_entry;
2750 long sym_value = get_symbol_value(symbol);
2751 int fmt = reloc_entry->howto->bitsize;
2752 unsigned char op = get_opcode(insn);
2755 #define too_far(val,num_bits) ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
2757 BFD_ASSERT(fmt == hppa_elf_insn2fmt(reloc_entry->howto->type,insn));
2763 reloc_entry->address + asec->output_offset + asec->output_section->vma;
2764 if ( too_far(sym_value - raddr,fmt+1) )
2767 fprintf(stderr,"long_branch needed on BL insn: abfd=%s,sym=%s,distance=0x%x\n",abfd->filename,symbol->name,sym_value - reloc_entry->address);
2777 hppa_elf_stub_check (abfd, output_bfd, input_section, reloc_entry, symbol, hit_data)
2780 asection *input_section;
2781 arelent *reloc_entry;
2787 switch (reloc_entry->howto->type)
2789 case R_HPPA_ABS_CALL_11: /* Symbol + Addend 11 */
2790 case R_HPPA_ABS_CALL_14: /* Symbol + Addend 14 */
2791 case R_HPPA_ABS_CALL_17: /* Symbol + Addend 17 */
2792 case R_HPPA_ABS_CALL_L21: /* L (Symbol, Addend) 21 */
2793 case R_HPPA_ABS_CALL_R11: /* R (Symbol, Addend) 11 */
2794 case R_HPPA_ABS_CALL_R14: /* R (Symbol, Addend) 14 */
2795 case R_HPPA_ABS_CALL_R17: /* R (Symbol, Addend) 17 */
2796 case R_HPPA_ABS_CALL_LS21: /* LS(Symbol, Addend) 21 */
2797 case R_HPPA_ABS_CALL_RS11: /* RS(Symbol, Addend) 11 */
2798 case R_HPPA_ABS_CALL_RS14: /* RS(Symbol, Addend) 14 */
2799 case R_HPPA_ABS_CALL_RS17: /* RS(Symbol, Addend) 17 */
2800 case R_HPPA_ABS_CALL_LD21: /* LD(Symbol, Addend) 21 */
2801 case R_HPPA_ABS_CALL_RD11: /* RD(Symbol, Addend) 11 */
2802 case R_HPPA_ABS_CALL_RD14: /* RD(Symbol, Addend) 14 */
2803 case R_HPPA_ABS_CALL_RD17: /* RD(Symbol, Addend) 17 */
2804 case R_HPPA_ABS_CALL_LR21: /* LR(Symbol, Addend) 21 */
2805 case R_HPPA_ABS_CALL_RR14: /* RR(Symbol, Addend) 14 */
2806 case R_HPPA_ABS_CALL_RR17: /* RR(Symbol, Addend) 17 */
2808 case R_HPPA_PCREL_CALL_11: /* Symbol - PC + Addend 11 */
2809 case R_HPPA_PCREL_CALL_14: /* Symbol - PC + Addend 14 */
2810 case R_HPPA_PCREL_CALL_17: /* Symbol - PC + Addend 17 */
2811 case R_HPPA_PCREL_CALL_12: /* Symbol - PC + Addend 12 */
2812 case R_HPPA_PCREL_CALL_L21:/* L (Symbol - PC, Addend) 21 */
2813 case R_HPPA_PCREL_CALL_R11:/* R (Symbol - PC, Addend) 11 */
2814 case R_HPPA_PCREL_CALL_R14:/* R (Symbol - PC, Addend) 14 */
2815 case R_HPPA_PCREL_CALL_R17:/* R (Symbol - PC, Addend) 17 */
2816 case R_HPPA_PCREL_CALL_LS21: /* LS(Symbol - PC, Addend) 21 */
2817 case R_HPPA_PCREL_CALL_RS11: /* RS(Symbol - PC, Addend) 11 */
2818 case R_HPPA_PCREL_CALL_RS14: /* RS(Symbol - PC, Addend) 14 */
2819 case R_HPPA_PCREL_CALL_RS17: /* RS(Symbol - PC, Addend) 17 */
2820 case R_HPPA_PCREL_CALL_LD21: /* LD(Symbol - PC, Addend) 21 */
2821 case R_HPPA_PCREL_CALL_RD11: /* RD(Symbol - PC, Addend) 11 */
2822 case R_HPPA_PCREL_CALL_RD14: /* RD(Symbol - PC, Addend) 14 */
2823 case R_HPPA_PCREL_CALL_RD17: /* RD(Symbol - PC, Addend) 17 */
2824 case R_HPPA_PCREL_CALL_LR21: /* LR(Symbol - PC, Addend) 21 */
2825 case R_HPPA_PCREL_CALL_RR14: /* RR(Symbol - PC, Addend) 14 */
2826 case R_HPPA_PCREL_CALL_RR17: /* RR(Symbol - PC, Addend) 17 */
2827 if (hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types))
2829 /* generate a stub */
2830 return hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
2833 if (hppa_elf_long_branch_needed_p (abfd, input_section, reloc_entry, symbol,*(unsigned *)hit_data))
2835 /* generate a stub */
2836 return hppa_elf_build_long_branch_stub (abfd, output_bfd,
2837 reloc_entry, symbol,
2838 (unsigned *)hit_data);
2846 return reloc_entry->sym_ptr_ptr[0];
2849 #define STUB_SYM_BUFFER_INC 5
2852 hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec, syms, new_sym_cnt)
2862 asymbol *new_syms = (asymbol *) NULL;
2866 /* Relocations are in different places depending on whether this is */
2867 /* an output section or an input section. Also, the relocations are */
2868 /* in different forms. Sigh. */
2869 /* Luckily, we have bfd_canonicalize_reloc() to straighten this out for us. */
2871 /* if ( asec->orelocation || asec->relocation ) { */
2872 if (asec->reloc_count > 0)
2874 arelent **reloc_vector = (arelent **) alloca (asec->reloc_count * (sizeof (arelent *) + 1));
2876 bfd_canonicalize_reloc (abfd, asec, reloc_vector, syms);
2877 for (i = 0; i < asec->reloc_count; i++)
2882 if ( asec->orelocation )
2883 rle = asec->orelocation[i];
2885 rle = asec->relocation+i;
2888 arelent *rle = reloc_vector[i];
2890 switch (rle->howto->type)
2892 case R_HPPA_ABS_CALL_11: /* Symbol + Addend 11 */
2893 case R_HPPA_ABS_CALL_14: /* Symbol + Addend 14 */
2894 case R_HPPA_ABS_CALL_17: /* Symbol + Addend 17 */
2895 case R_HPPA_ABS_CALL_L21: /* L (Symbol, Addend) 21 */
2896 case R_HPPA_ABS_CALL_R11: /* R (Symbol, Addend) 11 */
2897 case R_HPPA_ABS_CALL_R14: /* R (Symbol, Addend) 14 */
2898 case R_HPPA_ABS_CALL_R17: /* R (Symbol, Addend) 17 */
2899 case R_HPPA_ABS_CALL_LS21: /* LS(Symbol, Addend) 21 */
2900 case R_HPPA_ABS_CALL_RS11: /* RS(Symbol, Addend) 11 */
2901 case R_HPPA_ABS_CALL_RS14: /* RS(Symbol, Addend) 14 */
2902 case R_HPPA_ABS_CALL_RS17: /* RS(Symbol, Addend) 17 */
2903 case R_HPPA_ABS_CALL_LD21: /* LD(Symbol, Addend) 21 */
2904 case R_HPPA_ABS_CALL_RD11: /* RD(Symbol, Addend) 11 */
2905 case R_HPPA_ABS_CALL_RD14: /* RD(Symbol, Addend) 14 */
2906 case R_HPPA_ABS_CALL_RD17: /* RD(Symbol, Addend) 17 */
2907 case R_HPPA_ABS_CALL_LR21: /* LR(Symbol, Addend) 21 */
2908 case R_HPPA_ABS_CALL_RR14: /* RR(Symbol, Addend) 14 */
2909 case R_HPPA_ABS_CALL_RR17: /* RR(Symbol, Addend) 17 */
2911 case R_HPPA_PCREL_CALL_11: /* Symbol - PC + Addend 11 */
2912 case R_HPPA_PCREL_CALL_14: /* Symbol - PC + Addend 14 */
2913 case R_HPPA_PCREL_CALL_17: /* Symbol - PC + Addend 17 */
2914 case R_HPPA_PCREL_CALL_12: /* Symbol - PC + Addend 12 */
2915 case R_HPPA_PCREL_CALL_L21: /* L (Symbol - PC, Addend) 21 */
2916 case R_HPPA_PCREL_CALL_R11: /* R (Symbol - PC, Addend) 11 */
2917 case R_HPPA_PCREL_CALL_R14: /* R (Symbol - PC, Addend) 14 */
2918 case R_HPPA_PCREL_CALL_R17: /* R (Symbol - PC, Addend) 17 */
2919 case R_HPPA_PCREL_CALL_LS21: /* LS(Symbol - PC, Addend) 21 */
2920 case R_HPPA_PCREL_CALL_RS11: /* RS(Symbol - PC, Addend) 11 */
2921 case R_HPPA_PCREL_CALL_RS14: /* RS(Symbol - PC, Addend) 14 */
2922 case R_HPPA_PCREL_CALL_RS17: /* RS(Symbol - PC, Addend) 17 */
2923 case R_HPPA_PCREL_CALL_LD21: /* LD(Symbol - PC, Addend) 21 */
2924 case R_HPPA_PCREL_CALL_RD11: /* RD(Symbol - PC, Addend) 11 */
2925 case R_HPPA_PCREL_CALL_RD14: /* RD(Symbol - PC, Addend) 14 */
2926 case R_HPPA_PCREL_CALL_RD17: /* RD(Symbol - PC, Addend) 17 */
2927 case R_HPPA_PCREL_CALL_LR21: /* LR(Symbol - PC, Addend) 21 */
2928 case R_HPPA_PCREL_CALL_RR14: /* RR(Symbol - PC, Addend) 14 */
2929 case R_HPPA_PCREL_CALL_RR17: /* RR(Symbol - PC, Addend) 17 */
2930 if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types))
2932 /* generate a stub */
2933 /* keep track of the new symbol */
2937 if (new_cnt == new_max)
2939 new_max += STUB_SYM_BUFFER_INC;
2940 new_syms = (asymbol *) realloc (new_syms, new_max * sizeof (asymbol));
2942 r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd, rle,
2944 new_syms[new_cnt++] = *r;
2946 /* We need to retrieve the section contents to check for */
2947 /* long branch stubs. */
2951 bfd_get_section_contents(abfd, asec, &insn, rle->address, sizeof(insn));
2952 if (hppa_elf_long_branch_needed_p (abfd, asec, rle, rle->sym_ptr_ptr[0], insn))
2954 /* generate a stub */
2955 /* keep track of the new symbol */
2959 if (new_cnt == new_max)
2961 new_max += STUB_SYM_BUFFER_INC;
2962 new_syms = (asymbol *) realloc (new_syms, new_max * sizeof (asymbol));
2964 r = hppa_elf_build_long_branch_stub (stub_bfd,
2967 rle->sym_ptr_ptr[0],
2969 new_syms[new_cnt++] = *r;
2980 *new_sym_cnt = new_cnt;
2985 char *linker_stubs = NULL;
2986 int linker_stubs_size = 0;
2987 int linker_stubs_max_size = 0;
2988 #define STUB_ALLOC_INCR 100
2991 DEFUN (hppa_elf_set_section_contents, (abfd, section, location, offset, count),
2996 bfd_size_type count)
2998 if ( strcmp(section->name, ".hppa_linker_stubs") == 0 )
3000 if ( linker_stubs_max_size < offset + count )
3002 linker_stubs_max_size = offset + count + STUB_ALLOC_INCR;
3003 linker_stubs = (char *)realloc(linker_stubs, linker_stubs_max_size);
3006 if ( offset + count > linker_stubs_size )
3007 linker_stubs_size = offset + count;
3009 memcpy(linker_stubs + offset,location,count);
3013 return bfd_elf32_set_section_contents (abfd, section, location,
3018 DEFUN (hppa_elf_get_section_contents, (abfd, section, location, offset, count),
3023 bfd_size_type count)
3025 /* if this is the linker stub section, then we have the */
3026 /* section contents in memory rather than on disk. */
3027 if (strcmp (section->name, ".hppa_linker_stubs") == 0)
3029 Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, section);
3033 if ((bfd_size_type) (offset + count) > section->_raw_size)
3034 return (false); /* on error */
3035 if ((bfd_size_type) (offset + count) > stub_desc->real_size)
3036 return (false); /* on error */
3038 memcpy (location, stub_desc->stub_contents + offset, count);
3041 /* if this is the symbol extension section, then we have the */
3042 /* section contents in memory rather than on disk. */
3043 else if (strcmp (section->name, ".hppa_symextn") == 0)
3047 if ((bfd_size_type) (offset + count) > section->_raw_size)
3048 return (false); /* on error */
3049 if ((bfd_size_type) (offset + count) > symextn_contents_real_size)
3050 return (false); /* on error */
3052 memcpy (location, symextn_contents + offset, count);
3056 return bfd_generic_get_section_contents (abfd, section, location, offset, count);
3060 DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst),
3062 arelent * cache_ptr AND
3063 Elf32_Internal_Rela * dst)
3065 BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED);
3066 cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)];
3070 DEFUN (elf32_hppa_backend_symbol_processing, (abfd, sym),
3074 /* Is this a definition of $global$? If so, keep it because it will be
3075 needed if any relocations are performed. */
3077 if (!strcmp (sym->name, "$global$")
3078 && sym->section != &bfd_und_section)
3080 global_symbol = sym;
3084 #define elf_backend_symbol_processing elf32_hppa_backend_symbol_processing
3086 struct elf32_hppa_symextn_map_struct
3094 static struct elf32_hppa_symextn_map_struct *elf32_hppa_symextn_map;
3095 static int elf32_hppa_symextn_map_size;
3098 DEFUN (elf32_hppa_backend_symbol_table_processing, (abfd, esyms,symcnt),
3100 elf32_symbol_type *esyms AND
3103 Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
3105 int current_sym_idx = 0;
3107 /* If the symbol extension section does not exist, all the symbol */
3108 /* all the symbol extension information is assumed to be zero. */
3110 if ( symextn_hdr == NULL )
3112 for ( i = 0; i < symcnt; i++ )
3114 esyms[i].tc_data.hppa_arg_reloc = 0;
3119 /* allocate a buffer of the appropriate size for the symextn section */
3121 symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size);
3122 symextn_hdr->size = symextn_hdr->sh_size;
3124 /* read in the symextn section */
3126 if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1)
3128 bfd_error = system_call_error;
3131 if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->size, abfd)
3132 != symextn_hdr->size)
3134 free ((PTR)symextn_hdr->contents);
3135 bfd_error = system_call_error;
3139 /* parse the entries, updating the symtab entries as we go */
3141 for ( i = 0; i < symextn_hdr->size / sizeof(symext_entryS); i++ )
3143 symext_entryS *seP = ((symext_entryS *)symextn_hdr->contents) + i;
3144 int se_value = ELF32_HPPA_SX_VAL(*seP);
3145 int se_type = ELF32_HPPA_SX_TYPE(*seP);
3152 case HPPA_SXT_SYMNDX:
3153 if ( se_value >= symcnt )
3155 bfd_error = bad_value;
3156 bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
3159 current_sym_idx = se_value - 1;
3162 case HPPA_SXT_ARG_RELOC:
3163 esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value;
3167 bfd_error = bad_value;
3168 bfd_perror("elf32_hppa_backend_symbol_table_processing");
3175 #define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing
3178 DEFUN (elf32_hppa_backend_section_processing, (abfd, secthdr),
3180 Elf32_Internal_Shdr *secthdr)
3184 if ( secthdr->sh_type == SHT_HPPA_SYMEXTN )
3186 for ( i = 0; i < secthdr->size / sizeof(symext_entryS); i++ )
3188 symext_entryS *seP = ((symext_entryS *)secthdr->contents) + i;
3189 int se_value = ELF32_HPPA_SX_VAL(*seP);
3190 int se_type = ELF32_HPPA_SX_TYPE(*seP);
3197 case HPPA_SXT_SYMNDX:
3198 for ( j = 0; j < abfd->symcount; j++ )
3200 /* locate the map entry for this symbol, if there is one. */
3201 /* modify the symbol extension section symbol index entry */
3202 /* to reflect the new symbol table index */
3204 for ( k = 0; k < elf32_hppa_symextn_map_size; k++ )
3206 if ( elf32_hppa_symextn_map[k].old_index == se_value
3207 && elf32_hppa_symextn_map[k].bfd == abfd->outsymbols[j]->the_bfd
3208 && elf32_hppa_symextn_map[k].sym == abfd->outsymbols[j] )
3211 ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, j),
3218 case HPPA_SXT_ARG_RELOC:
3222 bfd_error = bad_value;
3223 bfd_perror("elf32_hppa_backend_section_processing");
3231 #define elf_backend_section_processing elf32_hppa_backend_section_processing
3234 DEFUN (elf32_hppa_backend_section_from_shdr, (abfd, hdr, name),
3236 Elf32_Internal_Shdr *hdr AND
3241 if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3243 BFD_ASSERT ( strcmp(name,".hppa_symextn") == 0 );
3245 /* Bits that get saved. This one is real. */
3248 newsect = bfd_make_section (abfd, name);
3249 if (newsect != NULL)
3251 newsect->vma = hdr->sh_addr;
3252 newsect->_raw_size = hdr->sh_size;
3253 newsect->filepos = hdr->sh_offset; /* so we can read back the bits */
3254 newsect->flags |= SEC_HAS_CONTENTS;
3255 newsect->alignment_power = hdr->sh_addralign;
3257 if (hdr->sh_flags & SHF_ALLOC)
3259 newsect->flags |= SEC_ALLOC;
3260 newsect->flags |= SEC_LOAD;
3263 if (!(hdr->sh_flags & SHF_WRITE))
3264 newsect->flags |= SEC_READONLY;
3266 if (hdr->sh_flags & SHF_EXECINSTR)
3267 newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
3269 newsect->flags |= SEC_DATA;
3271 hdr->rawdata = (void *) newsect;
3279 #define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr
3282 DEFUN (elf32_hppa_backend_fake_sections, (abfd, secthdr, asect),
3284 Elf_Internal_Shdr *secthdr AND
3288 if ( strcmp(asect->name, ".hppa_symextn") == 0 )
3290 secthdr->sh_type = SHT_HPPA_SYMEXTN;
3291 secthdr->sh_flags = 0;
3292 secthdr->sh_info = elf_section_data(asect)->rel_hdr.sh_link;
3293 secthdr->sh_link = elf_onesymtab(abfd);
3297 if (!strcmp (asect->name, ".hppa_unwind"))
3299 secthdr->sh_type = SHT_PROGBITS;
3300 /* Unwind descriptors are not part of the program memory image. */
3301 secthdr->sh_flags = 0;
3302 secthdr->sh_info = 0;
3303 secthdr->sh_link = 0;
3304 secthdr->sh_entsize = 16;
3311 #define elf_backend_fake_sections elf32_hppa_backend_fake_sections
3314 DEFUN (elf32_hppa_backend_section_from_bfd_section, (abfd, hdr, asect),
3316 Elf32_Internal_Shdr *hdr AND
3320 if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3324 if (((struct sec *) (hdr->rawdata)) == asect)
3326 BFD_ASSERT( strcmp(asect->name, ".hppa_symextn") == 0 );
3335 #define elf_backend_section_from_bfd_section elf32_hppa_backend_section_from_bfd_section
3337 #define bfd_generic_get_section_contents hppa_elf_get_section_contents
3338 #define bfd_elf32_set_section_contents hppa_elf_set_section_contents
3340 #define TARGET_BIG_SYM bfd_elf32_hppa_vec
3341 #define TARGET_BIG_NAME "elf32-hppa"
3342 #define ELF_ARCH bfd_arch_hppa
3344 #include "elf32-target.h"