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