elf32-rl78.c revision 1.7 1 1.1 christos /* Renesas RL78 specific support for 32-bit ELF.
2 1.7 christos Copyright (C) 2011-2017 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of BFD, the Binary File Descriptor library.
5 1.1 christos
6 1.1 christos This program is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3 of the License, or
9 1.1 christos (at your option) any later version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; if not, write to the Free Software
18 1.1 christos Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 1.1 christos
20 1.1 christos #include "sysdep.h"
21 1.1 christos #include "bfd.h"
22 1.1 christos #include "bfd_stdint.h"
23 1.1 christos #include "libbfd.h"
24 1.1 christos #include "elf-bfd.h"
25 1.1 christos #include "elf/rl78.h"
26 1.1 christos #include "libiberty.h"
27 1.1 christos
28 1.1 christos #define valid_16bit_address(v) ((v) <= 0x0ffff || (v) >= 0xf0000)
29 1.1 christos
30 1.1 christos #define RL78REL(n,sz,bit,shift,complain,pcrel) \
31 1.1 christos HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
32 1.1 christos bfd_elf_generic_reloc, "R_RL78_" #n, FALSE, 0, ~0, FALSE)
33 1.1 christos
34 1.5 christos static bfd_reloc_status_type rl78_special_reloc (bfd *, arelent *, asymbol *, void *,
35 1.5 christos asection *, bfd *, char **);
36 1.5 christos
37 1.5 christos /* FIXME: We could omit the SHIFT parameter, it is always zero. */
38 1.5 christos #define RL78_OP_REL(n,sz,bit,shift,complain,pcrel) \
39 1.5 christos HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
40 1.5 christos rl78_special_reloc, "R_RL78_" #n, FALSE, 0, ~0, FALSE)
41 1.5 christos
42 1.1 christos /* Note that the relocations around 0x7f are internal to this file;
43 1.1 christos feel free to move them as needed to avoid conflicts with published
44 1.1 christos relocation numbers. */
45 1.1 christos
46 1.1 christos static reloc_howto_type rl78_elf_howto_table [] =
47 1.1 christos {
48 1.5 christos RL78REL (NONE, 3, 0, 0, dont, FALSE),
49 1.1 christos RL78REL (DIR32, 2, 32, 0, signed, FALSE),
50 1.1 christos RL78REL (DIR24S, 2, 24, 0, signed, FALSE),
51 1.1 christos RL78REL (DIR16, 1, 16, 0, dont, FALSE),
52 1.1 christos RL78REL (DIR16U, 1, 16, 0, unsigned, FALSE),
53 1.1 christos RL78REL (DIR16S, 1, 16, 0, signed, FALSE),
54 1.1 christos RL78REL (DIR8, 0, 8, 0, dont, FALSE),
55 1.1 christos RL78REL (DIR8U, 0, 8, 0, unsigned, FALSE),
56 1.1 christos RL78REL (DIR8S, 0, 8, 0, signed, FALSE),
57 1.1 christos RL78REL (DIR24S_PCREL, 2, 24, 0, signed, TRUE),
58 1.1 christos RL78REL (DIR16S_PCREL, 1, 16, 0, signed, TRUE),
59 1.1 christos RL78REL (DIR8S_PCREL, 0, 8, 0, signed, TRUE),
60 1.1 christos RL78REL (DIR16UL, 1, 16, 2, unsigned, FALSE),
61 1.1 christos RL78REL (DIR16UW, 1, 16, 1, unsigned, FALSE),
62 1.1 christos RL78REL (DIR8UL, 0, 8, 2, unsigned, FALSE),
63 1.1 christos RL78REL (DIR8UW, 0, 8, 1, unsigned, FALSE),
64 1.1 christos RL78REL (DIR32_REV, 1, 16, 0, dont, FALSE),
65 1.1 christos RL78REL (DIR16_REV, 1, 16, 0, dont, FALSE),
66 1.1 christos RL78REL (DIR3U_PCREL, 0, 3, 0, dont, TRUE),
67 1.1 christos
68 1.1 christos EMPTY_HOWTO (0x13),
69 1.1 christos EMPTY_HOWTO (0x14),
70 1.1 christos EMPTY_HOWTO (0x15),
71 1.1 christos EMPTY_HOWTO (0x16),
72 1.1 christos EMPTY_HOWTO (0x17),
73 1.1 christos EMPTY_HOWTO (0x18),
74 1.1 christos EMPTY_HOWTO (0x19),
75 1.1 christos EMPTY_HOWTO (0x1a),
76 1.1 christos EMPTY_HOWTO (0x1b),
77 1.1 christos EMPTY_HOWTO (0x1c),
78 1.1 christos EMPTY_HOWTO (0x1d),
79 1.1 christos EMPTY_HOWTO (0x1e),
80 1.1 christos EMPTY_HOWTO (0x1f),
81 1.1 christos
82 1.1 christos EMPTY_HOWTO (0x20),
83 1.1 christos EMPTY_HOWTO (0x21),
84 1.1 christos EMPTY_HOWTO (0x22),
85 1.1 christos EMPTY_HOWTO (0x23),
86 1.1 christos EMPTY_HOWTO (0x24),
87 1.1 christos EMPTY_HOWTO (0x25),
88 1.1 christos EMPTY_HOWTO (0x26),
89 1.1 christos EMPTY_HOWTO (0x27),
90 1.1 christos EMPTY_HOWTO (0x28),
91 1.1 christos EMPTY_HOWTO (0x29),
92 1.1 christos EMPTY_HOWTO (0x2a),
93 1.1 christos EMPTY_HOWTO (0x2b),
94 1.1 christos EMPTY_HOWTO (0x2c),
95 1.1 christos RL78REL (RH_RELAX, 0, 0, 0, dont, FALSE),
96 1.1 christos
97 1.1 christos EMPTY_HOWTO (0x2e),
98 1.5 christos RL78REL (RH_SADDR, 0, 0, 0, dont, FALSE),
99 1.1 christos EMPTY_HOWTO (0x30),
100 1.1 christos EMPTY_HOWTO (0x31),
101 1.1 christos EMPTY_HOWTO (0x32),
102 1.1 christos EMPTY_HOWTO (0x33),
103 1.1 christos EMPTY_HOWTO (0x34),
104 1.1 christos EMPTY_HOWTO (0x35),
105 1.1 christos EMPTY_HOWTO (0x36),
106 1.1 christos EMPTY_HOWTO (0x37),
107 1.1 christos EMPTY_HOWTO (0x38),
108 1.1 christos EMPTY_HOWTO (0x39),
109 1.1 christos EMPTY_HOWTO (0x3a),
110 1.1 christos EMPTY_HOWTO (0x3b),
111 1.1 christos EMPTY_HOWTO (0x3c),
112 1.1 christos EMPTY_HOWTO (0x3d),
113 1.1 christos EMPTY_HOWTO (0x3e),
114 1.1 christos EMPTY_HOWTO (0x3f),
115 1.1 christos EMPTY_HOWTO (0x40),
116 1.1 christos
117 1.5 christos RL78_OP_REL (ABS32, 2, 32, 0, dont, FALSE),
118 1.5 christos RL78_OP_REL (ABS24S, 2, 24, 0, signed, FALSE),
119 1.5 christos RL78_OP_REL (ABS16, 1, 16, 0, dont, FALSE),
120 1.5 christos RL78_OP_REL (ABS16U, 1, 16, 0, unsigned, FALSE),
121 1.5 christos RL78_OP_REL (ABS16S, 1, 16, 0, signed, FALSE),
122 1.5 christos RL78_OP_REL (ABS8, 0, 8, 0, dont, FALSE),
123 1.5 christos RL78_OP_REL (ABS8U, 0, 8, 0, unsigned, FALSE),
124 1.5 christos RL78_OP_REL (ABS8S, 0, 8, 0, signed, FALSE),
125 1.5 christos RL78_OP_REL (ABS24S_PCREL, 2, 24, 0, signed, TRUE),
126 1.5 christos RL78_OP_REL (ABS16S_PCREL, 1, 16, 0, signed, TRUE),
127 1.5 christos RL78_OP_REL (ABS8S_PCREL, 0, 8, 0, signed, TRUE),
128 1.5 christos RL78_OP_REL (ABS16UL, 1, 16, 0, unsigned, FALSE),
129 1.5 christos RL78_OP_REL (ABS16UW, 1, 16, 0, unsigned, FALSE),
130 1.5 christos RL78_OP_REL (ABS8UL, 0, 8, 0, unsigned, FALSE),
131 1.5 christos RL78_OP_REL (ABS8UW, 0, 8, 0, unsigned, FALSE),
132 1.5 christos RL78_OP_REL (ABS32_REV, 2, 32, 0, dont, FALSE),
133 1.5 christos RL78_OP_REL (ABS16_REV, 1, 16, 0, dont, FALSE),
134 1.1 christos
135 1.1 christos #define STACK_REL_P(x) ((x) <= R_RL78_ABS16_REV && (x) >= R_RL78_ABS32)
136 1.1 christos
137 1.1 christos EMPTY_HOWTO (0x52),
138 1.1 christos EMPTY_HOWTO (0x53),
139 1.1 christos EMPTY_HOWTO (0x54),
140 1.1 christos EMPTY_HOWTO (0x55),
141 1.1 christos EMPTY_HOWTO (0x56),
142 1.1 christos EMPTY_HOWTO (0x57),
143 1.1 christos EMPTY_HOWTO (0x58),
144 1.1 christos EMPTY_HOWTO (0x59),
145 1.1 christos EMPTY_HOWTO (0x5a),
146 1.1 christos EMPTY_HOWTO (0x5b),
147 1.1 christos EMPTY_HOWTO (0x5c),
148 1.1 christos EMPTY_HOWTO (0x5d),
149 1.1 christos EMPTY_HOWTO (0x5e),
150 1.1 christos EMPTY_HOWTO (0x5f),
151 1.1 christos EMPTY_HOWTO (0x60),
152 1.1 christos EMPTY_HOWTO (0x61),
153 1.1 christos EMPTY_HOWTO (0x62),
154 1.1 christos EMPTY_HOWTO (0x63),
155 1.1 christos EMPTY_HOWTO (0x64),
156 1.1 christos EMPTY_HOWTO (0x65),
157 1.1 christos EMPTY_HOWTO (0x66),
158 1.1 christos EMPTY_HOWTO (0x67),
159 1.1 christos EMPTY_HOWTO (0x68),
160 1.1 christos EMPTY_HOWTO (0x69),
161 1.1 christos EMPTY_HOWTO (0x6a),
162 1.1 christos EMPTY_HOWTO (0x6b),
163 1.1 christos EMPTY_HOWTO (0x6c),
164 1.1 christos EMPTY_HOWTO (0x6d),
165 1.1 christos EMPTY_HOWTO (0x6e),
166 1.1 christos EMPTY_HOWTO (0x6f),
167 1.1 christos EMPTY_HOWTO (0x70),
168 1.1 christos EMPTY_HOWTO (0x71),
169 1.1 christos EMPTY_HOWTO (0x72),
170 1.1 christos EMPTY_HOWTO (0x73),
171 1.1 christos EMPTY_HOWTO (0x74),
172 1.1 christos EMPTY_HOWTO (0x75),
173 1.1 christos EMPTY_HOWTO (0x76),
174 1.1 christos EMPTY_HOWTO (0x77),
175 1.1 christos
176 1.1 christos EMPTY_HOWTO (0x78),
177 1.1 christos EMPTY_HOWTO (0x79),
178 1.1 christos EMPTY_HOWTO (0x7a),
179 1.1 christos EMPTY_HOWTO (0x7b),
180 1.1 christos EMPTY_HOWTO (0x7c),
181 1.1 christos EMPTY_HOWTO (0x7d),
182 1.1 christos EMPTY_HOWTO (0x7e),
183 1.1 christos EMPTY_HOWTO (0x7f),
184 1.1 christos
185 1.5 christos RL78_OP_REL (SYM, 2, 32, 0, dont, FALSE),
186 1.5 christos RL78_OP_REL (OPneg, 2, 32, 0, dont, FALSE),
187 1.5 christos RL78_OP_REL (OPadd, 2, 32, 0, dont, FALSE),
188 1.5 christos RL78_OP_REL (OPsub, 2, 32, 0, dont, FALSE),
189 1.5 christos RL78_OP_REL (OPmul, 2, 32, 0, dont, FALSE),
190 1.5 christos RL78_OP_REL (OPdiv, 2, 32, 0, dont, FALSE),
191 1.5 christos RL78_OP_REL (OPshla, 2, 32, 0, dont, FALSE),
192 1.5 christos RL78_OP_REL (OPshra, 2, 32, 0, dont, FALSE),
193 1.5 christos RL78_OP_REL (OPsctsize, 2, 32, 0, dont, FALSE),
194 1.1 christos EMPTY_HOWTO (0x89),
195 1.1 christos EMPTY_HOWTO (0x8a),
196 1.1 christos EMPTY_HOWTO (0x8b),
197 1.1 christos EMPTY_HOWTO (0x8c),
198 1.5 christos RL78_OP_REL (OPscttop, 2, 32, 0, dont, FALSE),
199 1.1 christos EMPTY_HOWTO (0x8e),
200 1.1 christos EMPTY_HOWTO (0x8f),
201 1.5 christos RL78_OP_REL (OPand, 2, 32, 0, dont, FALSE),
202 1.5 christos RL78_OP_REL (OPor, 2, 32, 0, dont, FALSE),
203 1.5 christos RL78_OP_REL (OPxor, 2, 32, 0, dont, FALSE),
204 1.5 christos RL78_OP_REL (OPnot, 2, 32, 0, dont, FALSE),
205 1.5 christos RL78_OP_REL (OPmod, 2, 32, 0, dont, FALSE),
206 1.5 christos RL78_OP_REL (OPromtop, 2, 32, 0, dont, FALSE),
207 1.5 christos RL78_OP_REL (OPramtop, 2, 32, 0, dont, FALSE)
208 1.1 christos };
209 1.1 christos
210 1.1 christos /* Map BFD reloc types to RL78 ELF reloc types. */
212 1.1 christos
213 1.1 christos struct rl78_reloc_map
214 1.1 christos {
215 1.1 christos bfd_reloc_code_real_type bfd_reloc_val;
216 1.1 christos unsigned int rl78_reloc_val;
217 1.1 christos };
218 1.1 christos
219 1.1 christos static const struct rl78_reloc_map rl78_reloc_map [] =
220 1.1 christos {
221 1.1 christos { BFD_RELOC_NONE, R_RL78_NONE },
222 1.1 christos { BFD_RELOC_8, R_RL78_DIR8S },
223 1.1 christos { BFD_RELOC_16, R_RL78_DIR16S },
224 1.1 christos { BFD_RELOC_24, R_RL78_DIR24S },
225 1.1 christos { BFD_RELOC_32, R_RL78_DIR32 },
226 1.1 christos { BFD_RELOC_RL78_16_OP, R_RL78_DIR16 },
227 1.1 christos { BFD_RELOC_RL78_DIR3U_PCREL, R_RL78_DIR3U_PCREL },
228 1.1 christos { BFD_RELOC_8_PCREL, R_RL78_DIR8S_PCREL },
229 1.1 christos { BFD_RELOC_16_PCREL, R_RL78_DIR16S_PCREL },
230 1.1 christos { BFD_RELOC_24_PCREL, R_RL78_DIR24S_PCREL },
231 1.1 christos { BFD_RELOC_RL78_8U, R_RL78_DIR8U },
232 1.1 christos { BFD_RELOC_RL78_16U, R_RL78_DIR16U },
233 1.1 christos { BFD_RELOC_RL78_SYM, R_RL78_SYM },
234 1.1 christos { BFD_RELOC_RL78_OP_SUBTRACT, R_RL78_OPsub },
235 1.1 christos { BFD_RELOC_RL78_OP_NEG, R_RL78_OPneg },
236 1.1 christos { BFD_RELOC_RL78_OP_AND, R_RL78_OPand },
237 1.1 christos { BFD_RELOC_RL78_OP_SHRA, R_RL78_OPshra },
238 1.1 christos { BFD_RELOC_RL78_ABS8, R_RL78_ABS8 },
239 1.1 christos { BFD_RELOC_RL78_ABS16, R_RL78_ABS16 },
240 1.1 christos { BFD_RELOC_RL78_ABS16_REV, R_RL78_ABS16_REV },
241 1.1 christos { BFD_RELOC_RL78_ABS32, R_RL78_ABS32 },
242 1.1 christos { BFD_RELOC_RL78_ABS32_REV, R_RL78_ABS32_REV },
243 1.1 christos { BFD_RELOC_RL78_ABS16UL, R_RL78_ABS16UL },
244 1.1 christos { BFD_RELOC_RL78_ABS16UW, R_RL78_ABS16UW },
245 1.5 christos { BFD_RELOC_RL78_ABS16U, R_RL78_ABS16U },
246 1.1 christos { BFD_RELOC_RL78_SADDR, R_RL78_RH_SADDR },
247 1.1 christos { BFD_RELOC_RL78_RELAX, R_RL78_RH_RELAX }
248 1.1 christos };
249 1.1 christos
250 1.1 christos static reloc_howto_type *
251 1.1 christos rl78_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
252 1.1 christos bfd_reloc_code_real_type code)
253 1.1 christos {
254 1.1 christos unsigned int i;
255 1.1 christos
256 1.1 christos if (code == BFD_RELOC_RL78_32_OP)
257 1.1 christos return rl78_elf_howto_table + R_RL78_DIR32;
258 1.5 christos
259 1.1 christos for (i = ARRAY_SIZE (rl78_reloc_map); i--;)
260 1.1 christos if (rl78_reloc_map [i].bfd_reloc_val == code)
261 1.1 christos return rl78_elf_howto_table + rl78_reloc_map[i].rl78_reloc_val;
262 1.1 christos
263 1.1 christos return NULL;
264 1.1 christos }
265 1.1 christos
266 1.1 christos static reloc_howto_type *
267 1.1 christos rl78_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name)
268 1.1 christos {
269 1.1 christos unsigned int i;
270 1.1 christos
271 1.1 christos for (i = 0; i < ARRAY_SIZE (rl78_elf_howto_table); i++)
272 1.1 christos if (rl78_elf_howto_table[i].name != NULL
273 1.1 christos && strcasecmp (rl78_elf_howto_table[i].name, r_name) == 0)
274 1.1 christos return rl78_elf_howto_table + i;
275 1.1 christos
276 1.1 christos return NULL;
277 1.1 christos }
278 1.1 christos
279 1.1 christos /* Set the howto pointer for an RL78 ELF reloc. */
280 1.1 christos
281 1.1 christos static void
282 1.1 christos rl78_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
283 1.1 christos arelent * cache_ptr,
284 1.1 christos Elf_Internal_Rela * dst)
285 1.1 christos {
286 1.1 christos unsigned int r_type;
287 1.1 christos
288 1.3 christos r_type = ELF32_R_TYPE (dst->r_info);
289 1.3 christos if (r_type >= (unsigned int) R_RL78_max)
290 1.7 christos {
291 1.5 christos /* xgettext:c-format */
292 1.3 christos _bfd_error_handler (_("%B: invalid RL78 reloc number: %d"), abfd, r_type);
293 1.3 christos r_type = 0;
294 1.1 christos }
295 1.1 christos cache_ptr->howto = rl78_elf_howto_table + r_type;
296 1.1 christos }
297 1.1 christos
298 1.1 christos static bfd_vma
300 1.1 christos get_symbol_value (const char * name,
301 1.1 christos struct bfd_link_info * info,
302 1.1 christos bfd * input_bfd,
303 1.1 christos asection * input_section,
304 1.1 christos int offset)
305 1.1 christos {
306 1.5 christos struct bfd_link_hash_entry * h;
307 1.5 christos
308 1.5 christos if (info == NULL)
309 1.1 christos return 0;
310 1.1 christos
311 1.1 christos h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
312 1.1 christos
313 1.1 christos if (h == NULL
314 1.5 christos || (h->type != bfd_link_hash_defined
315 1.6 christos && h->type != bfd_link_hash_defweak))
316 1.5 christos {
317 1.5 christos (*info->callbacks->undefined_symbol)
318 1.5 christos (info, name, input_bfd, input_section, offset, TRUE);
319 1.1 christos return 0;
320 1.5 christos }
321 1.5 christos
322 1.5 christos return (h->u.def.value
323 1.1 christos + h->u.def.section->output_section->vma
324 1.1 christos + h->u.def.section->output_offset);
325 1.1 christos }
326 1.6 christos
327 1.1 christos static bfd_vma
328 1.1 christos get_romstart (struct bfd_link_info * info,
329 1.1 christos bfd * abfd,
330 1.1 christos asection * sec,
331 1.1 christos int offset)
332 1.1 christos {
333 1.1 christos static bfd_boolean cached = FALSE;
334 1.1 christos static bfd_vma cached_value = 0;
335 1.1 christos
336 1.6 christos if (!cached)
337 1.1 christos {
338 1.1 christos cached_value = get_symbol_value ("_start", info, abfd, sec, offset);
339 1.1 christos cached = TRUE;
340 1.1 christos }
341 1.1 christos return cached_value;
342 1.1 christos }
343 1.6 christos
344 1.1 christos static bfd_vma
345 1.1 christos get_ramstart (struct bfd_link_info * info,
346 1.1 christos bfd * abfd,
347 1.1 christos asection * sec,
348 1.1 christos int offset)
349 1.1 christos {
350 1.1 christos static bfd_boolean cached = FALSE;
351 1.1 christos static bfd_vma cached_value = 0;
352 1.1 christos
353 1.6 christos if (!cached)
354 1.1 christos {
355 1.1 christos cached_value = get_symbol_value ("__datastart", info, abfd, sec, offset);
356 1.1 christos cached = TRUE;
357 1.1 christos }
358 1.1 christos return cached_value;
359 1.1 christos }
360 1.1 christos
361 1.1 christos #define NUM_STACK_ENTRIES 16
362 1.1 christos static int32_t rl78_stack [ NUM_STACK_ENTRIES ];
363 1.1 christos static unsigned int rl78_stack_top;
364 1.1 christos
365 1.1 christos #define RL78_STACK_PUSH(val) \
366 1.1 christos do \
367 1.1 christos { \
368 1.1 christos if (rl78_stack_top < NUM_STACK_ENTRIES) \
369 1.5 christos rl78_stack [rl78_stack_top ++] = (val); \
370 1.1 christos else \
371 1.1 christos _bfd_error_handler (_("Internal Error: RL78 reloc stack overflow")); \
372 1.1 christos } \
373 1.1 christos while (0)
374 1.1 christos
375 1.1 christos #define RL78_STACK_POP(dest) \
376 1.1 christos do \
377 1.5 christos { \
378 1.1 christos if (rl78_stack_top > 0) \
379 1.5 christos (dest) = rl78_stack [-- rl78_stack_top];\
380 1.5 christos else \
381 1.5 christos { \
382 1.5 christos _bfd_error_handler (_("Internal Error: RL78 reloc stack underflow")); \
383 1.1 christos (dest) = 0; \
384 1.1 christos } \
385 1.1 christos } \
386 1.5 christos while (0)
387 1.5 christos
388 1.5 christos /* Special handling for RL78 complex relocs. Returns the
389 1.5 christos value of the reloc, or 0 for relocs which do not generate
390 1.5 christos a result. SYMVAL is the value of the symbol for relocs
391 1.5 christos which use a symbolic argument. */
392 1.5 christos
393 1.5 christos static bfd_vma
394 1.5 christos rl78_compute_complex_reloc (unsigned long r_type,
395 1.5 christos bfd_vma symval,
396 1.5 christos asection * input_section)
397 1.5 christos {
398 1.5 christos int32_t tmp1, tmp2;
399 1.5 christos bfd_vma relocation;
400 1.5 christos
401 1.5 christos switch (r_type)
402 1.5 christos {
403 1.5 christos default:
404 1.5 christos return 0;
405 1.5 christos
406 1.5 christos case R_RL78_ABS24S_PCREL:
407 1.5 christos case R_RL78_ABS16S_PCREL:
408 1.5 christos case R_RL78_ABS8S_PCREL:
409 1.5 christos RL78_STACK_POP (relocation);
410 1.5 christos relocation -= input_section->output_section->vma + input_section->output_offset;
411 1.5 christos return relocation;
412 1.5 christos
413 1.5 christos case R_RL78_ABS32:
414 1.5 christos case R_RL78_ABS32_REV:
415 1.5 christos case R_RL78_ABS16:
416 1.5 christos case R_RL78_ABS16_REV:
417 1.5 christos case R_RL78_ABS16S:
418 1.5 christos case R_RL78_ABS16U:
419 1.5 christos case R_RL78_ABS8:
420 1.5 christos case R_RL78_ABS8U:
421 1.5 christos case R_RL78_ABS8S:
422 1.5 christos RL78_STACK_POP (relocation);
423 1.5 christos return relocation;
424 1.5 christos
425 1.5 christos case R_RL78_ABS16UL:
426 1.5 christos case R_RL78_ABS8UL:
427 1.5 christos RL78_STACK_POP (relocation);
428 1.5 christos return relocation >> 2;
429 1.5 christos
430 1.5 christos case R_RL78_ABS16UW:
431 1.5 christos case R_RL78_ABS8UW:
432 1.5 christos RL78_STACK_POP (relocation);
433 1.5 christos return relocation >> 1;
434 1.5 christos
435 1.5 christos /* The rest of the relocs compute values and then push them onto the stack. */
436 1.5 christos case R_RL78_OPramtop:
437 1.5 christos case R_RL78_OPromtop:
438 1.5 christos case R_RL78_SYM:
439 1.6 christos RL78_STACK_PUSH (symval);
440 1.5 christos return 0;
441 1.5 christos
442 1.5 christos case R_RL78_OPneg:
443 1.5 christos RL78_STACK_POP (tmp1);
444 1.5 christos tmp1 = - tmp1;
445 1.5 christos RL78_STACK_PUSH (tmp1);
446 1.5 christos return 0;
447 1.5 christos
448 1.5 christos case R_RL78_OPadd:
449 1.5 christos RL78_STACK_POP (tmp2);
450 1.5 christos RL78_STACK_POP (tmp1);
451 1.5 christos tmp1 += tmp2;
452 1.5 christos RL78_STACK_PUSH (tmp1);
453 1.5 christos return 0;
454 1.5 christos
455 1.5 christos case R_RL78_OPsub:
456 1.5 christos /* For the expression "A - B", the assembler pushes A,
457 1.5 christos then B, then OPSUB. So the first op we pop is B, not A. */
458 1.5 christos RL78_STACK_POP (tmp2); /* B */
459 1.5 christos RL78_STACK_POP (tmp1); /* A */
460 1.5 christos tmp1 -= tmp2; /* A - B */
461 1.5 christos RL78_STACK_PUSH (tmp1);
462 1.5 christos return 0;
463 1.5 christos
464 1.5 christos case R_RL78_OPmul:
465 1.5 christos RL78_STACK_POP (tmp2);
466 1.5 christos RL78_STACK_POP (tmp1);
467 1.5 christos tmp1 *= tmp2;
468 1.5 christos RL78_STACK_PUSH (tmp1);
469 1.5 christos return 0;
470 1.5 christos
471 1.5 christos case R_RL78_OPdiv:
472 1.5 christos RL78_STACK_POP (tmp2);
473 1.5 christos RL78_STACK_POP (tmp1);
474 1.5 christos tmp1 /= tmp2;
475 1.5 christos RL78_STACK_PUSH (tmp1);
476 1.5 christos return 0;
477 1.5 christos
478 1.5 christos case R_RL78_OPshla:
479 1.5 christos RL78_STACK_POP (tmp2);
480 1.5 christos RL78_STACK_POP (tmp1);
481 1.5 christos tmp1 <<= tmp2;
482 1.5 christos RL78_STACK_PUSH (tmp1);
483 1.5 christos return 0;
484 1.5 christos
485 1.5 christos case R_RL78_OPshra:
486 1.5 christos RL78_STACK_POP (tmp2);
487 1.5 christos RL78_STACK_POP (tmp1);
488 1.5 christos tmp1 >>= tmp2;
489 1.5 christos RL78_STACK_PUSH (tmp1);
490 1.5 christos return 0;
491 1.5 christos
492 1.5 christos case R_RL78_OPsctsize:
493 1.5 christos RL78_STACK_PUSH (input_section->size);
494 1.5 christos return 0;
495 1.5 christos
496 1.5 christos case R_RL78_OPscttop:
497 1.5 christos RL78_STACK_PUSH (input_section->output_section->vma);
498 1.5 christos return 0;
499 1.5 christos
500 1.5 christos case R_RL78_OPand:
501 1.5 christos RL78_STACK_POP (tmp2);
502 1.5 christos RL78_STACK_POP (tmp1);
503 1.5 christos tmp1 &= tmp2;
504 1.5 christos RL78_STACK_PUSH (tmp1);
505 1.5 christos return 0;
506 1.5 christos
507 1.5 christos case R_RL78_OPor:
508 1.5 christos RL78_STACK_POP (tmp2);
509 1.5 christos RL78_STACK_POP (tmp1);
510 1.5 christos tmp1 |= tmp2;
511 1.5 christos RL78_STACK_PUSH (tmp1);
512 1.5 christos return 0;
513 1.5 christos
514 1.5 christos case R_RL78_OPxor:
515 1.5 christos RL78_STACK_POP (tmp2);
516 1.5 christos RL78_STACK_POP (tmp1);
517 1.5 christos tmp1 ^= tmp2;
518 1.5 christos RL78_STACK_PUSH (tmp1);
519 1.5 christos return 0;
520 1.5 christos
521 1.5 christos case R_RL78_OPnot:
522 1.5 christos RL78_STACK_POP (tmp1);
523 1.5 christos tmp1 = ~ tmp1;
524 1.5 christos RL78_STACK_PUSH (tmp1);
525 1.5 christos return 0;
526 1.5 christos
527 1.5 christos case R_RL78_OPmod:
528 1.5 christos RL78_STACK_POP (tmp2);
529 1.5 christos RL78_STACK_POP (tmp1);
530 1.5 christos tmp1 %= tmp2;
531 1.5 christos RL78_STACK_PUSH (tmp1);
532 1.5 christos return 0;
533 1.5 christos }
534 1.5 christos }
535 1.5 christos
536 1.5 christos #undef RL78_STACK_PUSH
537 1.5 christos #undef RL78_STACK_POP
538 1.5 christos
539 1.5 christos #define OP(i) (contents[reloc->address + (i)])
540 1.5 christos
541 1.5 christos static bfd_reloc_status_type
542 1.5 christos rl78_special_reloc (bfd * input_bfd,
543 1.5 christos arelent * reloc,
544 1.5 christos asymbol * symbol,
545 1.5 christos void * data,
546 1.5 christos asection * input_section,
547 1.5 christos bfd * output_bfd ATTRIBUTE_UNUSED,
548 1.5 christos char ** error_message ATTRIBUTE_UNUSED)
549 1.5 christos {
550 1.5 christos bfd_reloc_status_type r = bfd_reloc_ok;
551 1.5 christos bfd_vma relocation = 0;
552 1.5 christos unsigned long r_type = reloc->howto->type;
553 1.5 christos bfd_byte * contents = data;
554 1.5 christos
555 1.5 christos /* If necessary, compute the symbolic value of the relocation. */
556 1.5 christos switch (r_type)
557 1.5 christos {
558 1.5 christos case R_RL78_SYM:
559 1.5 christos relocation = (symbol->value
560 1.5 christos + symbol->section->output_section->vma
561 1.5 christos + symbol->section->output_offset
562 1.5 christos + reloc->addend);
563 1.5 christos break;
564 1.6 christos
565 1.5 christos case R_RL78_OPromtop:
566 1.5 christos relocation = get_romstart (NULL, input_bfd, input_section,
567 1.5 christos reloc->address);
568 1.5 christos break;
569 1.6 christos
570 1.5 christos case R_RL78_OPramtop:
571 1.5 christos relocation = get_ramstart (NULL, input_bfd, input_section,
572 1.5 christos reloc->address);
573 1.5 christos break;
574 1.5 christos }
575 1.5 christos
576 1.5 christos /* Get the value of the relocation. */
577 1.5 christos relocation = rl78_compute_complex_reloc (r_type, relocation, input_section);
578 1.5 christos
579 1.5 christos /* If the relocation alters the contents of the section then apply it now.
580 1.5 christos Note - since this function is called from
581 1.5 christos bfd_generic_get_relocated_section_contents via bfd_perform_relocation,
582 1.5 christos and not from the linker, we do not perform any range checking. The
583 1.5 christos clients who are calling us are only interested in some relocated section
584 1.5 christos contents, and not any linkage problems that might occur later. */
585 1.5 christos switch (r_type)
586 1.5 christos {
587 1.5 christos case R_RL78_ABS32:
588 1.5 christos OP (0) = relocation;
589 1.5 christos OP (1) = relocation >> 8;
590 1.5 christos OP (2) = relocation >> 16;
591 1.5 christos OP (3) = relocation >> 24;
592 1.5 christos break;
593 1.5 christos
594 1.5 christos case R_RL78_ABS32_REV:
595 1.5 christos OP (3) = relocation;
596 1.5 christos OP (2) = relocation >> 8;
597 1.5 christos OP (1) = relocation >> 16;
598 1.5 christos OP (0) = relocation >> 24;
599 1.5 christos break;
600 1.5 christos
601 1.5 christos case R_RL78_ABS24S_PCREL:
602 1.5 christos case R_RL78_ABS24S:
603 1.5 christos OP (0) = relocation;
604 1.5 christos OP (1) = relocation >> 8;
605 1.5 christos OP (2) = relocation >> 16;
606 1.5 christos break;
607 1.5 christos
608 1.5 christos case R_RL78_ABS16_REV:
609 1.5 christos OP (1) = relocation;
610 1.5 christos OP (0) = relocation >> 8;
611 1.5 christos break;
612 1.5 christos
613 1.5 christos case R_RL78_ABS16S_PCREL:
614 1.5 christos case R_RL78_ABS16:
615 1.5 christos case R_RL78_ABS16S:
616 1.5 christos case R_RL78_ABS16U:
617 1.5 christos case R_RL78_ABS16UL:
618 1.5 christos case R_RL78_ABS16UW:
619 1.5 christos OP (0) = relocation;
620 1.5 christos OP (1) = relocation >> 8;
621 1.5 christos break;
622 1.5 christos
623 1.5 christos case R_RL78_ABS8S_PCREL:
624 1.5 christos case R_RL78_ABS8:
625 1.5 christos case R_RL78_ABS8U:
626 1.5 christos case R_RL78_ABS8UL:
627 1.5 christos case R_RL78_ABS8UW:
628 1.5 christos case R_RL78_ABS8S:
629 1.5 christos OP (0) = relocation;
630 1.5 christos break;
631 1.5 christos
632 1.5 christos default:
633 1.5 christos break;
634 1.5 christos }
635 1.5 christos
636 1.5 christos return r;
637 1.5 christos }
638 1.5 christos
639 1.5 christos #undef OP
640 1.1 christos #define OP(i) (contents[rel->r_offset + (i)])
641 1.1 christos
642 1.1 christos /* Relocate an RL78 ELF section.
643 1.1 christos There is some attempt to make this function usable for many architectures,
644 1.1 christos both USE_REL and USE_RELA ['twould be nice if such a critter existed],
645 1.1 christos if only to serve as a learning tool.
646 1.1 christos
647 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker
648 1.1 christos to handle the relocations for a section.
649 1.1 christos
650 1.1 christos The relocs are always passed as Rela structures; if the section
651 1.1 christos actually uses Rel structures, the r_addend field will always be
652 1.1 christos zero.
653 1.1 christos
654 1.1 christos This function is responsible for adjusting the section contents as
655 1.1 christos necessary, and (if using Rela relocs and generating a relocatable
656 1.1 christos output file) adjusting the reloc addend as necessary.
657 1.1 christos
658 1.1 christos This function does not have to worry about setting the reloc
659 1.1 christos address or the reloc symbol index.
660 1.1 christos
661 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols.
662 1.1 christos
663 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file
664 1.1 christos corresponding to the st_shndx field of each local symbol.
665 1.1 christos
666 1.1 christos The global hash table entry for the global symbols can be found
667 1.1 christos via elf_sym_hashes (input_bfd).
668 1.1 christos
669 1.1 christos When generating relocatable output, this function must handle
670 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is
671 1.1 christos going to be the section symbol corresponding to the output
672 1.1 christos section, which means that the addend must be adjusted
673 1.1 christos accordingly. */
674 1.1 christos
675 1.1 christos static bfd_boolean
676 1.1 christos rl78_elf_relocate_section
677 1.1 christos (bfd * output_bfd,
678 1.1 christos struct bfd_link_info * info,
679 1.1 christos bfd * input_bfd,
680 1.1 christos asection * input_section,
681 1.1 christos bfd_byte * contents,
682 1.1 christos Elf_Internal_Rela * relocs,
683 1.1 christos Elf_Internal_Sym * local_syms,
684 1.1 christos asection ** local_sections)
685 1.1 christos {
686 1.1 christos Elf_Internal_Shdr * symtab_hdr;
687 1.1 christos struct elf_link_hash_entry ** sym_hashes;
688 1.1 christos Elf_Internal_Rela * rel;
689 1.1 christos Elf_Internal_Rela * relend;
690 1.1 christos asection *splt;
691 1.1 christos
692 1.1 christos symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
693 1.1 christos sym_hashes = elf_sym_hashes (input_bfd);
694 1.7 christos relend = relocs + input_section->reloc_count;
695 1.1 christos
696 1.1 christos splt = elf_hash_table (info)->splt;
697 1.1 christos
698 1.1 christos for (rel = relocs; rel < relend; rel ++)
699 1.1 christos {
700 1.1 christos reloc_howto_type * howto;
701 1.1 christos unsigned long r_symndx;
702 1.1 christos Elf_Internal_Sym * sym;
703 1.1 christos asection * sec;
704 1.1 christos struct elf_link_hash_entry * h;
705 1.1 christos bfd_vma relocation;
706 1.1 christos bfd_reloc_status_type r;
707 1.1 christos const char * name = NULL;
708 1.1 christos bfd_boolean unresolved_reloc = TRUE;
709 1.1 christos int r_type;
710 1.1 christos
711 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
712 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
713 1.1 christos
714 1.1 christos howto = rl78_elf_howto_table + ELF32_R_TYPE (rel->r_info);
715 1.1 christos h = NULL;
716 1.1 christos sym = NULL;
717 1.1 christos sec = NULL;
718 1.1 christos relocation = 0;
719 1.1 christos
720 1.1 christos if (r_symndx < symtab_hdr->sh_info)
721 1.1 christos {
722 1.1 christos sym = local_syms + r_symndx;
723 1.1 christos sec = local_sections [r_symndx];
724 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
725 1.1 christos
726 1.1 christos name = bfd_elf_string_from_elf_section
727 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name);
728 1.1 christos name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
729 1.1 christos }
730 1.1 christos else
731 1.1 christos {
732 1.1 christos bfd_boolean warned ATTRIBUTE_UNUSED;
733 1.1 christos bfd_boolean ignored ATTRIBUTE_UNUSED;
734 1.1 christos
735 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
736 1.1 christos r_symndx, symtab_hdr, sym_hashes, h,
737 1.1 christos sec, relocation, unresolved_reloc,
738 1.1 christos warned, ignored);
739 1.1 christos
740 1.1 christos name = h->root.root.string;
741 1.1 christos }
742 1.1 christos
743 1.1 christos if (sec != NULL && discarded_section (sec))
744 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
745 1.6 christos rel, 1, relend, howto, 0, contents);
746 1.1 christos
747 1.1 christos if (bfd_link_relocatable (info))
748 1.1 christos {
749 1.1 christos /* This is a relocatable link. We don't have to change
750 1.1 christos anything, unless the reloc is against a section symbol,
751 1.1 christos in which case we have to adjust according to where the
752 1.1 christos section symbol winds up in the output section. */
753 1.1 christos if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
754 1.1 christos rel->r_addend += sec->output_offset;
755 1.1 christos continue;
756 1.1 christos }
757 1.1 christos
758 1.1 christos switch (ELF32_R_TYPE (rel->r_info))
759 1.1 christos {
760 1.1 christos case R_RL78_DIR16S:
761 1.1 christos {
762 1.1 christos bfd_vma *plt_offset;
763 1.1 christos
764 1.1 christos if (h != NULL)
765 1.1 christos plt_offset = &h->plt.offset;
766 1.1 christos else
767 1.1 christos plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
768 1.1 christos
769 1.1 christos if (! valid_16bit_address (relocation))
770 1.1 christos {
771 1.1 christos /* If this is the first time we've processed this symbol,
772 1.1 christos fill in the plt entry with the correct symbol address. */
773 1.1 christos if ((*plt_offset & 1) == 0)
774 1.1 christos {
775 1.1 christos unsigned int x;
776 1.1 christos
777 1.1 christos x = 0x000000ec; /* br !!abs24 */
778 1.1 christos x |= (relocation << 8) & 0xffffff00;
779 1.1 christos bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
780 1.1 christos *plt_offset |= 1;
781 1.1 christos }
782 1.1 christos
783 1.1 christos relocation = (splt->output_section->vma
784 1.1 christos + splt->output_offset
785 1.1 christos + (*plt_offset & -2));
786 1.1 christos if (name)
787 1.1 christos {
788 1.1 christos char *newname = bfd_malloc (strlen(name)+5);
789 1.1 christos strcpy (newname, name);
790 1.1 christos strcat(newname, ".plt");
791 1.1 christos _bfd_generic_link_add_one_symbol (info,
792 1.1 christos input_bfd,
793 1.1 christos newname,
794 1.1 christos BSF_FUNCTION | BSF_WEAK,
795 1.1 christos splt,
796 1.1 christos (*plt_offset & -2),
797 1.1 christos 0,
798 1.1 christos 1,
799 1.1 christos 0,
800 1.1 christos 0);
801 1.1 christos }
802 1.1 christos }
803 1.1 christos }
804 1.1 christos break;
805 1.1 christos }
806 1.1 christos
807 1.1 christos if (h != NULL && h->root.type == bfd_link_hash_undefweak)
808 1.1 christos /* If the symbol is undefined and weak
809 1.1 christos then the relocation resolves to zero. */
810 1.1 christos relocation = 0;
811 1.1 christos else
812 1.1 christos {
813 1.1 christos if (howto->pc_relative)
814 1.1 christos {
815 1.1 christos relocation -= (input_section->output_section->vma
816 1.1 christos + input_section->output_offset
817 1.1 christos + rel->r_offset);
818 1.1 christos relocation -= bfd_get_reloc_size (howto);
819 1.1 christos }
820 1.1 christos
821 1.1 christos relocation += rel->r_addend;
822 1.1 christos }
823 1.1 christos
824 1.1 christos r = bfd_reloc_ok;
825 1.1 christos
826 1.1 christos #define RANGE(a,b) if (a > (long) relocation || (long) relocation > b) r = bfd_reloc_overflow
827 1.1 christos
828 1.1 christos /* Opcode relocs are always big endian. Data relocs are bi-endian. */
829 1.1 christos switch (r_type)
830 1.1 christos {
831 1.1 christos case R_RL78_NONE:
832 1.1 christos break;
833 1.1 christos
834 1.1 christos case R_RL78_RH_RELAX:
835 1.1 christos break;
836 1.1 christos
837 1.1 christos case R_RL78_DIR8S_PCREL:
838 1.1 christos RANGE (-128, 127);
839 1.1 christos OP (0) = relocation;
840 1.1 christos break;
841 1.1 christos
842 1.1 christos case R_RL78_DIR8S:
843 1.1 christos RANGE (-128, 255);
844 1.1 christos OP (0) = relocation;
845 1.1 christos break;
846 1.1 christos
847 1.1 christos case R_RL78_DIR8U:
848 1.1 christos RANGE (0, 255);
849 1.1 christos OP (0) = relocation;
850 1.1 christos break;
851 1.1 christos
852 1.1 christos case R_RL78_DIR16S_PCREL:
853 1.1 christos RANGE (-32768, 32767);
854 1.1 christos OP (0) = relocation;
855 1.1 christos OP (1) = relocation >> 8;
856 1.1 christos break;
857 1.1 christos
858 1.1 christos case R_RL78_DIR16S:
859 1.1 christos if ((relocation & 0xf0000) == 0xf0000)
860 1.1 christos relocation &= 0xffff;
861 1.1 christos RANGE (-32768, 65535);
862 1.1 christos OP (0) = relocation;
863 1.1 christos OP (1) = relocation >> 8;
864 1.1 christos break;
865 1.1 christos
866 1.1 christos case R_RL78_DIR16U:
867 1.1 christos RANGE (0, 65536);
868 1.1 christos OP (0) = relocation;
869 1.1 christos OP (1) = relocation >> 8;
870 1.1 christos break;
871 1.1 christos
872 1.1 christos case R_RL78_DIR16:
873 1.1 christos RANGE (-32768, 65536);
874 1.1 christos OP (0) = relocation;
875 1.1 christos OP (1) = relocation >> 8;
876 1.1 christos break;
877 1.1 christos
878 1.1 christos case R_RL78_DIR16_REV:
879 1.1 christos RANGE (-32768, 65536);
880 1.1 christos OP (1) = relocation;
881 1.1 christos OP (0) = relocation >> 8;
882 1.1 christos break;
883 1.1 christos
884 1.1 christos case R_RL78_DIR3U_PCREL:
885 1.1 christos RANGE (3, 10);
886 1.1 christos OP (0) &= 0xf8;
887 1.1 christos OP (0) |= relocation & 0x07;
888 1.1 christos break;
889 1.1 christos
890 1.1 christos case R_RL78_DIR24S_PCREL:
891 1.1 christos RANGE (-0x800000, 0x7fffff);
892 1.1 christos OP (0) = relocation;
893 1.1 christos OP (1) = relocation >> 8;
894 1.1 christos OP (2) = relocation >> 16;
895 1.1 christos break;
896 1.1 christos
897 1.1 christos case R_RL78_DIR24S:
898 1.1 christos RANGE (-0x800000, 0x7fffff);
899 1.1 christos OP (0) = relocation;
900 1.1 christos OP (1) = relocation >> 8;
901 1.1 christos OP (2) = relocation >> 16;
902 1.1 christos break;
903 1.1 christos
904 1.1 christos case R_RL78_DIR32:
905 1.1 christos OP (0) = relocation;
906 1.1 christos OP (1) = relocation >> 8;
907 1.1 christos OP (2) = relocation >> 16;
908 1.1 christos OP (3) = relocation >> 24;
909 1.1 christos break;
910 1.1 christos
911 1.1 christos case R_RL78_DIR32_REV:
912 1.1 christos OP (3) = relocation;
913 1.1 christos OP (2) = relocation >> 8;
914 1.1 christos OP (1) = relocation >> 16;
915 1.1 christos OP (0) = relocation >> 24;
916 1.1 christos break;
917 1.1 christos
918 1.1 christos case R_RL78_RH_SFR:
919 1.1 christos RANGE (0xfff00, 0xfffff);
920 1.1 christos OP (0) = relocation & 0xff;
921 1.1 christos break;
922 1.1 christos
923 1.1 christos case R_RL78_RH_SADDR:
924 1.1 christos RANGE (0xffe20, 0xfff1f);
925 1.1 christos OP (0) = relocation & 0xff;
926 1.1 christos break;
927 1.1 christos
928 1.1 christos /* Complex reloc handling: */
929 1.1 christos case R_RL78_ABS32:
930 1.1 christos case R_RL78_ABS32_REV:
931 1.1 christos case R_RL78_ABS24S_PCREL:
932 1.1 christos case R_RL78_ABS24S:
933 1.1 christos case R_RL78_ABS16:
934 1.1 christos case R_RL78_ABS16_REV:
935 1.1 christos case R_RL78_ABS16S_PCREL:
936 1.1 christos case R_RL78_ABS16S:
937 1.1 christos case R_RL78_ABS16U:
938 1.1 christos case R_RL78_ABS16UL:
939 1.1 christos case R_RL78_ABS16UW:
940 1.1 christos case R_RL78_ABS8:
941 1.1 christos case R_RL78_ABS8U:
942 1.1 christos case R_RL78_ABS8UL:
943 1.1 christos case R_RL78_ABS8UW:
944 1.1 christos case R_RL78_ABS8S_PCREL:
945 1.1 christos case R_RL78_ABS8S:
946 1.1 christos case R_RL78_OPneg:
947 1.1 christos case R_RL78_OPadd:
948 1.1 christos case R_RL78_OPsub:
949 1.1 christos case R_RL78_OPmul:
950 1.1 christos case R_RL78_OPdiv:
951 1.5 christos case R_RL78_OPshla:
952 1.5 christos case R_RL78_OPshra:
953 1.5 christos case R_RL78_OPsctsize:
954 1.5 christos case R_RL78_OPscttop:
955 1.5 christos case R_RL78_OPand:
956 1.5 christos case R_RL78_OPor:
957 1.5 christos case R_RL78_OPxor:
958 1.5 christos case R_RL78_OPnot:
959 1.1 christos case R_RL78_OPmod:
960 1.5 christos relocation = rl78_compute_complex_reloc (r_type, 0, input_section);
961 1.5 christos
962 1.5 christos switch (r_type)
963 1.5 christos {
964 1.5 christos case R_RL78_ABS32:
965 1.5 christos OP (0) = relocation;
966 1.5 christos OP (1) = relocation >> 8;
967 1.5 christos OP (2) = relocation >> 16;
968 1.1 christos OP (3) = relocation >> 24;
969 1.5 christos break;
970 1.5 christos
971 1.5 christos case R_RL78_ABS32_REV:
972 1.5 christos OP (3) = relocation;
973 1.5 christos OP (2) = relocation >> 8;
974 1.5 christos OP (1) = relocation >> 16;
975 1.1 christos OP (0) = relocation >> 24;
976 1.5 christos break;
977 1.5 christos
978 1.5 christos case R_RL78_ABS24S_PCREL:
979 1.5 christos case R_RL78_ABS24S:
980 1.5 christos RANGE (-0x800000, 0x7fffff);
981 1.5 christos OP (0) = relocation;
982 1.5 christos OP (1) = relocation >> 8;
983 1.1 christos OP (2) = relocation >> 16;
984 1.5 christos break;
985 1.5 christos
986 1.5 christos case R_RL78_ABS16:
987 1.5 christos RANGE (-32768, 65535);
988 1.5 christos OP (0) = relocation;
989 1.1 christos OP (1) = relocation >> 8;
990 1.5 christos break;
991 1.5 christos
992 1.5 christos case R_RL78_ABS16_REV:
993 1.5 christos RANGE (-32768, 65535);
994 1.5 christos OP (1) = relocation;
995 1.1 christos OP (0) = relocation >> 8;
996 1.5 christos break;
997 1.5 christos
998 1.5 christos case R_RL78_ABS16S_PCREL:
999 1.5 christos case R_RL78_ABS16S:
1000 1.5 christos RANGE (-32768, 32767);
1001 1.5 christos OP (0) = relocation;
1002 1.1 christos OP (1) = relocation >> 8;
1003 1.5 christos break;
1004 1.5 christos
1005 1.5 christos case R_RL78_ABS16U:
1006 1.5 christos case R_RL78_ABS16UL:
1007 1.5 christos case R_RL78_ABS16UW:
1008 1.5 christos RANGE (0, 65536);
1009 1.5 christos OP (0) = relocation;
1010 1.1 christos OP (1) = relocation >> 8;
1011 1.5 christos break;
1012 1.5 christos
1013 1.5 christos case R_RL78_ABS8:
1014 1.5 christos RANGE (-128, 255);
1015 1.1 christos OP (0) = relocation;
1016 1.5 christos break;
1017 1.5 christos
1018 1.5 christos case R_RL78_ABS8U:
1019 1.5 christos case R_RL78_ABS8UL:
1020 1.5 christos case R_RL78_ABS8UW:
1021 1.5 christos RANGE (0, 255);
1022 1.1 christos OP (0) = relocation;
1023 1.5 christos break;
1024 1.5 christos
1025 1.5 christos case R_RL78_ABS8S_PCREL:
1026 1.5 christos case R_RL78_ABS8S:
1027 1.5 christos RANGE (-128, 127);
1028 1.1 christos OP (0) = relocation;
1029 1.5 christos break;
1030 1.5 christos
1031 1.5 christos default:
1032 1.1 christos break;
1033 1.6 christos }
1034 1.5 christos break;
1035 1.5 christos
1036 1.5 christos case R_RL78_SYM:
1037 1.5 christos if (r_symndx < symtab_hdr->sh_info)
1038 1.5 christos relocation = sec->output_section->vma + sec->output_offset
1039 1.5 christos + sym->st_value + rel->r_addend;
1040 1.5 christos else if (h != NULL
1041 1.5 christos && (h->root.type == bfd_link_hash_defined
1042 1.5 christos || h->root.type == bfd_link_hash_defweak))
1043 1.5 christos relocation = h->root.u.def.value
1044 1.5 christos + sec->output_section->vma
1045 1.5 christos + sec->output_offset
1046 1.5 christos + rel->r_addend;
1047 1.5 christos else
1048 1.5 christos {
1049 1.5 christos relocation = 0;
1050 1.5 christos if (h->root.type != bfd_link_hash_undefweak)
1051 1.5 christos _bfd_error_handler (_("Warning: RL78_SYM reloc with an unknown symbol"));
1052 1.1 christos }
1053 1.1 christos (void) rl78_compute_complex_reloc (r_type, relocation, input_section);
1054 1.1 christos break;
1055 1.6 christos
1056 1.5 christos case R_RL78_OPromtop:
1057 1.1 christos relocation = get_romstart (info, input_bfd, input_section, rel->r_offset);
1058 1.1 christos (void) rl78_compute_complex_reloc (r_type, relocation, input_section);
1059 1.1 christos break;
1060 1.6 christos
1061 1.5 christos case R_RL78_OPramtop:
1062 1.1 christos relocation = get_ramstart (info, input_bfd, input_section, rel->r_offset);
1063 1.1 christos (void) rl78_compute_complex_reloc (r_type, relocation, input_section);
1064 1.1 christos break;
1065 1.1 christos
1066 1.1 christos default:
1067 1.1 christos r = bfd_reloc_notsupported;
1068 1.1 christos break;
1069 1.1 christos }
1070 1.1 christos
1071 1.1 christos if (r != bfd_reloc_ok)
1072 1.1 christos {
1073 1.1 christos const char * msg = NULL;
1074 1.1 christos
1075 1.1 christos switch (r)
1076 1.1 christos {
1077 1.1 christos case bfd_reloc_overflow:
1078 1.1 christos /* Catch the case of a missing function declaration
1079 1.7 christos and emit a more helpful error message. */
1080 1.1 christos if (r_type == R_RL78_DIR24S_PCREL)
1081 1.1 christos /* xgettext:c-format */
1082 1.6 christos msg = _("%B(%A): error: call to undefined function '%s'");
1083 1.1 christos else
1084 1.1 christos (*info->callbacks->reloc_overflow)
1085 1.1 christos (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
1086 1.1 christos input_bfd, input_section, rel->r_offset);
1087 1.1 christos break;
1088 1.6 christos
1089 1.6 christos case bfd_reloc_undefined:
1090 1.1 christos (*info->callbacks->undefined_symbol)
1091 1.1 christos (info, name, input_bfd, input_section, rel->r_offset, TRUE);
1092 1.1 christos break;
1093 1.7 christos
1094 1.1 christos case bfd_reloc_other:
1095 1.1 christos /* xgettext:c-format */
1096 1.1 christos msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
1097 1.1 christos break;
1098 1.7 christos
1099 1.1 christos case bfd_reloc_outofrange:
1100 1.1 christos /* xgettext:c-format */
1101 1.1 christos msg = _("%B(%A): internal error: out of range error");
1102 1.1 christos break;
1103 1.7 christos
1104 1.1 christos case bfd_reloc_notsupported:
1105 1.1 christos /* xgettext:c-format */
1106 1.1 christos msg = _("%B(%A): internal error: unsupported relocation error");
1107 1.1 christos break;
1108 1.7 christos
1109 1.1 christos case bfd_reloc_dangerous:
1110 1.1 christos /* xgettext:c-format */
1111 1.1 christos msg = _("%B(%A): internal error: dangerous relocation");
1112 1.1 christos break;
1113 1.7 christos
1114 1.1 christos default:
1115 1.1 christos /* xgettext:c-format */
1116 1.1 christos msg = _("%B(%A): internal error: unknown error");
1117 1.1 christos break;
1118 1.1 christos }
1119 1.1 christos
1120 1.1 christos if (msg)
1121 1.1 christos _bfd_error_handler (msg, input_bfd, input_section, name);
1122 1.1 christos }
1123 1.1 christos }
1124 1.1 christos
1125 1.1 christos return TRUE;
1126 1.1 christos }
1127 1.1 christos
1128 1.1 christos /* Function to set the ELF flag bits. */
1130 1.1 christos
1131 1.1 christos static bfd_boolean
1132 1.1 christos rl78_elf_set_private_flags (bfd * abfd, flagword flags)
1133 1.1 christos {
1134 1.1 christos elf_elfheader (abfd)->e_flags = flags;
1135 1.1 christos elf_flags_init (abfd) = TRUE;
1136 1.1 christos return TRUE;
1137 1.1 christos }
1138 1.1 christos
1139 1.1 christos static bfd_boolean no_warn_mismatch = FALSE;
1140 1.1 christos
1141 1.1 christos void bfd_elf32_rl78_set_target_flags (bfd_boolean);
1142 1.1 christos
1143 1.1 christos void
1144 1.1 christos bfd_elf32_rl78_set_target_flags (bfd_boolean user_no_warn_mismatch)
1145 1.1 christos {
1146 1.5 christos no_warn_mismatch = user_no_warn_mismatch;
1147 1.5 christos }
1148 1.5 christos
1149 1.5 christos static const char *
1150 1.5 christos rl78_cpu_name (flagword flags)
1151 1.5 christos {
1152 1.5 christos switch (flags & E_FLAG_RL78_CPU_MASK)
1153 1.5 christos {
1154 1.5 christos default: return "";
1155 1.5 christos case E_FLAG_RL78_G10: return "G10";
1156 1.5 christos case E_FLAG_RL78_G13: return "G13";
1157 1.5 christos case E_FLAG_RL78_G14: return "G14";
1158 1.1 christos }
1159 1.1 christos }
1160 1.1 christos
1161 1.1 christos /* Merge backend specific data from an object file to the output
1162 1.7 christos object file when linking. */
1163 1.1 christos
1164 1.7 christos static bfd_boolean
1165 1.1 christos rl78_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
1166 1.1 christos {
1167 1.1 christos bfd *obfd = info->output_bfd;
1168 1.1 christos flagword new_flags;
1169 1.1 christos flagword old_flags;
1170 1.1 christos bfd_boolean error = FALSE;
1171 1.1 christos
1172 1.1 christos new_flags = elf_elfheader (ibfd)->e_flags;
1173 1.1 christos old_flags = elf_elfheader (obfd)->e_flags;
1174 1.1 christos
1175 1.1 christos if (!elf_flags_init (obfd))
1176 1.1 christos {
1177 1.1 christos /* First call, no flags set. */
1178 1.1 christos elf_flags_init (obfd) = TRUE;
1179 1.1 christos elf_elfheader (obfd)->e_flags = new_flags;
1180 1.1 christos }
1181 1.1 christos else if (old_flags != new_flags)
1182 1.5 christos {
1183 1.1 christos flagword changed_flags = old_flags ^ new_flags;
1184 1.5 christos
1185 1.5 christos if (changed_flags & E_FLAG_RL78_CPU_MASK)
1186 1.1 christos {
1187 1.5 christos flagword out_cpu = old_flags & E_FLAG_RL78_CPU_MASK;
1188 1.5 christos flagword in_cpu = new_flags & E_FLAG_RL78_CPU_MASK;
1189 1.5 christos
1190 1.5 christos if (in_cpu == E_FLAG_RL78_ANY_CPU || in_cpu == out_cpu)
1191 1.5 christos /* It does not matter what new_cpu may have. */;
1192 1.5 christos else if (out_cpu == E_FLAG_RL78_ANY_CPU)
1193 1.5 christos {
1194 1.5 christos if (in_cpu == E_FLAG_RL78_G10)
1195 1.5 christos {
1196 1.5 christos /* G10 files can only be linked with other G10 files.
1197 1.5 christos If the output is set to "any" this means that it is
1198 1.5 christos a G14 file that does not use hardware multiply/divide,
1199 1.7 christos but that is still incompatible with the G10 ABI. */
1200 1.7 christos error = TRUE;
1201 1.7 christos
1202 1.7 christos _bfd_error_handler
1203 1.7 christos /* xgettext:c-format */
1204 1.5 christos (_("RL78 ABI conflict: G10 file %B cannot be linked"
1205 1.5 christos " with %s file %B"),
1206 1.5 christos ibfd, rl78_cpu_name (out_cpu), obfd);
1207 1.5 christos }
1208 1.5 christos else
1209 1.5 christos {
1210 1.5 christos old_flags &= ~ E_FLAG_RL78_CPU_MASK;
1211 1.5 christos old_flags |= in_cpu;
1212 1.1 christos elf_elfheader (obfd)->e_flags = old_flags;
1213 1.5 christos }
1214 1.5 christos }
1215 1.5 christos else
1216 1.7 christos {
1217 1.7 christos error = TRUE;
1218 1.7 christos
1219 1.7 christos _bfd_error_handler
1220 1.7 christos /* xgettext:c-format */
1221 1.5 christos (_("RL78 ABI conflict: cannot link %s file %B with %s file %B"),
1222 1.1 christos rl78_cpu_name (in_cpu), ibfd,
1223 1.3 christos rl78_cpu_name (out_cpu), obfd);
1224 1.3 christos }
1225 1.3 christos }
1226 1.7 christos
1227 1.3 christos if (changed_flags & E_FLAG_RL78_64BIT_DOUBLES)
1228 1.3 christos {
1229 1.3 christos _bfd_error_handler
1230 1.7 christos (_("RL78 merge conflict: cannot link 32-bit and 64-bit objects together"));
1231 1.7 christos
1232 1.7 christos if (old_flags & E_FLAG_RL78_64BIT_DOUBLES)
1233 1.3 christos /* xgettext:c-format */
1234 1.7 christos _bfd_error_handler (_("- %B is 64-bit, %B is not"),
1235 1.7 christos obfd, ibfd);
1236 1.7 christos else
1237 1.5 christos /* xgettext:c-format */
1238 1.6 christos _bfd_error_handler (_("- %B is 64-bit, %B is not"),
1239 1.1 christos ibfd, obfd);
1240 1.1 christos error = TRUE;
1241 1.1 christos }
1242 1.1 christos }
1243 1.1 christos
1244 1.1 christos return !error;
1245 1.1 christos }
1246 1.1 christos
1247 1.1 christos static bfd_boolean
1249 1.1 christos rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
1250 1.1 christos {
1251 1.1 christos FILE * file = (FILE *) ptr;
1252 1.1 christos flagword flags;
1253 1.1 christos
1254 1.1 christos BFD_ASSERT (abfd != NULL && ptr != NULL);
1255 1.1 christos
1256 1.1 christos /* Print normal ELF private data. */
1257 1.1 christos _bfd_elf_print_private_bfd_data (abfd, ptr);
1258 1.5 christos
1259 1.5 christos flags = elf_elfheader (abfd)->e_flags;
1260 1.1 christos fprintf (file, _("private flags = 0x%lx:"), (long) flags);
1261 1.3 christos
1262 1.3 christos if (flags & E_FLAG_RL78_CPU_MASK)
1263 1.3 christos fprintf (file, " [%s]", rl78_cpu_name (flags));
1264 1.1 christos
1265 1.1 christos if (flags & E_FLAG_RL78_64BIT_DOUBLES)
1266 1.1 christos fprintf (file, _(" [64-bit doubles]"));
1267 1.1 christos
1268 1.1 christos fputc ('\n', file);
1269 1.1 christos return TRUE;
1270 1.1 christos }
1271 1.5 christos
1272 1.1 christos /* Return the MACH for an e_flags value. */
1273 1.5 christos
1274 1.1 christos static int
1275 1.1 christos elf32_rl78_machine (bfd * abfd ATTRIBUTE_UNUSED)
1276 1.1 christos {
1277 1.1 christos return bfd_mach_rl78;
1278 1.1 christos }
1279 1.1 christos
1280 1.1 christos static bfd_boolean
1281 1.1 christos rl78_elf_object_p (bfd * abfd)
1282 1.1 christos {
1283 1.1 christos bfd_default_set_arch_mach (abfd, bfd_arch_rl78,
1284 1.1 christos elf32_rl78_machine (abfd));
1285 1.1 christos return TRUE;
1286 1.1 christos }
1287 1.1 christos
1288 1.1 christos /* support PLT for 16-bit references to 24-bit functions. */
1290 1.1 christos
1291 1.1 christos /* We support 16-bit pointers to code above 64k by generating a thunk
1292 1.1 christos below 64k containing a JMP instruction to the final address. */
1293 1.1 christos
1294 1.1 christos static bfd_boolean
1295 1.1 christos rl78_elf_check_relocs
1296 1.1 christos (bfd * abfd,
1297 1.1 christos struct bfd_link_info * info,
1298 1.1 christos asection * sec,
1299 1.1 christos const Elf_Internal_Rela * relocs)
1300 1.1 christos {
1301 1.1 christos Elf_Internal_Shdr * symtab_hdr;
1302 1.1 christos struct elf_link_hash_entry ** sym_hashes;
1303 1.1 christos const Elf_Internal_Rela * rel;
1304 1.6 christos const Elf_Internal_Rela * rel_end;
1305 1.1 christos bfd_vma *local_plt_offsets;
1306 1.1 christos asection *splt;
1307 1.1 christos bfd *dynobj;
1308 1.1 christos
1309 1.1 christos if (bfd_link_relocatable (info))
1310 1.1 christos return TRUE;
1311 1.1 christos
1312 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1313 1.1 christos sym_hashes = elf_sym_hashes (abfd);
1314 1.1 christos local_plt_offsets = elf_local_got_offsets (abfd);
1315 1.1 christos dynobj = elf_hash_table(info)->dynobj;
1316 1.1 christos
1317 1.1 christos rel_end = relocs + sec->reloc_count;
1318 1.1 christos for (rel = relocs; rel < rel_end; rel++)
1319 1.1 christos {
1320 1.1 christos struct elf_link_hash_entry *h;
1321 1.1 christos unsigned long r_symndx;
1322 1.1 christos bfd_vma *offset;
1323 1.1 christos
1324 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
1325 1.1 christos if (r_symndx < symtab_hdr->sh_info)
1326 1.1 christos h = NULL;
1327 1.1 christos else
1328 1.1 christos {
1329 1.1 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1330 1.1 christos while (h->root.type == bfd_link_hash_indirect
1331 1.1 christos || h->root.type == bfd_link_hash_warning)
1332 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link;
1333 1.1 christos
1334 1.1 christos /* PR15323, ref flags aren't set for references in the same
1335 1.1 christos object. */
1336 1.1 christos h->root.non_ir_ref = 1;
1337 1.1 christos }
1338 1.1 christos
1339 1.1 christos switch (ELF32_R_TYPE (rel->r_info))
1340 1.1 christos {
1341 1.1 christos /* This relocation describes a 16-bit pointer to a function.
1342 1.7 christos We may need to allocate a thunk in low memory; reserve memory
1343 1.1 christos for it now. */
1344 1.1 christos case R_RL78_DIR16S:
1345 1.7 christos if (dynobj == NULL)
1346 1.7 christos elf_hash_table (info)->dynobj = dynobj = abfd;
1347 1.7 christos splt = elf_hash_table (info)->splt;
1348 1.7 christos if (splt == NULL)
1349 1.7 christos {
1350 1.7 christos flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1351 1.7 christos | SEC_IN_MEMORY | SEC_LINKER_CREATED
1352 1.7 christos | SEC_READONLY | SEC_CODE);
1353 1.7 christos splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
1354 1.1 christos flags);
1355 1.1 christos elf_hash_table (info)->splt = splt;
1356 1.1 christos if (splt == NULL
1357 1.1 christos || ! bfd_set_section_alignment (dynobj, splt, 1))
1358 1.1 christos return FALSE;
1359 1.1 christos }
1360 1.1 christos
1361 1.1 christos if (h != NULL)
1362 1.1 christos offset = &h->plt.offset;
1363 1.1 christos else
1364 1.1 christos {
1365 1.1 christos if (local_plt_offsets == NULL)
1366 1.1 christos {
1367 1.1 christos size_t size;
1368 1.1 christos unsigned int i;
1369 1.1 christos
1370 1.1 christos size = symtab_hdr->sh_info * sizeof (bfd_vma);
1371 1.1 christos local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
1372 1.1 christos if (local_plt_offsets == NULL)
1373 1.1 christos return FALSE;
1374 1.1 christos elf_local_got_offsets (abfd) = local_plt_offsets;
1375 1.1 christos
1376 1.1 christos for (i = 0; i < symtab_hdr->sh_info; i++)
1377 1.1 christos local_plt_offsets[i] = (bfd_vma) -1;
1378 1.1 christos }
1379 1.1 christos offset = &local_plt_offsets[r_symndx];
1380 1.1 christos }
1381 1.1 christos
1382 1.1 christos if (*offset == (bfd_vma) -1)
1383 1.1 christos {
1384 1.1 christos *offset = splt->size;
1385 1.1 christos splt->size += 4;
1386 1.1 christos }
1387 1.1 christos break;
1388 1.1 christos }
1389 1.1 christos }
1390 1.1 christos
1391 1.1 christos return TRUE;
1392 1.1 christos }
1393 1.1 christos
1394 1.1 christos /* This must exist if dynobj is ever set. */
1395 1.1 christos
1396 1.1 christos static bfd_boolean
1397 1.1 christos rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
1398 1.1 christos struct bfd_link_info *info)
1399 1.1 christos {
1400 1.1 christos bfd *dynobj;
1401 1.1 christos asection *splt;
1402 1.1 christos
1403 1.1 christos if (!elf_hash_table (info)->dynamic_sections_created)
1404 1.1 christos return TRUE;
1405 1.1 christos
1406 1.1 christos /* As an extra sanity check, verify that all plt entries have been
1407 1.5 christos filled in. However, relaxing might have changed the relocs so
1408 1.1 christos that some plt entries don't get filled in, so we have to skip
1409 1.1 christos this check if we're relaxing. Unfortunately, check_relocs is
1410 1.7 christos called before relaxation. */
1411 1.7 christos
1412 1.7 christos if (info->relax_trip > 0)
1413 1.1 christos return TRUE;
1414 1.1 christos
1415 1.1 christos dynobj = elf_hash_table (info)->dynobj;
1416 1.1 christos splt = elf_hash_table (info)->splt;
1417 1.1 christos if (dynobj != NULL && splt != NULL)
1418 1.1 christos {
1419 1.1 christos bfd_byte *contents = splt->contents;
1420 1.1 christos unsigned int i, size = splt->size;
1421 1.1 christos
1422 1.1 christos for (i = 0; i < size; i += 4)
1423 1.1 christos {
1424 1.1 christos unsigned int x = bfd_get_32 (dynobj, contents + i);
1425 1.1 christos BFD_ASSERT (x != 0);
1426 1.1 christos }
1427 1.1 christos }
1428 1.1 christos
1429 1.1 christos return TRUE;
1430 1.1 christos }
1431 1.1 christos
1432 1.1 christos static bfd_boolean
1433 1.1 christos rl78_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
1434 1.6 christos struct bfd_link_info *info)
1435 1.1 christos {
1436 1.1 christos bfd *dynobj;
1437 1.1 christos asection *splt;
1438 1.1 christos
1439 1.1 christos if (bfd_link_relocatable (info))
1440 1.1 christos return TRUE;
1441 1.7 christos
1442 1.1 christos dynobj = elf_hash_table (info)->dynobj;
1443 1.1 christos if (dynobj == NULL)
1444 1.1 christos return TRUE;
1445 1.1 christos
1446 1.1 christos splt = elf_hash_table (info)->splt;
1447 1.1 christos BFD_ASSERT (splt != NULL);
1448 1.1 christos
1449 1.1 christos splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
1450 1.1 christos if (splt->contents == NULL)
1451 1.1 christos return FALSE;
1452 1.1 christos
1453 1.1 christos return TRUE;
1454 1.1 christos }
1455 1.1 christos
1456 1.1 christos
1457 1.1 christos
1459 1.1 christos /* Handle relaxing. */
1460 1.1 christos
1461 1.1 christos /* A subroutine of rl78_elf_relax_section. If the global symbol H
1462 1.1 christos is within the low 64k, remove any entry for it in the plt. */
1463 1.1 christos
1464 1.1 christos struct relax_plt_data
1465 1.1 christos {
1466 1.1 christos asection *splt;
1467 1.1 christos bfd_boolean *again;
1468 1.1 christos };
1469 1.1 christos
1470 1.1 christos static bfd_boolean
1471 1.1 christos rl78_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
1472 1.1 christos {
1473 1.1 christos struct relax_plt_data *data = (struct relax_plt_data *) xdata;
1474 1.1 christos
1475 1.1 christos if (h->plt.offset != (bfd_vma) -1)
1476 1.1 christos {
1477 1.1 christos bfd_vma address;
1478 1.1 christos
1479 1.1 christos if (h->root.type == bfd_link_hash_undefined
1480 1.1 christos || h->root.type == bfd_link_hash_undefweak)
1481 1.1 christos address = 0;
1482 1.1 christos else
1483 1.1 christos address = (h->root.u.def.section->output_section->vma
1484 1.1 christos + h->root.u.def.section->output_offset
1485 1.1 christos + h->root.u.def.value);
1486 1.1 christos
1487 1.1 christos if (valid_16bit_address (address))
1488 1.1 christos {
1489 1.1 christos h->plt.offset = -1;
1490 1.1 christos data->splt->size -= 4;
1491 1.1 christos *data->again = TRUE;
1492 1.1 christos }
1493 1.1 christos }
1494 1.1 christos
1495 1.1 christos return TRUE;
1496 1.1 christos }
1497 1.1 christos
1498 1.1 christos /* A subroutine of rl78_elf_relax_section. If the global symbol H
1499 1.1 christos previously had a plt entry, give it a new entry offset. */
1500 1.1 christos
1501 1.1 christos static bfd_boolean
1502 1.1 christos rl78_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
1503 1.1 christos {
1504 1.1 christos bfd_vma *entry = (bfd_vma *) xdata;
1505 1.1 christos
1506 1.1 christos if (h->plt.offset != (bfd_vma) -1)
1507 1.1 christos {
1508 1.1 christos h->plt.offset = *entry;
1509 1.1 christos *entry += 4;
1510 1.1 christos }
1511 1.1 christos
1512 1.1 christos return TRUE;
1513 1.1 christos }
1514 1.1 christos
1515 1.1 christos static bfd_boolean
1516 1.1 christos rl78_elf_relax_plt_section (bfd *dynobj,
1517 1.1 christos asection *splt,
1518 1.1 christos struct bfd_link_info *info,
1519 1.1 christos bfd_boolean *again)
1520 1.1 christos {
1521 1.6 christos struct relax_plt_data relax_plt_data;
1522 1.1 christos bfd *ibfd;
1523 1.1 christos
1524 1.1 christos /* Assume nothing changes. */
1525 1.1 christos *again = FALSE;
1526 1.1 christos
1527 1.1 christos if (bfd_link_relocatable (info))
1528 1.1 christos return TRUE;
1529 1.1 christos
1530 1.1 christos /* We only relax the .plt section at the moment. */
1531 1.1 christos if (dynobj != elf_hash_table (info)->dynobj
1532 1.1 christos || strcmp (splt->name, ".plt") != 0)
1533 1.1 christos return TRUE;
1534 1.1 christos
1535 1.1 christos /* Quick check for an empty plt. */
1536 1.1 christos if (splt->size == 0)
1537 1.1 christos return TRUE;
1538 1.1 christos
1539 1.1 christos /* Map across all global symbols; see which ones happen to
1540 1.1 christos fall in the low 64k. */
1541 1.1 christos relax_plt_data.splt = splt;
1542 1.3 christos relax_plt_data.again = again;
1543 1.1 christos elf_link_hash_traverse (elf_hash_table (info), rl78_relax_plt_check,
1544 1.1 christos &relax_plt_data);
1545 1.1 christos
1546 1.1 christos /* Likewise for local symbols, though that's somewhat less convenient
1547 1.1 christos as we have to walk the list of input bfds and swap in symbol data. */
1548 1.1 christos for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
1549 1.1 christos {
1550 1.1 christos bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1551 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1552 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
1553 1.1 christos unsigned int idx;
1554 1.1 christos
1555 1.1 christos if (! local_plt_offsets)
1556 1.1 christos continue;
1557 1.1 christos
1558 1.1 christos symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1559 1.1 christos if (symtab_hdr->sh_info != 0)
1560 1.1 christos {
1561 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1562 1.1 christos if (isymbuf == NULL)
1563 1.1 christos isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1564 1.1 christos symtab_hdr->sh_info, 0,
1565 1.1 christos NULL, NULL, NULL);
1566 1.1 christos if (isymbuf == NULL)
1567 1.1 christos return FALSE;
1568 1.1 christos }
1569 1.1 christos
1570 1.1 christos for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1571 1.1 christos {
1572 1.1 christos Elf_Internal_Sym *isym;
1573 1.1 christos asection *tsec;
1574 1.1 christos bfd_vma address;
1575 1.1 christos
1576 1.1 christos if (local_plt_offsets[idx] == (bfd_vma) -1)
1577 1.1 christos continue;
1578 1.1 christos
1579 1.1 christos isym = &isymbuf[idx];
1580 1.1 christos if (isym->st_shndx == SHN_UNDEF)
1581 1.1 christos continue;
1582 1.1 christos else if (isym->st_shndx == SHN_ABS)
1583 1.1 christos tsec = bfd_abs_section_ptr;
1584 1.1 christos else if (isym->st_shndx == SHN_COMMON)
1585 1.1 christos tsec = bfd_com_section_ptr;
1586 1.1 christos else
1587 1.1 christos tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1588 1.1 christos
1589 1.1 christos address = (tsec->output_section->vma
1590 1.1 christos + tsec->output_offset
1591 1.1 christos + isym->st_value);
1592 1.1 christos if (valid_16bit_address (address))
1593 1.1 christos {
1594 1.1 christos local_plt_offsets[idx] = -1;
1595 1.1 christos splt->size -= 4;
1596 1.1 christos *again = TRUE;
1597 1.1 christos }
1598 1.1 christos }
1599 1.1 christos
1600 1.1 christos if (isymbuf != NULL
1601 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1602 1.1 christos {
1603 1.1 christos if (! info->keep_memory)
1604 1.1 christos free (isymbuf);
1605 1.1 christos else
1606 1.1 christos {
1607 1.1 christos /* Cache the symbols for elf_link_input_bfd. */
1608 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1609 1.1 christos }
1610 1.1 christos }
1611 1.1 christos }
1612 1.1 christos
1613 1.1 christos /* If we changed anything, walk the symbols again to reallocate
1614 1.1 christos .plt entry addresses. */
1615 1.1 christos if (*again && splt->size > 0)
1616 1.3 christos {
1617 1.1 christos bfd_vma entry = 0;
1618 1.1 christos
1619 1.1 christos elf_link_hash_traverse (elf_hash_table (info),
1620 1.1 christos rl78_relax_plt_realloc, &entry);
1621 1.1 christos
1622 1.1 christos for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
1623 1.1 christos {
1624 1.1 christos bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1625 1.1 christos unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1626 1.1 christos unsigned int idx;
1627 1.1 christos
1628 1.1 christos if (! local_plt_offsets)
1629 1.1 christos continue;
1630 1.1 christos
1631 1.1 christos for (idx = 0; idx < nlocals; ++idx)
1632 1.1 christos if (local_plt_offsets[idx] != (bfd_vma) -1)
1633 1.1 christos {
1634 1.1 christos local_plt_offsets[idx] = entry;
1635 1.1 christos entry += 4;
1636 1.1 christos }
1637 1.1 christos }
1638 1.1 christos }
1639 1.1 christos
1640 1.1 christos return TRUE;
1641 1.5 christos }
1642 1.1 christos
1643 1.1 christos /* Delete some bytes from a section while relaxing. */
1644 1.1 christos
1645 1.1 christos static bfd_boolean
1646 1.1 christos elf32_rl78_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
1647 1.1 christos Elf_Internal_Rela *alignment_rel, int force_snip)
1648 1.1 christos {
1649 1.1 christos Elf_Internal_Shdr * symtab_hdr;
1650 1.1 christos unsigned int sec_shndx;
1651 1.1 christos bfd_byte * contents;
1652 1.1 christos Elf_Internal_Rela * irel;
1653 1.1 christos Elf_Internal_Rela * irelend;
1654 1.1 christos Elf_Internal_Sym * isym;
1655 1.1 christos Elf_Internal_Sym * isymend;
1656 1.1 christos bfd_vma toaddr;
1657 1.1 christos unsigned int symcount;
1658 1.1 christos struct elf_link_hash_entry ** sym_hashes;
1659 1.1 christos struct elf_link_hash_entry ** end_hashes;
1660 1.1 christos
1661 1.1 christos if (!alignment_rel)
1662 1.1 christos force_snip = 1;
1663 1.1 christos
1664 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1665 1.1 christos
1666 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
1667 1.1 christos
1668 1.1 christos /* The deletion must stop at the next alignment boundary, if
1669 1.1 christos ALIGNMENT_REL is non-NULL. */
1670 1.1 christos toaddr = sec->size;
1671 1.1 christos if (alignment_rel)
1672 1.1 christos toaddr = alignment_rel->r_offset;
1673 1.1 christos
1674 1.1 christos irel = elf_section_data (sec)->relocs;
1675 1.1 christos if (irel == NULL)
1676 1.1 christos {
1677 1.1 christos _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE);
1678 1.1 christos irel = elf_section_data (sec)->relocs;
1679 1.1 christos }
1680 1.1 christos
1681 1.1 christos irelend = irel + sec->reloc_count;
1682 1.1 christos
1683 1.1 christos /* Actually delete the bytes. */
1684 1.1 christos memmove (contents + addr, contents + addr + count,
1685 1.1 christos (size_t) (toaddr - addr - count));
1686 1.1 christos
1687 1.1 christos /* If we don't have an alignment marker to worry about, we can just
1688 1.1 christos shrink the section. Otherwise, we have to fill in the newly
1689 1.1 christos created gap with NOP insns (0x03). */
1690 1.1 christos if (force_snip)
1691 1.1 christos sec->size -= count;
1692 1.1 christos else
1693 1.1 christos memset (contents + toaddr - count, 0x03, count);
1694 1.1 christos
1695 1.1 christos /* Adjust all the relocs. */
1696 1.1 christos for (; irel && irel < irelend; irel++)
1697 1.1 christos {
1698 1.1 christos /* Get the new reloc address. */
1699 1.1 christos if (irel->r_offset > addr
1700 1.1 christos && (irel->r_offset < toaddr
1701 1.1 christos || (force_snip && irel->r_offset == toaddr)))
1702 1.1 christos irel->r_offset -= count;
1703 1.1 christos
1704 1.1 christos /* If we see an ALIGN marker at the end of the gap, we move it
1705 1.1 christos to the beginning of the gap, since marking these gaps is what
1706 1.1 christos they're for. */
1707 1.1 christos if (irel->r_offset == toaddr
1708 1.1 christos && ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
1709 1.1 christos && irel->r_addend & RL78_RELAXA_ALIGN)
1710 1.1 christos irel->r_offset -= count;
1711 1.1 christos }
1712 1.1 christos
1713 1.1 christos /* Adjust the local symbols defined in this section. */
1714 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1715 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1716 1.1 christos isymend = isym + symtab_hdr->sh_info;
1717 1.1 christos
1718 1.1 christos for (; isym < isymend; isym++)
1719 1.1 christos {
1720 1.1 christos /* If the symbol is in the range of memory we just moved, we
1721 1.1 christos have to adjust its value. */
1722 1.1 christos if (isym->st_shndx == sec_shndx
1723 1.1 christos && isym->st_value > addr
1724 1.1 christos && isym->st_value < toaddr)
1725 1.1 christos isym->st_value -= count;
1726 1.1 christos
1727 1.1 christos /* If the symbol *spans* the bytes we just deleted (i.e. it's
1728 1.1 christos *end* is in the moved bytes but it's *start* isn't), then we
1729 1.1 christos must adjust its size. */
1730 1.1 christos if (isym->st_shndx == sec_shndx
1731 1.1 christos && isym->st_value < addr
1732 1.1 christos && isym->st_value + isym->st_size > addr
1733 1.1 christos && isym->st_value + isym->st_size < toaddr)
1734 1.1 christos isym->st_size -= count;
1735 1.1 christos }
1736 1.1 christos
1737 1.1 christos /* Now adjust the global symbols defined in this section. */
1738 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1739 1.1 christos - symtab_hdr->sh_info);
1740 1.1 christos sym_hashes = elf_sym_hashes (abfd);
1741 1.1 christos end_hashes = sym_hashes + symcount;
1742 1.1 christos
1743 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++)
1744 1.1 christos {
1745 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
1746 1.1 christos
1747 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined
1748 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak)
1749 1.1 christos && sym_hash->root.u.def.section == sec)
1750 1.1 christos {
1751 1.1 christos /* As above, adjust the value if needed. */
1752 1.1 christos if (sym_hash->root.u.def.value > addr
1753 1.1 christos && sym_hash->root.u.def.value < toaddr)
1754 1.1 christos sym_hash->root.u.def.value -= count;
1755 1.1 christos
1756 1.1 christos /* As above, adjust the size if needed. */
1757 1.1 christos if (sym_hash->root.u.def.value < addr
1758 1.1 christos && sym_hash->root.u.def.value + sym_hash->size > addr
1759 1.1 christos && sym_hash->root.u.def.value + sym_hash->size < toaddr)
1760 1.1 christos sym_hash->size -= count;
1761 1.1 christos }
1762 1.1 christos }
1763 1.1 christos
1764 1.1 christos return TRUE;
1765 1.1 christos }
1766 1.1 christos
1767 1.1 christos /* Used to sort relocs by address. If relocs have the same address,
1768 1.1 christos we maintain their relative order, except that R_RL78_RH_RELAX
1769 1.1 christos alignment relocs must be the first reloc for any given address. */
1770 1.1 christos
1771 1.1 christos static void
1772 1.1 christos reloc_bubblesort (Elf_Internal_Rela * r, int count)
1773 1.1 christos {
1774 1.1 christos int i;
1775 1.1 christos bfd_boolean again;
1776 1.1 christos bfd_boolean swappit;
1777 1.1 christos
1778 1.1 christos /* This is almost a classic bubblesort. It's the slowest sort, but
1779 1.1 christos we're taking advantage of the fact that the relocations are
1780 1.1 christos mostly in order already (the assembler emits them that way) and
1781 1.1 christos we need relocs with the same address to remain in the same
1782 1.1 christos relative order. */
1783 1.1 christos again = TRUE;
1784 1.1 christos while (again)
1785 1.1 christos {
1786 1.1 christos again = FALSE;
1787 1.1 christos for (i = 0; i < count - 1; i ++)
1788 1.1 christos {
1789 1.1 christos if (r[i].r_offset > r[i + 1].r_offset)
1790 1.1 christos swappit = TRUE;
1791 1.1 christos else if (r[i].r_offset < r[i + 1].r_offset)
1792 1.1 christos swappit = FALSE;
1793 1.1 christos else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
1794 1.1 christos && (r[i + 1].r_addend & RL78_RELAXA_ALIGN))
1795 1.1 christos swappit = TRUE;
1796 1.1 christos else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
1797 1.1 christos && (r[i + 1].r_addend & RL78_RELAXA_ELIGN)
1798 1.1 christos && !(ELF32_R_TYPE (r[i].r_info) == R_RL78_RH_RELAX
1799 1.1 christos && (r[i].r_addend & RL78_RELAXA_ALIGN)))
1800 1.1 christos swappit = TRUE;
1801 1.1 christos else
1802 1.1 christos swappit = FALSE;
1803 1.1 christos
1804 1.1 christos if (swappit)
1805 1.1 christos {
1806 1.1 christos Elf_Internal_Rela tmp;
1807 1.1 christos
1808 1.1 christos tmp = r[i];
1809 1.1 christos r[i] = r[i + 1];
1810 1.1 christos r[i + 1] = tmp;
1811 1.1 christos /* If we do move a reloc back, re-scan to see if it
1812 1.1 christos needs to be moved even further back. This avoids
1813 1.1 christos most of the O(n^2) behavior for our cases. */
1814 1.1 christos if (i > 0)
1815 1.1 christos i -= 2;
1816 1.1 christos again = TRUE;
1817 1.1 christos }
1818 1.1 christos }
1819 1.5 christos }
1820 1.1 christos }
1821 1.1 christos
1822 1.1 christos
1823 1.5 christos #define OFFSET_FOR_RELOC(rel, lrel, scale) \
1824 1.5 christos rl78_offset_for_reloc (abfd, rel + 1, symtab_hdr, shndx_buf, intsyms, \
1825 1.5 christos lrel, abfd, sec, link_info, scale)
1826 1.5 christos
1827 1.5 christos static bfd_vma
1828 1.5 christos rl78_offset_for_reloc (bfd * abfd,
1829 1.5 christos Elf_Internal_Rela * rel,
1830 1.5 christos Elf_Internal_Shdr * symtab_hdr,
1831 1.5 christos Elf_External_Sym_Shndx * shndx_buf ATTRIBUTE_UNUSED,
1832 1.1 christos Elf_Internal_Sym * intsyms,
1833 1.1 christos Elf_Internal_Rela ** lrel,
1834 1.1 christos bfd * input_bfd,
1835 1.1 christos asection * input_section,
1836 1.1 christos struct bfd_link_info * info,
1837 1.1 christos int * scale)
1838 1.1 christos {
1839 1.1 christos bfd_vma symval;
1840 1.1 christos
1841 1.1 christos *scale = 1;
1842 1.5 christos
1843 1.1 christos /* REL is the first of 1..N relocations. We compute the symbol
1844 1.1 christos value for each relocation, then combine them if needed. LREL
1845 1.1 christos gets a pointer to the last relocation used. */
1846 1.1 christos while (1)
1847 1.1 christos {
1848 1.1 christos unsigned long r_type;
1849 1.1 christos
1850 1.1 christos /* Get the value of the symbol referred to by the reloc. */
1851 1.1 christos if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
1852 1.1 christos {
1853 1.1 christos /* A local symbol. */
1854 1.1 christos Elf_Internal_Sym *isym;
1855 1.1 christos asection *ssec;
1856 1.1 christos
1857 1.1 christos isym = intsyms + ELF32_R_SYM (rel->r_info);
1858 1.1 christos
1859 1.1 christos if (isym->st_shndx == SHN_UNDEF)
1860 1.1 christos ssec = bfd_und_section_ptr;
1861 1.1 christos else if (isym->st_shndx == SHN_ABS)
1862 1.1 christos ssec = bfd_abs_section_ptr;
1863 1.1 christos else if (isym->st_shndx == SHN_COMMON)
1864 1.1 christos ssec = bfd_com_section_ptr;
1865 1.1 christos else
1866 1.1 christos ssec = bfd_section_from_elf_index (abfd,
1867 1.1 christos isym->st_shndx);
1868 1.1 christos
1869 1.1 christos /* Initial symbol value. */
1870 1.1 christos symval = isym->st_value;
1871 1.1 christos
1872 1.1 christos /* GAS may have made this symbol relative to a section, in
1873 1.1 christos which case, we have to add the addend to find the
1874 1.1 christos symbol. */
1875 1.1 christos if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
1876 1.1 christos symval += rel->r_addend;
1877 1.1 christos
1878 1.1 christos if (ssec)
1879 1.1 christos {
1880 1.1 christos if ((ssec->flags & SEC_MERGE)
1881 1.1 christos && ssec->sec_info_type == SEC_INFO_TYPE_MERGE)
1882 1.1 christos symval = _bfd_merged_section_offset (abfd, & ssec,
1883 1.1 christos elf_section_data (ssec)->sec_info,
1884 1.1 christos symval);
1885 1.1 christos }
1886 1.1 christos
1887 1.1 christos /* Now make the offset relative to where the linker is putting it. */
1888 1.1 christos if (ssec)
1889 1.1 christos symval +=
1890 1.1 christos ssec->output_section->vma + ssec->output_offset;
1891 1.1 christos
1892 1.1 christos symval += rel->r_addend;
1893 1.1 christos }
1894 1.1 christos else
1895 1.1 christos {
1896 1.1 christos unsigned long indx;
1897 1.1 christos struct elf_link_hash_entry * h;
1898 1.1 christos
1899 1.1 christos /* An external symbol. */
1900 1.1 christos indx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
1901 1.1 christos h = elf_sym_hashes (abfd)[indx];
1902 1.1 christos BFD_ASSERT (h != NULL);
1903 1.1 christos
1904 1.1 christos if (h->root.type != bfd_link_hash_defined
1905 1.1 christos && h->root.type != bfd_link_hash_defweak)
1906 1.1 christos {
1907 1.1 christos /* This appears to be a reference to an undefined
1908 1.1 christos symbol. Just ignore it--it will be caught by the
1909 1.1 christos regular reloc processing. */
1910 1.1 christos if (lrel)
1911 1.1 christos *lrel = rel;
1912 1.1 christos return 0;
1913 1.1 christos }
1914 1.1 christos
1915 1.1 christos symval = (h->root.u.def.value
1916 1.5 christos + h->root.u.def.section->output_section->vma
1917 1.5 christos + h->root.u.def.section->output_offset);
1918 1.1 christos
1919 1.1 christos symval += rel->r_addend;
1920 1.5 christos }
1921 1.1 christos
1922 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
1923 1.5 christos switch (r_type)
1924 1.6 christos {
1925 1.5 christos case R_RL78_SYM:
1926 1.1 christos (void) rl78_compute_complex_reloc (r_type, symval, input_section);
1927 1.1 christos break;
1928 1.5 christos
1929 1.6 christos case R_RL78_OPromtop:
1930 1.5 christos symval = get_romstart (info, input_bfd, input_section, rel->r_offset);
1931 1.1 christos (void) rl78_compute_complex_reloc (r_type, symval, input_section);
1932 1.1 christos break;
1933 1.5 christos
1934 1.5 christos case R_RL78_OPramtop:
1935 1.1 christos symval = get_ramstart (info, input_bfd, input_section, rel->r_offset);
1936 1.1 christos (void) rl78_compute_complex_reloc (r_type, symval, input_section);
1937 1.1 christos break;
1938 1.1 christos
1939 1.1 christos case R_RL78_OPneg:
1940 1.1 christos case R_RL78_OPadd:
1941 1.1 christos case R_RL78_OPsub:
1942 1.1 christos case R_RL78_OPmul:
1943 1.1 christos case R_RL78_OPdiv:
1944 1.1 christos case R_RL78_OPshla:
1945 1.1 christos case R_RL78_OPshra:
1946 1.1 christos case R_RL78_OPsctsize:
1947 1.5 christos case R_RL78_OPscttop:
1948 1.1 christos case R_RL78_OPand:
1949 1.1 christos case R_RL78_OPor:
1950 1.1 christos case R_RL78_OPxor:
1951 1.1 christos case R_RL78_OPnot:
1952 1.1 christos case R_RL78_OPmod:
1953 1.1 christos (void) rl78_compute_complex_reloc (r_type, 0, input_section);
1954 1.1 christos break;
1955 1.5 christos
1956 1.1 christos case R_RL78_DIR16UL:
1957 1.1 christos case R_RL78_DIR8UL:
1958 1.1 christos case R_RL78_ABS16UL:
1959 1.1 christos case R_RL78_ABS8UL:
1960 1.1 christos *scale = 4;
1961 1.1 christos goto reloc_computes_value;
1962 1.5 christos
1963 1.6 christos case R_RL78_DIR16UW:
1964 1.1 christos case R_RL78_DIR8UW:
1965 1.5 christos case R_RL78_ABS16UW:
1966 1.6 christos case R_RL78_ABS8UW:
1967 1.7 christos *scale = 2;
1968 1.6 christos goto reloc_computes_value;
1969 1.6 christos
1970 1.6 christos default:
1971 1.6 christos reloc_computes_value:
1972 1.6 christos symval = rl78_compute_complex_reloc (r_type, symval, input_section);
1973 1.6 christos /* Fall through. */
1974 1.6 christos case R_RL78_DIR32:
1975 1.6 christos case R_RL78_DIR24S:
1976 1.1 christos case R_RL78_DIR16:
1977 1.1 christos case R_RL78_DIR16U:
1978 1.1 christos case R_RL78_DIR16S:
1979 1.1 christos case R_RL78_DIR24S_PCREL:
1980 1.1 christos case R_RL78_DIR16S_PCREL:
1981 1.1 christos case R_RL78_DIR8S_PCREL:
1982 1.1 christos if (lrel)
1983 1.1 christos *lrel = rel;
1984 1.1 christos return symval;
1985 1.1 christos }
1986 1.1 christos
1987 1.1 christos rel ++;
1988 1.1 christos }
1989 1.1 christos }
1990 1.1 christos
1991 1.1 christos struct {
1992 1.1 christos int prefix; /* or -1 for "no prefix" */
1993 1.1 christos int insn; /* or -1 for "end of list" */
1994 1.1 christos int insn_for_saddr; /* or -1 for "no alternative" */
1995 1.1 christos int insn_for_sfr; /* or -1 for "no alternative" */
1996 1.1 christos } relax_addr16[] = {
1997 1.1 christos { -1, 0x02, 0x06, -1 }, /* ADDW AX, !addr16 */
1998 1.1 christos { -1, 0x22, 0x26, -1 }, /* SUBW AX, !addr16 */
1999 1.1 christos { -1, 0x42, 0x46, -1 }, /* CMPW AX, !addr16 */
2000 1.1 christos { -1, 0x40, 0x4a, -1 }, /* CMP !addr16, #byte */
2001 1.1 christos
2002 1.1 christos { -1, 0x0f, 0x0b, -1 }, /* ADD A, !addr16 */
2003 1.1 christos { -1, 0x1f, 0x1b, -1 }, /* ADDC A, !addr16 */
2004 1.1 christos { -1, 0x2f, 0x2b, -1 }, /* SUB A, !addr16 */
2005 1.1 christos { -1, 0x3f, 0x3b, -1 }, /* SUBC A, !addr16 */
2006 1.1 christos { -1, 0x4f, 0x4b, -1 }, /* CMP A, !addr16 */
2007 1.1 christos { -1, 0x5f, 0x5b, -1 }, /* AND A, !addr16 */
2008 1.1 christos { -1, 0x6f, 0x6b, -1 }, /* OR A, !addr16 */
2009 1.1 christos { -1, 0x7f, 0x7b, -1 }, /* XOR A, !addr16 */
2010 1.1 christos
2011 1.1 christos { -1, 0x8f, 0x8d, 0x8e }, /* MOV A, !addr16 */
2012 1.1 christos { -1, 0x9f, 0x9d, 0x9e }, /* MOV !addr16, A */
2013 1.1 christos { -1, 0xaf, 0xad, 0xae }, /* MOVW AX, !addr16 */
2014 1.1 christos { -1, 0xbf, 0xbd, 0xbe }, /* MOVW !addr16, AX */
2015 1.1 christos { -1, 0xcf, 0xcd, 0xce }, /* MOVW !addr16, #word */
2016 1.1 christos
2017 1.1 christos { -1, 0xa0, 0xa4, -1 }, /* INC !addr16 */
2018 1.1 christos { -1, 0xa2, 0xa6, -1 }, /* INCW !addr16 */
2019 1.1 christos { -1, 0xb0, 0xb4, -1 }, /* DEC !addr16 */
2020 1.1 christos { -1, 0xb2, 0xb6, -1 }, /* DECW !addr16 */
2021 1.1 christos
2022 1.1 christos { -1, 0xd5, 0xd4, -1 }, /* CMP0 !addr16 */
2023 1.1 christos { -1, 0xe5, 0xe4, -1 }, /* ONEB !addr16 */
2024 1.1 christos { -1, 0xf5, 0xf4, -1 }, /* CLRB !addr16 */
2025 1.1 christos
2026 1.1 christos { -1, 0xd9, 0xd8, -1 }, /* MOV X, !addr16 */
2027 1.1 christos { -1, 0xe9, 0xe8, -1 }, /* MOV B, !addr16 */
2028 1.1 christos { -1, 0xf9, 0xf8, -1 }, /* MOV C, !addr16 */
2029 1.1 christos { -1, 0xdb, 0xda, -1 }, /* MOVW BC, !addr16 */
2030 1.1 christos { -1, 0xeb, 0xea, -1 }, /* MOVW DE, !addr16 */
2031 1.1 christos { -1, 0xfb, 0xfa, -1 }, /* MOVW HL, !addr16 */
2032 1.1 christos
2033 1.1 christos { 0x61, 0xaa, 0xa8, -1 }, /* XCH A, !addr16 */
2034 1.1 christos
2035 1.1 christos { 0x71, 0x00, 0x02, 0x0a }, /* SET1 !addr16.0 */
2036 1.1 christos { 0x71, 0x10, 0x12, 0x1a }, /* SET1 !addr16.0 */
2037 1.1 christos { 0x71, 0x20, 0x22, 0x2a }, /* SET1 !addr16.0 */
2038 1.1 christos { 0x71, 0x30, 0x32, 0x3a }, /* SET1 !addr16.0 */
2039 1.1 christos { 0x71, 0x40, 0x42, 0x4a }, /* SET1 !addr16.0 */
2040 1.1 christos { 0x71, 0x50, 0x52, 0x5a }, /* SET1 !addr16.0 */
2041 1.1 christos { 0x71, 0x60, 0x62, 0x6a }, /* SET1 !addr16.0 */
2042 1.1 christos { 0x71, 0x70, 0x72, 0x7a }, /* SET1 !addr16.0 */
2043 1.1 christos
2044 1.1 christos { 0x71, 0x08, 0x03, 0x0b }, /* CLR1 !addr16.0 */
2045 1.1 christos { 0x71, 0x18, 0x13, 0x1b }, /* CLR1 !addr16.0 */
2046 1.1 christos { 0x71, 0x28, 0x23, 0x2b }, /* CLR1 !addr16.0 */
2047 1.1 christos { 0x71, 0x38, 0x33, 0x3b }, /* CLR1 !addr16.0 */
2048 1.1 christos { 0x71, 0x48, 0x43, 0x4b }, /* CLR1 !addr16.0 */
2049 1.1 christos { 0x71, 0x58, 0x53, 0x5b }, /* CLR1 !addr16.0 */
2050 1.1 christos { 0x71, 0x68, 0x63, 0x6b }, /* CLR1 !addr16.0 */
2051 1.1 christos { 0x71, 0x78, 0x73, 0x7b }, /* CLR1 !addr16.0 */
2052 1.1 christos
2053 1.1 christos { -1, -1, -1, -1 }
2054 1.1 christos };
2055 1.1 christos
2056 1.1 christos /* Relax one section. */
2057 1.1 christos
2058 1.1 christos static bfd_boolean
2059 1.1 christos rl78_elf_relax_section
2060 1.1 christos (bfd * abfd,
2061 1.1 christos asection * sec,
2062 1.1 christos struct bfd_link_info * link_info,
2063 1.1 christos bfd_boolean * again)
2064 1.1 christos {
2065 1.1 christos Elf_Internal_Shdr * symtab_hdr;
2066 1.1 christos Elf_Internal_Shdr * shndx_hdr;
2067 1.1 christos Elf_Internal_Rela * internal_relocs;
2068 1.1 christos Elf_Internal_Rela * free_relocs = NULL;
2069 1.1 christos Elf_Internal_Rela * irel;
2070 1.1 christos Elf_Internal_Rela * srel;
2071 1.1 christos Elf_Internal_Rela * irelend;
2072 1.1 christos Elf_Internal_Rela * next_alignment;
2073 1.1 christos bfd_byte * contents = NULL;
2074 1.1 christos bfd_byte * free_contents = NULL;
2075 1.1 christos Elf_Internal_Sym * intsyms = NULL;
2076 1.1 christos Elf_Internal_Sym * free_intsyms = NULL;
2077 1.1 christos Elf_External_Sym_Shndx * shndx_buf = NULL;
2078 1.1 christos bfd_vma pc;
2079 1.1 christos bfd_vma symval ATTRIBUTE_UNUSED = 0;
2080 1.1 christos int pcrel ATTRIBUTE_UNUSED = 0;
2081 1.1 christos int code ATTRIBUTE_UNUSED = 0;
2082 1.1 christos int section_alignment_glue;
2083 1.1 christos int scale;
2084 1.1 christos
2085 1.1 christos if (abfd == elf_hash_table (link_info)->dynobj
2086 1.1 christos && strcmp (sec->name, ".plt") == 0)
2087 1.1 christos return rl78_elf_relax_plt_section (abfd, sec, link_info, again);
2088 1.1 christos
2089 1.6 christos /* Assume nothing changes. */
2090 1.1 christos *again = FALSE;
2091 1.1 christos
2092 1.1 christos /* We don't have to do anything for a relocatable link, if
2093 1.1 christos this section does not have relocs, or if this is not a
2094 1.1 christos code section. */
2095 1.6 christos if (bfd_link_relocatable (link_info)
2096 1.6 christos || (sec->flags & SEC_RELOC) == 0
2097 1.6 christos || sec->reloc_count == 0
2098 1.6 christos || (sec->flags & SEC_CODE) == 0)
2099 1.6 christos return TRUE;
2100 1.1 christos
2101 1.1 christos symtab_hdr = & elf_symtab_hdr (abfd);
2102 1.1 christos if (elf_symtab_shndx_list (abfd))
2103 1.1 christos shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
2104 1.1 christos else
2105 1.1 christos shndx_hdr = NULL;
2106 1.1 christos
2107 1.1 christos /* Get the section contents. */
2108 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL)
2109 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
2110 1.1 christos /* Go get them off disk. */
2111 1.1 christos else
2112 1.1 christos {
2113 1.1 christos if (! bfd_malloc_and_get_section (abfd, sec, &contents))
2114 1.1 christos goto error_return;
2115 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
2116 1.1 christos }
2117 1.1 christos
2118 1.1 christos /* Read this BFD's symbols. */
2119 1.1 christos /* Get cached copy if it exists. */
2120 1.1 christos if (symtab_hdr->contents != NULL)
2121 1.1 christos intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
2122 1.6 christos else
2123 1.1 christos {
2124 1.1 christos intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
2125 1.1 christos symtab_hdr->contents = (bfd_byte *) intsyms;
2126 1.1 christos }
2127 1.1 christos
2128 1.1 christos if (shndx_hdr && shndx_hdr->sh_size != 0)
2129 1.1 christos {
2130 1.1 christos bfd_size_type amt;
2131 1.1 christos
2132 1.1 christos amt = symtab_hdr->sh_info;
2133 1.1 christos amt *= sizeof (Elf_External_Sym_Shndx);
2134 1.1 christos shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
2135 1.1 christos if (shndx_buf == NULL)
2136 1.1 christos goto error_return;
2137 1.1 christos if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
2138 1.1 christos || bfd_bread (shndx_buf, amt, abfd) != amt)
2139 1.1 christos goto error_return;
2140 1.1 christos shndx_hdr->contents = (bfd_byte *) shndx_buf;
2141 1.1 christos }
2142 1.1 christos
2143 1.1 christos /* Get a copy of the native relocations. */
2144 1.1 christos internal_relocs = (_bfd_elf_link_read_relocs
2145 1.1 christos (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
2146 1.1 christos link_info->keep_memory));
2147 1.1 christos if (internal_relocs == NULL)
2148 1.1 christos goto error_return;
2149 1.1 christos if (! link_info->keep_memory)
2150 1.1 christos free_relocs = internal_relocs;
2151 1.1 christos
2152 1.1 christos /* The RL_ relocs must be just before the operand relocs they go
2153 1.1 christos with, so we must sort them to guarantee this. We use bubblesort
2154 1.1 christos instead of qsort so we can guarantee that relocs with the same
2155 1.1 christos address remain in the same relative order. */
2156 1.1 christos reloc_bubblesort (internal_relocs, sec->reloc_count);
2157 1.1 christos
2158 1.1 christos /* Walk through them looking for relaxing opportunities. */
2159 1.1 christos irelend = internal_relocs + sec->reloc_count;
2160 1.1 christos
2161 1.1 christos
2162 1.1 christos /* This will either be NULL or a pointer to the next alignment
2163 1.1 christos relocation. */
2164 1.1 christos next_alignment = internal_relocs;
2165 1.1 christos
2166 1.1 christos /* We calculate worst case shrinkage caused by alignment directives.
2167 1.1 christos No fool-proof, but better than either ignoring the problem or
2168 1.1 christos doing heavy duty analysis of all the alignment markers in all
2169 1.1 christos input sections. */
2170 1.1 christos section_alignment_glue = 0;
2171 1.1 christos for (irel = internal_relocs; irel < irelend; irel++)
2172 1.1 christos if (ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
2173 1.1 christos && irel->r_addend & RL78_RELAXA_ALIGN)
2174 1.1 christos {
2175 1.1 christos int this_glue = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
2176 1.1 christos
2177 1.1 christos if (section_alignment_glue < this_glue)
2178 1.1 christos section_alignment_glue = this_glue;
2179 1.1 christos }
2180 1.1 christos /* Worst case is all 0..N alignments, in order, causing 2*N-1 byte
2181 1.1 christos shrinkage. */
2182 1.1 christos section_alignment_glue *= 2;
2183 1.1 christos
2184 1.1 christos for (irel = internal_relocs; irel < irelend; irel++)
2185 1.1 christos {
2186 1.1 christos unsigned char *insn;
2187 1.1 christos int nrelocs;
2188 1.1 christos
2189 1.1 christos /* The insns we care about are all marked with one of these. */
2190 1.1 christos if (ELF32_R_TYPE (irel->r_info) != R_RL78_RH_RELAX)
2191 1.1 christos continue;
2192 1.1 christos
2193 1.1 christos if (irel->r_addend & RL78_RELAXA_ALIGN
2194 1.1 christos || next_alignment == internal_relocs)
2195 1.1 christos {
2196 1.1 christos /* When we delete bytes, we need to maintain all the alignments
2197 1.1 christos indicated. In addition, we need to be careful about relaxing
2198 1.1 christos jumps across alignment boundaries - these displacements
2199 1.1 christos *grow* when we delete bytes. For now, don't shrink
2200 1.1 christos displacements across an alignment boundary, just in case.
2201 1.1 christos Note that this only affects relocations to the same
2202 1.1 christos section. */
2203 1.1 christos next_alignment += 2;
2204 1.1 christos while (next_alignment < irelend
2205 1.1 christos && (ELF32_R_TYPE (next_alignment->r_info) != R_RL78_RH_RELAX
2206 1.1 christos || !(next_alignment->r_addend & RL78_RELAXA_ELIGN)))
2207 1.1 christos next_alignment ++;
2208 1.1 christos if (next_alignment >= irelend || next_alignment->r_offset == 0)
2209 1.1 christos next_alignment = NULL;
2210 1.1 christos }
2211 1.1 christos
2212 1.1 christos /* When we hit alignment markers, see if we've shrunk enough
2213 1.1 christos before them to reduce the gap without violating the alignment
2214 1.1 christos requirements. */
2215 1.1 christos if (irel->r_addend & RL78_RELAXA_ALIGN)
2216 1.1 christos {
2217 1.1 christos /* At this point, the next relocation *should* be the ELIGN
2218 1.1 christos end marker. */
2219 1.1 christos Elf_Internal_Rela *erel = irel + 1;
2220 1.1 christos unsigned int alignment, nbytes;
2221 1.1 christos
2222 1.1 christos if (ELF32_R_TYPE (erel->r_info) != R_RL78_RH_RELAX)
2223 1.1 christos continue;
2224 1.1 christos if (!(erel->r_addend & RL78_RELAXA_ELIGN))
2225 1.1 christos continue;
2226 1.1 christos
2227 1.1 christos alignment = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
2228 1.1 christos
2229 1.1 christos if (erel->r_offset - irel->r_offset < alignment)
2230 1.5 christos continue;
2231 1.5 christos
2232 1.1 christos nbytes = erel->r_offset - irel->r_offset;
2233 1.1 christos nbytes /= alignment;
2234 1.1 christos nbytes *= alignment;
2235 1.1 christos
2236 1.1 christos elf32_rl78_relax_delete_bytes (abfd, sec, erel->r_offset - nbytes, nbytes,
2237 1.1 christos next_alignment, erel->r_offset == sec->size);
2238 1.1 christos *again = TRUE;
2239 1.1 christos
2240 1.1 christos continue;
2241 1.1 christos }
2242 1.1 christos
2243 1.1 christos if (irel->r_addend & RL78_RELAXA_ELIGN)
2244 1.1 christos continue;
2245 1.1 christos
2246 1.1 christos insn = contents + irel->r_offset;
2247 1.1 christos
2248 1.1 christos nrelocs = irel->r_addend & RL78_RELAXA_RNUM;
2249 1.1 christos
2250 1.1 christos /* At this point, we have an insn that is a candidate for linker
2251 1.1 christos relaxation. There are NRELOCS relocs following that may be
2252 1.1 christos relaxed, although each reloc may be made of more than one
2253 1.1 christos reloc entry (such as gp-rel symbols). */
2254 1.1 christos
2255 1.1 christos /* Get the value of the symbol referred to by the reloc. Just
2256 1.1 christos in case this is the last reloc in the list, use the RL's
2257 1.1 christos addend to choose between this reloc (no addend) or the next
2258 1.1 christos (yes addend, which means at least one following reloc). */
2259 1.1 christos
2260 1.1 christos /* srel points to the "current" reloction for this insn -
2261 1.1 christos actually the last reloc for a given operand, which is the one
2262 1.1 christos we need to update. We check the relaxations in the same
2263 1.1 christos order that the relocations happen, so we'll just push it
2264 1.5 christos along as we go. */
2265 1.5 christos srel = irel;
2266 1.5 christos
2267 1.5 christos pc = sec->output_section->vma + sec->output_offset
2268 1.1 christos + srel->r_offset;
2269 1.1 christos
2270 1.1 christos #define GET_RELOC \
2271 1.1 christos BFD_ASSERT (nrelocs > 0); \
2272 1.5 christos symval = OFFSET_FOR_RELOC (srel, &srel, &scale); \
2273 1.5 christos pcrel = symval - pc + srel->r_addend; \
2274 1.5 christos nrelocs --;
2275 1.1 christos
2276 1.1 christos #define SNIPNR(offset, nbytes) \
2277 1.1 christos elf32_rl78_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0);
2278 1.1 christos
2279 1.1 christos #define SNIP(offset, nbytes, newtype) \
2280 1.1 christos SNIPNR (offset, nbytes); \
2281 1.1 christos srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype)
2282 1.1 christos
2283 1.1 christos /* The order of these bit tests must match the order that the
2284 1.1 christos relocs appear in. Since we sorted those by offset, we can
2285 1.1 christos predict them. */
2286 1.1 christos
2287 1.1 christos /*----------------------------------------------------------------------*/
2288 1.1 christos /* EF ad BR $rel8 pcrel
2289 1.1 christos ED al ah BR !abs16 abs
2290 1.1 christos EE al ah BR $!rel16 pcrel
2291 1.1 christos EC al ah as BR !!abs20 abs
2292 1.1 christos
2293 1.1 christos FD al ah CALL !abs16 abs
2294 1.1 christos FE al ah CALL $!rel16 pcrel
2295 1.1 christos FC al ah as CALL !!abs20 abs
2296 1.1 christos
2297 1.1 christos DC ad BC $rel8
2298 1.1 christos DE ad BNC $rel8
2299 1.1 christos DD ad BZ $rel8
2300 1.1 christos DF ad BNZ $rel8
2301 1.1 christos 61 C3 ad BH $rel8
2302 1.1 christos 61 D3 ad BNH $rel8
2303 1.1 christos 61 C8 EF ad SKC ; BR $rel8
2304 1.1 christos 61 D8 EF ad SKNC ; BR $rel8
2305 1.3 christos 61 E8 EF ad SKZ ; BR $rel8
2306 1.1 christos 61 F8 EF ad SKNZ ; BR $rel8
2307 1.1 christos 61 E3 EF ad SKH ; BR $rel8
2308 1.1 christos 61 F3 EF ad SKNH ; BR $rel8
2309 1.1 christos */
2310 1.1 christos
2311 1.1 christos if ((irel->r_addend & RL78_RELAXA_MASK) == RL78_RELAXA_BRA)
2312 1.1 christos {
2313 1.1 christos /* SKIP opcodes that skip non-branches will have a relax tag
2314 1.1 christos but no corresponding symbol to relax against; we just
2315 1.1 christos skip those. */
2316 1.1 christos if (irel->r_addend & RL78_RELAXA_RNUM)
2317 1.6 christos {
2318 1.6 christos GET_RELOC;
2319 1.6 christos }
2320 1.6 christos
2321 1.6 christos switch (insn[0])
2322 1.6 christos {
2323 1.6 christos case 0xdc: /* BC */
2324 1.6 christos case 0xdd: /* BZ */
2325 1.6 christos case 0xde: /* BNC */
2326 1.6 christos case 0xdf: /* BNZ */
2327 1.6 christos if (insn[1] == 0x03 && insn[2] == 0xee /* BR */
2328 1.6 christos && (srel->r_offset - irel->r_offset) > 1) /* a B<c> without its own reloc */
2329 1.6 christos {
2330 1.6 christos /* This is a "long" conditional as generated by gas:
2331 1.6 christos DC 03 EE ad.dr */
2332 1.6 christos if (pcrel < 127
2333 1.6 christos && pcrel > -127)
2334 1.6 christos {
2335 1.6 christos insn[0] ^= 0x02; /* invert conditional */
2336 1.6 christos SNIPNR (4, 1);
2337 1.6 christos SNIP (1, 2, R_RL78_DIR8S_PCREL);
2338 1.1 christos insn[1] = pcrel;
2339 1.1 christos *again = TRUE;
2340 1.1 christos }
2341 1.1 christos }
2342 1.1 christos break;
2343 1.1 christos
2344 1.1 christos case 0xec: /* BR !!abs20 */
2345 1.1 christos
2346 1.1 christos if (pcrel < 127
2347 1.1 christos && pcrel > -127)
2348 1.1 christos {
2349 1.1 christos insn[0] = 0xef;
2350 1.1 christos insn[1] = pcrel;
2351 1.1 christos SNIP (2, 2, R_RL78_DIR8S_PCREL);
2352 1.1 christos *again = TRUE;
2353 1.6 christos }
2354 1.1 christos else if (symval < 65536)
2355 1.1 christos {
2356 1.1 christos insn[0] = 0xed;
2357 1.1 christos insn[1] = symval & 0xff;
2358 1.1 christos insn[2] = symval >> 8;
2359 1.1 christos SNIP (2, 1, R_RL78_DIR16U);
2360 1.1 christos *again = TRUE;
2361 1.1 christos }
2362 1.1 christos else if (pcrel < 32767
2363 1.1 christos && pcrel > -32767)
2364 1.1 christos {
2365 1.1 christos insn[0] = 0xee;
2366 1.1 christos insn[1] = pcrel & 0xff;
2367 1.1 christos insn[2] = pcrel >> 8;
2368 1.1 christos SNIP (2, 1, R_RL78_DIR16S_PCREL);
2369 1.1 christos *again = TRUE;
2370 1.1 christos }
2371 1.1 christos break;
2372 1.1 christos
2373 1.1 christos case 0xee: /* BR $!pcrel16 */
2374 1.1 christos case 0xed: /* BR $!abs16 */
2375 1.1 christos if (pcrel < 127
2376 1.1 christos && pcrel > -127)
2377 1.1 christos {
2378 1.1 christos insn[0] = 0xef;
2379 1.1 christos insn[1] = pcrel;
2380 1.1 christos SNIP (2, 1, R_RL78_DIR8S_PCREL);
2381 1.1 christos *again = TRUE;
2382 1.1 christos }
2383 1.1 christos break;
2384 1.1 christos
2385 1.6 christos case 0xfc: /* CALL !!abs20 */
2386 1.1 christos if (symval < 65536)
2387 1.1 christos {
2388 1.1 christos insn[0] = 0xfd;
2389 1.1 christos insn[1] = symval & 0xff;
2390 1.1 christos insn[2] = symval >> 8;
2391 1.1 christos SNIP (2, 1, R_RL78_DIR16U);
2392 1.1 christos *again = TRUE;
2393 1.1 christos }
2394 1.1 christos else if (pcrel < 32767
2395 1.1 christos && pcrel > -32767)
2396 1.1 christos {
2397 1.1 christos insn[0] = 0xfe;
2398 1.1 christos insn[1] = pcrel & 0xff;
2399 1.1 christos insn[2] = pcrel >> 8;
2400 1.1 christos SNIP (2, 1, R_RL78_DIR16S_PCREL);
2401 1.1 christos *again = TRUE;
2402 1.1 christos }
2403 1.1 christos break;
2404 1.1 christos
2405 1.1 christos case 0x61: /* PREFIX */
2406 1.1 christos /* For SKIP/BR, we change the BR opcode and delete the
2407 1.1 christos SKIP. That way, we don't have to find and change the
2408 1.6 christos relocation for the BR. */
2409 1.6 christos /* Note that, for the case where we're skipping some
2410 1.6 christos other insn, we have no "other" reloc but that's safe
2411 1.6 christos here anyway. */
2412 1.6 christos switch (insn[1])
2413 1.6 christos {
2414 1.6 christos case 0xd3: /* BNH */
2415 1.6 christos case 0xc3: /* BH */
2416 1.6 christos if (insn[2] == 0x03 && insn[3] == 0xee
2417 1.6 christos && (srel->r_offset - irel->r_offset) > 2) /* a B<c> without its own reloc */
2418 1.6 christos {
2419 1.6 christos /* Another long branch by gas:
2420 1.6 christos 61 D3 03 EE ad.dr */
2421 1.6 christos if (pcrel < 127
2422 1.6 christos && pcrel > -127)
2423 1.6 christos {
2424 1.6 christos insn[1] ^= 0x10; /* invert conditional */
2425 1.6 christos SNIPNR (5, 1);
2426 1.6 christos SNIP (2, 2, R_RL78_DIR8S_PCREL);
2427 1.1 christos insn[2] = pcrel;
2428 1.1 christos *again = TRUE;
2429 1.1 christos }
2430 1.1 christos }
2431 1.1 christos break;
2432 1.1 christos
2433 1.1 christos case 0xc8: /* SKC */
2434 1.1 christos if (insn[2] == 0xef)
2435 1.1 christos {
2436 1.1 christos insn[2] = 0xde; /* BNC */
2437 1.1 christos SNIPNR (0, 2);
2438 1.1 christos }
2439 1.1 christos break;
2440 1.1 christos
2441 1.1 christos case 0xd8: /* SKNC */
2442 1.1 christos if (insn[2] == 0xef)
2443 1.1 christos {
2444 1.1 christos insn[2] = 0xdc; /* BC */
2445 1.1 christos SNIPNR (0, 2);
2446 1.1 christos }
2447 1.1 christos break;
2448 1.1 christos
2449 1.1 christos case 0xe8: /* SKZ */
2450 1.1 christos if (insn[2] == 0xef)
2451 1.1 christos {
2452 1.1 christos insn[2] = 0xdf; /* BNZ */
2453 1.1 christos SNIPNR (0, 2);
2454 1.1 christos }
2455 1.1 christos break;
2456 1.1 christos
2457 1.1 christos case 0xf8: /* SKNZ */
2458 1.1 christos if (insn[2] == 0xef)
2459 1.1 christos {
2460 1.1 christos insn[2] = 0xdd; /* BZ */
2461 1.1 christos SNIPNR (0, 2);
2462 1.1 christos }
2463 1.1 christos break;
2464 1.1 christos
2465 1.1 christos case 0xe3: /* SKH */
2466 1.1 christos if (insn[2] == 0xef)
2467 1.1 christos {
2468 1.1 christos insn[2] = 0xd3; /* BNH */
2469 1.1 christos SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
2470 1.1 christos }
2471 1.1 christos break;
2472 1.1 christos
2473 1.1 christos case 0xf3: /* SKNH */
2474 1.1 christos if (insn[2] == 0xef)
2475 1.1 christos {
2476 1.1 christos insn[2] = 0xc3; /* BH */
2477 1.1 christos SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
2478 1.1 christos }
2479 1.5 christos break;
2480 1.5 christos }
2481 1.1 christos break;
2482 1.1 christos }
2483 1.1 christos }
2484 1.1 christos
2485 1.1 christos if ((irel->r_addend & RL78_RELAXA_MASK) == RL78_RELAXA_ADDR16
2486 1.1 christos && nrelocs > 0)
2487 1.1 christos {
2488 1.1 christos /*----------------------------------------------------------------------*/
2489 1.1 christos /* Some insns have both a 16-bit address operand and an 8-bit
2490 1.1 christos variant if the address is within a special range:
2491 1.1 christos
2492 1.1 christos Address 16-bit operand SADDR range SFR range
2493 1.1 christos FFF00-FFFFF 0xff00-0xffff 0x00-0xff
2494 1.1 christos FFE20-FFF1F 0xfe20-0xff1f 0x00-0xff
2495 1.1 christos
2496 1.1 christos The RELAX_ADDR16[] array has the insn encodings for the
2497 1.1 christos 16-bit operand version, as well as the SFR and SADDR
2498 1.1 christos variants. We only need to replace the encodings and
2499 1.1 christos adjust the operand.
2500 1.1 christos
2501 1.1 christos Note: we intentionally do not attempt to decode and skip
2502 1.1 christos any ES: prefix, as adding ES: means the addr16 (likely)
2503 1.1 christos no longer points to saddr/sfr space.
2504 1.1 christos */
2505 1.1 christos
2506 1.1 christos int is_sfr;
2507 1.1 christos int is_saddr;
2508 1.1 christos int idx;
2509 1.1 christos int poff;
2510 1.1 christos
2511 1.1 christos GET_RELOC;
2512 1.1 christos
2513 1.1 christos if (0xffe20 <= symval && symval <= 0xfffff)
2514 1.1 christos {
2515 1.1 christos
2516 1.1 christos is_saddr = (0xffe20 <= symval && symval <= 0xfff1f);
2517 1.1 christos is_sfr = (0xfff00 <= symval && symval <= 0xfffff);
2518 1.1 christos
2519 1.1 christos for (idx = 0; relax_addr16[idx].insn != -1; idx ++)
2520 1.1 christos {
2521 1.1 christos if (relax_addr16[idx].prefix != -1
2522 1.1 christos && insn[0] == relax_addr16[idx].prefix
2523 1.1 christos && insn[1] == relax_addr16[idx].insn)
2524 1.1 christos {
2525 1.1 christos poff = 1;
2526 1.1 christos }
2527 1.1 christos else if (relax_addr16[idx].prefix == -1
2528 1.1 christos && insn[0] == relax_addr16[idx].insn)
2529 1.1 christos {
2530 1.1 christos poff = 0;
2531 1.1 christos }
2532 1.1 christos else
2533 1.1 christos continue;
2534 1.1 christos
2535 1.1 christos /* We have a matched insn, and poff is 0 or 1 depending
2536 1.1 christos on the base pattern size. */
2537 1.1 christos
2538 1.1 christos if (is_sfr && relax_addr16[idx].insn_for_sfr != -1)
2539 1.1 christos {
2540 1.1 christos insn[poff] = relax_addr16[idx].insn_for_sfr;
2541 1.1 christos SNIP (poff+2, 1, R_RL78_RH_SFR);
2542 1.1 christos }
2543 1.1 christos
2544 1.1 christos else if (is_saddr && relax_addr16[idx].insn_for_saddr != -1)
2545 1.1 christos {
2546 1.1 christos insn[poff] = relax_addr16[idx].insn_for_saddr;
2547 1.1 christos SNIP (poff+2, 1, R_RL78_RH_SADDR);
2548 1.1 christos }
2549 1.1 christos }
2550 1.1 christos }
2551 1.1 christos }
2552 1.1 christos /*----------------------------------------------------------------------*/
2553 1.1 christos }
2554 1.1 christos
2555 1.1 christos return TRUE;
2556 1.1 christos
2557 1.1 christos error_return:
2558 1.1 christos if (free_relocs != NULL)
2559 1.1 christos free (free_relocs);
2560 1.1 christos
2561 1.1 christos if (free_contents != NULL)
2562 1.1 christos free (free_contents);
2563 1.1 christos
2564 1.1 christos if (shndx_buf != NULL)
2565 1.1 christos {
2566 1.1 christos shndx_hdr->contents = NULL;
2567 1.1 christos free (shndx_buf);
2568 1.1 christos }
2569 1.1 christos
2570 1.1 christos if (free_intsyms != NULL)
2571 1.1 christos free (free_intsyms);
2572 1.1 christos
2573 1.1 christos return TRUE;
2574 1.1 christos }
2575 1.1 christos
2576 1.3 christos
2577 1.1 christos
2579 1.1 christos #define ELF_ARCH bfd_arch_rl78
2580 1.1 christos #define ELF_MACHINE_CODE EM_RL78
2581 1.1 christos #define ELF_MAXPAGESIZE 0x1000
2582 1.1 christos
2583 1.1 christos #define TARGET_LITTLE_SYM rl78_elf32_vec
2584 1.1 christos #define TARGET_LITTLE_NAME "elf32-rl78"
2585 1.1 christos
2586 1.1 christos #define elf_info_to_howto_rel NULL
2587 1.1 christos #define elf_info_to_howto rl78_info_to_howto_rela
2588 1.1 christos #define elf_backend_object_p rl78_elf_object_p
2589 1.1 christos #define elf_backend_relocate_section rl78_elf_relocate_section
2590 1.1 christos #define elf_symbol_leading_char ('_')
2591 1.1 christos #define elf_backend_can_gc_sections 1
2592 1.1 christos
2593 1.1 christos #define bfd_elf32_bfd_reloc_type_lookup rl78_reloc_type_lookup
2594 1.1 christos #define bfd_elf32_bfd_reloc_name_lookup rl78_reloc_name_lookup
2595 1.1 christos #define bfd_elf32_bfd_set_private_flags rl78_elf_set_private_flags
2596 1.1 christos #define bfd_elf32_bfd_merge_private_bfd_data rl78_elf_merge_private_bfd_data
2597 1.1 christos #define bfd_elf32_bfd_print_private_bfd_data rl78_elf_print_private_bfd_data
2598 1.1 christos
2599 1.1 christos #define bfd_elf32_bfd_relax_section rl78_elf_relax_section
2600 #define elf_backend_check_relocs rl78_elf_check_relocs
2601 #define elf_backend_always_size_sections \
2602 rl78_elf_always_size_sections
2603 #define elf_backend_finish_dynamic_sections \
2604 rl78_elf_finish_dynamic_sections
2605
2606 #include "elf32-target.h"
2607