elf-m10200.c revision 1.9 1 1.1 christos /* Matsushita 10200 specific support for 32-bit ELF
2 1.9 christos Copyright (C) 1996-2020 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of BFD, the Binary File Descriptor library.
5 1.1 christos
6 1.1 christos This program is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3 of the License, or
9 1.1 christos (at your option) any later version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; if not, write to the Free Software
18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 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
26 1.1 christos static bfd_boolean
27 1.1 christos mn10200_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
28 1.1 christos static bfd_boolean
29 1.1 christos mn10200_elf_symbol_address_p (bfd *, asection *, Elf_Internal_Sym *, bfd_vma);
30 1.1 christos
31 1.1 christos enum reloc_type
32 1.1 christos {
33 1.1 christos R_MN10200_NONE = 0,
34 1.1 christos R_MN10200_32,
35 1.1 christos R_MN10200_16,
36 1.1 christos R_MN10200_8,
37 1.1 christos R_MN10200_24,
38 1.1 christos R_MN10200_PCREL8,
39 1.1 christos R_MN10200_PCREL16,
40 1.1 christos R_MN10200_PCREL24,
41 1.1 christos R_MN10200_MAX
42 1.1 christos };
43 1.1 christos
44 1.1 christos static reloc_howto_type elf_mn10200_howto_table[] =
45 1.1 christos {
46 1.1 christos /* Dummy relocation. Does nothing. */
47 1.1 christos HOWTO (R_MN10200_NONE,
48 1.1 christos 0,
49 1.5 christos 3,
50 1.5 christos 0,
51 1.1 christos FALSE,
52 1.1 christos 0,
53 1.5 christos complain_overflow_dont,
54 1.1 christos bfd_elf_generic_reloc,
55 1.1 christos "R_MN10200_NONE",
56 1.1 christos FALSE,
57 1.1 christos 0,
58 1.1 christos 0,
59 1.1 christos FALSE),
60 1.1 christos /* Standard 32 bit reloc. */
61 1.1 christos HOWTO (R_MN10200_32,
62 1.1 christos 0,
63 1.1 christos 2,
64 1.1 christos 32,
65 1.1 christos FALSE,
66 1.1 christos 0,
67 1.1 christos complain_overflow_bitfield,
68 1.1 christos bfd_elf_generic_reloc,
69 1.1 christos "R_MN10200_32",
70 1.1 christos FALSE,
71 1.1 christos 0xffffffff,
72 1.1 christos 0xffffffff,
73 1.1 christos FALSE),
74 1.1 christos /* Standard 16 bit reloc. */
75 1.1 christos HOWTO (R_MN10200_16,
76 1.1 christos 0,
77 1.1 christos 1,
78 1.1 christos 16,
79 1.1 christos FALSE,
80 1.1 christos 0,
81 1.1 christos complain_overflow_bitfield,
82 1.1 christos bfd_elf_generic_reloc,
83 1.1 christos "R_MN10200_16",
84 1.1 christos FALSE,
85 1.1 christos 0xffff,
86 1.1 christos 0xffff,
87 1.1 christos FALSE),
88 1.1 christos /* Standard 8 bit reloc. */
89 1.1 christos HOWTO (R_MN10200_8,
90 1.1 christos 0,
91 1.1 christos 0,
92 1.1 christos 8,
93 1.1 christos FALSE,
94 1.1 christos 0,
95 1.1 christos complain_overflow_bitfield,
96 1.1 christos bfd_elf_generic_reloc,
97 1.1 christos "R_MN10200_8",
98 1.1 christos FALSE,
99 1.1 christos 0xff,
100 1.1 christos 0xff,
101 1.1 christos FALSE),
102 1.1 christos /* Standard 24 bit reloc. */
103 1.1 christos HOWTO (R_MN10200_24,
104 1.1 christos 0,
105 1.1 christos 2,
106 1.1 christos 24,
107 1.1 christos FALSE,
108 1.1 christos 0,
109 1.1 christos complain_overflow_bitfield,
110 1.1 christos bfd_elf_generic_reloc,
111 1.1 christos "R_MN10200_24",
112 1.1 christos FALSE,
113 1.1 christos 0xffffff,
114 1.1 christos 0xffffff,
115 1.1 christos FALSE),
116 1.1 christos /* Simple 8 pc-relative reloc. */
117 1.1 christos HOWTO (R_MN10200_PCREL8,
118 1.1 christos 0,
119 1.1 christos 0,
120 1.1 christos 8,
121 1.1 christos TRUE,
122 1.1 christos 0,
123 1.1 christos complain_overflow_bitfield,
124 1.1 christos bfd_elf_generic_reloc,
125 1.1 christos "R_MN10200_PCREL8",
126 1.1 christos FALSE,
127 1.1 christos 0xff,
128 1.1 christos 0xff,
129 1.1 christos TRUE),
130 1.1 christos /* Simple 16 pc-relative reloc. */
131 1.1 christos HOWTO (R_MN10200_PCREL16,
132 1.1 christos 0,
133 1.1 christos 1,
134 1.1 christos 16,
135 1.1 christos TRUE,
136 1.1 christos 0,
137 1.1 christos complain_overflow_bitfield,
138 1.1 christos bfd_elf_generic_reloc,
139 1.1 christos "R_MN10200_PCREL16",
140 1.1 christos FALSE,
141 1.1 christos 0xffff,
142 1.1 christos 0xffff,
143 1.1 christos TRUE),
144 1.1 christos /* Simple 32bit pc-relative reloc with a 1 byte adjustment
145 1.1 christos to get the pc-relative offset correct. */
146 1.1 christos HOWTO (R_MN10200_PCREL24,
147 1.1 christos 0,
148 1.1 christos 2,
149 1.1 christos 24,
150 1.1 christos TRUE,
151 1.1 christos 0,
152 1.1 christos complain_overflow_bitfield,
153 1.1 christos bfd_elf_generic_reloc,
154 1.1 christos "R_MN10200_PCREL24",
155 1.1 christos FALSE,
156 1.1 christos 0xffffff,
157 1.1 christos 0xffffff,
158 1.1 christos TRUE),
159 1.1 christos };
160 1.1 christos
161 1.1 christos struct mn10200_reloc_map
162 1.1 christos {
163 1.1 christos bfd_reloc_code_real_type bfd_reloc_val;
164 1.1 christos unsigned char elf_reloc_val;
165 1.1 christos };
166 1.1 christos
167 1.1 christos static const struct mn10200_reloc_map mn10200_reloc_map[] =
168 1.1 christos {
169 1.1 christos { BFD_RELOC_NONE , R_MN10200_NONE , },
170 1.1 christos { BFD_RELOC_32 , R_MN10200_32 , },
171 1.1 christos { BFD_RELOC_16 , R_MN10200_16 , },
172 1.1 christos { BFD_RELOC_8 , R_MN10200_8 , },
173 1.1 christos { BFD_RELOC_24 , R_MN10200_24 , },
174 1.1 christos { BFD_RELOC_8_PCREL , R_MN10200_PCREL8 , },
175 1.1 christos { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, },
176 1.1 christos { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, },
177 1.1 christos };
178 1.1 christos
179 1.1 christos static reloc_howto_type *
180 1.1 christos bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
181 1.1 christos bfd_reloc_code_real_type code)
182 1.1 christos {
183 1.1 christos unsigned int i;
184 1.1 christos
185 1.1 christos for (i = 0;
186 1.1 christos i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map);
187 1.1 christos i++)
188 1.1 christos {
189 1.1 christos if (mn10200_reloc_map[i].bfd_reloc_val == code)
190 1.1 christos return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val];
191 1.1 christos }
192 1.1 christos
193 1.1 christos return NULL;
194 1.1 christos }
195 1.1 christos
196 1.1 christos static reloc_howto_type *
197 1.1 christos bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
198 1.1 christos const char *r_name)
199 1.1 christos {
200 1.1 christos unsigned int i;
201 1.1 christos
202 1.1 christos for (i = 0;
203 1.1 christos i < (sizeof (elf_mn10200_howto_table)
204 1.1 christos / sizeof (elf_mn10200_howto_table[0]));
205 1.1 christos i++)
206 1.1 christos if (elf_mn10200_howto_table[i].name != NULL
207 1.1 christos && strcasecmp (elf_mn10200_howto_table[i].name, r_name) == 0)
208 1.1 christos return &elf_mn10200_howto_table[i];
209 1.1 christos
210 1.1 christos return NULL;
211 1.1 christos }
212 1.1 christos
213 1.1 christos /* Set the howto pointer for an MN10200 ELF reloc. */
214 1.1 christos
215 1.8 christos static bfd_boolean
216 1.8 christos mn10200_info_to_howto (bfd *abfd,
217 1.1 christos arelent *cache_ptr,
218 1.1 christos Elf_Internal_Rela *dst)
219 1.1 christos {
220 1.1 christos unsigned int r_type;
221 1.1 christos
222 1.1 christos r_type = ELF32_R_TYPE (dst->r_info);
223 1.8 christos if (r_type >= (unsigned int) R_MN10200_MAX)
224 1.8 christos {
225 1.8 christos /* xgettext:c-format */
226 1.8 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
227 1.8 christos abfd, r_type);
228 1.8 christos bfd_set_error (bfd_error_bad_value);
229 1.8 christos return FALSE;
230 1.8 christos }
231 1.9 christos
232 1.1 christos cache_ptr->howto = &elf_mn10200_howto_table[r_type];
233 1.8 christos return cache_ptr->howto != NULL;
234 1.1 christos }
235 1.1 christos
236 1.1 christos /* Perform a relocation as part of a final link. */
237 1.1 christos
238 1.1 christos static bfd_reloc_status_type
239 1.1 christos mn10200_elf_final_link_relocate (reloc_howto_type *howto,
240 1.1 christos bfd *input_bfd,
241 1.1 christos bfd *output_bfd ATTRIBUTE_UNUSED,
242 1.1 christos asection *input_section,
243 1.1 christos bfd_byte *contents,
244 1.1 christos bfd_vma offset,
245 1.1 christos bfd_vma value,
246 1.1 christos bfd_vma addend,
247 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
248 1.1 christos asection *sym_sec ATTRIBUTE_UNUSED,
249 1.1 christos int is_local ATTRIBUTE_UNUSED)
250 1.1 christos {
251 1.1 christos unsigned long r_type = howto->type;
252 1.1 christos bfd_byte *hit_data = contents + offset;
253 1.1 christos
254 1.1 christos switch (r_type)
255 1.1 christos {
256 1.1 christos
257 1.1 christos case R_MN10200_NONE:
258 1.1 christos return bfd_reloc_ok;
259 1.1 christos
260 1.1 christos case R_MN10200_32:
261 1.1 christos value += addend;
262 1.1 christos bfd_put_32 (input_bfd, value, hit_data);
263 1.1 christos return bfd_reloc_ok;
264 1.1 christos
265 1.1 christos case R_MN10200_16:
266 1.1 christos value += addend;
267 1.1 christos
268 1.1 christos if ((long) value > 0x7fff || (long) value < -0x8000)
269 1.1 christos return bfd_reloc_overflow;
270 1.1 christos
271 1.1 christos bfd_put_16 (input_bfd, value, hit_data);
272 1.1 christos return bfd_reloc_ok;
273 1.1 christos
274 1.1 christos case R_MN10200_8:
275 1.1 christos value += addend;
276 1.1 christos
277 1.1 christos if ((long) value > 0x7f || (long) value < -0x80)
278 1.1 christos return bfd_reloc_overflow;
279 1.1 christos
280 1.1 christos bfd_put_8 (input_bfd, value, hit_data);
281 1.1 christos return bfd_reloc_ok;
282 1.1 christos
283 1.1 christos case R_MN10200_24:
284 1.1 christos value += addend;
285 1.1 christos
286 1.1 christos if ((long) value > 0x7fffff || (long) value < -0x800000)
287 1.1 christos return bfd_reloc_overflow;
288 1.1 christos
289 1.1 christos value &= 0xffffff;
290 1.1 christos value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
291 1.1 christos bfd_put_32 (input_bfd, value, hit_data);
292 1.1 christos return bfd_reloc_ok;
293 1.1 christos
294 1.1 christos case R_MN10200_PCREL8:
295 1.1 christos value -= (input_section->output_section->vma
296 1.1 christos + input_section->output_offset);
297 1.1 christos value -= (offset + 1);
298 1.1 christos value += addend;
299 1.1 christos
300 1.1 christos if ((long) value > 0xff || (long) value < -0x100)
301 1.1 christos return bfd_reloc_overflow;
302 1.1 christos
303 1.1 christos bfd_put_8 (input_bfd, value, hit_data);
304 1.1 christos return bfd_reloc_ok;
305 1.1 christos
306 1.1 christos case R_MN10200_PCREL16:
307 1.1 christos value -= (input_section->output_section->vma
308 1.1 christos + input_section->output_offset);
309 1.1 christos value -= (offset + 2);
310 1.1 christos value += addend;
311 1.1 christos
312 1.1 christos if ((long) value > 0xffff || (long) value < -0x10000)
313 1.1 christos return bfd_reloc_overflow;
314 1.1 christos
315 1.1 christos bfd_put_16 (input_bfd, value, hit_data);
316 1.1 christos return bfd_reloc_ok;
317 1.1 christos
318 1.1 christos case R_MN10200_PCREL24:
319 1.1 christos value -= (input_section->output_section->vma
320 1.1 christos + input_section->output_offset);
321 1.1 christos value -= (offset + 3);
322 1.1 christos value += addend;
323 1.1 christos
324 1.1 christos if ((long) value > 0xffffff || (long) value < -0x1000000)
325 1.1 christos return bfd_reloc_overflow;
326 1.1 christos
327 1.1 christos value &= 0xffffff;
328 1.1 christos value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
329 1.1 christos bfd_put_32 (input_bfd, value, hit_data);
330 1.1 christos return bfd_reloc_ok;
331 1.1 christos
332 1.1 christos default:
333 1.1 christos return bfd_reloc_notsupported;
334 1.1 christos }
335 1.1 christos }
336 1.1 christos
337 1.1 christos /* Relocate an MN10200 ELF section. */
339 1.1 christos static bfd_boolean
340 1.1 christos mn10200_elf_relocate_section (bfd *output_bfd,
341 1.1 christos struct bfd_link_info *info,
342 1.1 christos bfd *input_bfd,
343 1.1 christos asection *input_section,
344 1.1 christos bfd_byte *contents,
345 1.1 christos Elf_Internal_Rela *relocs,
346 1.1 christos Elf_Internal_Sym *local_syms,
347 1.1 christos asection **local_sections)
348 1.1 christos {
349 1.1 christos Elf_Internal_Shdr *symtab_hdr;
350 1.1 christos struct elf_link_hash_entry **sym_hashes;
351 1.1 christos Elf_Internal_Rela *rel, *relend;
352 1.1 christos
353 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
354 1.1 christos sym_hashes = elf_sym_hashes (input_bfd);
355 1.1 christos
356 1.1 christos rel = relocs;
357 1.1 christos relend = relocs + input_section->reloc_count;
358 1.1 christos for (; rel < relend; rel++)
359 1.1 christos {
360 1.1 christos int r_type;
361 1.1 christos reloc_howto_type *howto;
362 1.1 christos unsigned long r_symndx;
363 1.1 christos Elf_Internal_Sym *sym;
364 1.1 christos asection *sec;
365 1.1 christos struct elf_link_hash_entry *h;
366 1.1 christos bfd_vma relocation;
367 1.1 christos bfd_reloc_status_type r;
368 1.1 christos
369 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
370 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
371 1.1 christos howto = elf_mn10200_howto_table + r_type;
372 1.1 christos
373 1.1 christos h = NULL;
374 1.1 christos sym = NULL;
375 1.1 christos sec = NULL;
376 1.1 christos if (r_symndx < symtab_hdr->sh_info)
377 1.1 christos {
378 1.1 christos sym = local_syms + r_symndx;
379 1.1 christos sec = local_sections[r_symndx];
380 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
381 1.1 christos }
382 1.1 christos else
383 1.1 christos {
384 1.1 christos bfd_boolean unresolved_reloc, warned, ignored;
385 1.1 christos
386 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
387 1.1 christos r_symndx, symtab_hdr, sym_hashes,
388 1.1 christos h, sec, relocation,
389 1.1 christos unresolved_reloc, warned, ignored);
390 1.1 christos }
391 1.1 christos
392 1.1 christos if (sec != NULL && discarded_section (sec))
393 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
394 1.1 christos rel, 1, relend, howto, 0, contents);
395 1.6 christos
396 1.1 christos if (bfd_link_relocatable (info))
397 1.1 christos continue;
398 1.1 christos
399 1.1 christos r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
400 1.1 christos input_section,
401 1.1 christos contents, rel->r_offset,
402 1.1 christos relocation, rel->r_addend,
403 1.1 christos info, sec, h == NULL);
404 1.1 christos
405 1.1 christos if (r != bfd_reloc_ok)
406 1.1 christos {
407 1.1 christos const char *name;
408 1.1 christos const char *msg = (const char *) 0;
409 1.1 christos
410 1.1 christos if (h != NULL)
411 1.1 christos name = h->root.root.string;
412 1.1 christos else
413 1.1 christos {
414 1.1 christos name = (bfd_elf_string_from_elf_section
415 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name));
416 1.9 christos if (name == NULL || *name == '\0')
417 1.1 christos name = bfd_section_name (sec);
418 1.1 christos }
419 1.1 christos
420 1.1 christos switch (r)
421 1.1 christos {
422 1.6 christos case bfd_reloc_overflow:
423 1.6 christos (*info->callbacks->reloc_overflow)
424 1.6 christos (info, (h ? &h->root : NULL), name, howto->name,
425 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
426 1.1 christos break;
427 1.1 christos
428 1.6 christos case bfd_reloc_undefined:
429 1.6 christos (*info->callbacks->undefined_symbol) (info, name, input_bfd,
430 1.6 christos input_section,
431 1.1 christos rel->r_offset, TRUE);
432 1.1 christos break;
433 1.1 christos
434 1.1 christos case bfd_reloc_outofrange:
435 1.1 christos msg = _("internal error: out of range error");
436 1.1 christos goto common_error;
437 1.1 christos
438 1.1 christos case bfd_reloc_notsupported:
439 1.1 christos msg = _("internal error: unsupported relocation error");
440 1.1 christos goto common_error;
441 1.1 christos
442 1.1 christos case bfd_reloc_dangerous:
443 1.1 christos msg = _("internal error: dangerous error");
444 1.1 christos goto common_error;
445 1.1 christos
446 1.1 christos default:
447 1.1 christos msg = _("internal error: unknown error");
448 1.1 christos /* fall through */
449 1.1 christos
450 1.6 christos common_error:
451 1.6 christos (*info->callbacks->warning) (info, msg, name, input_bfd,
452 1.1 christos input_section, rel->r_offset);
453 1.1 christos break;
454 1.1 christos }
455 1.1 christos }
456 1.1 christos }
457 1.1 christos
458 1.1 christos return TRUE;
459 1.1 christos }
460 1.1 christos
461 1.1 christos /* Delete some bytes from a section while relaxing. */
462 1.1 christos
463 1.1 christos static bfd_boolean
464 1.1 christos mn10200_elf_relax_delete_bytes (bfd *abfd, asection *sec,
465 1.1 christos bfd_vma addr, int count)
466 1.1 christos {
467 1.1 christos Elf_Internal_Shdr *symtab_hdr;
468 1.1 christos unsigned int sec_shndx;
469 1.1 christos bfd_byte *contents;
470 1.1 christos Elf_Internal_Rela *irel, *irelend;
471 1.1 christos bfd_vma toaddr;
472 1.1 christos Elf_Internal_Sym *isym;
473 1.1 christos Elf_Internal_Sym *isymend;
474 1.1 christos struct elf_link_hash_entry **sym_hashes;
475 1.1 christos struct elf_link_hash_entry **end_hashes;
476 1.1 christos unsigned int symcount;
477 1.1 christos
478 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
479 1.1 christos
480 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
481 1.1 christos
482 1.1 christos toaddr = sec->size;
483 1.1 christos
484 1.1 christos irel = elf_section_data (sec)->relocs;
485 1.1 christos irelend = irel + sec->reloc_count;
486 1.1 christos
487 1.1 christos /* Actually delete the bytes. */
488 1.1 christos memmove (contents + addr, contents + addr + count,
489 1.1 christos (size_t) (toaddr - addr - count));
490 1.1 christos sec->size -= count;
491 1.1 christos
492 1.1 christos /* Adjust all the relocs. */
493 1.1 christos for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
494 1.1 christos {
495 1.1 christos /* Get the new reloc address. */
496 1.1 christos if ((irel->r_offset > addr
497 1.1 christos && irel->r_offset < toaddr))
498 1.1 christos irel->r_offset -= count;
499 1.1 christos }
500 1.1 christos
501 1.1 christos /* Adjust the local symbols defined in this section. */
502 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
503 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents;
504 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
505 1.1 christos {
506 1.1 christos if (isym->st_shndx == sec_shndx
507 1.1 christos && isym->st_value > addr
508 1.1 christos && isym->st_value < toaddr)
509 1.1 christos isym->st_value -= count;
510 1.1 christos }
511 1.1 christos
512 1.1 christos /* Now adjust the global symbols defined in this section. */
513 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
514 1.1 christos - symtab_hdr->sh_info);
515 1.1 christos sym_hashes = elf_sym_hashes (abfd);
516 1.1 christos end_hashes = sym_hashes + symcount;
517 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++)
518 1.1 christos {
519 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
520 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined
521 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak)
522 1.1 christos && sym_hash->root.u.def.section == sec
523 1.1 christos && sym_hash->root.u.def.value > addr
524 1.1 christos && sym_hash->root.u.def.value < toaddr)
525 1.1 christos {
526 1.1 christos sym_hash->root.u.def.value -= count;
527 1.1 christos }
528 1.1 christos }
529 1.1 christos
530 1.1 christos return TRUE;
531 1.1 christos }
532 1.1 christos
533 1.1 christos /* This function handles relaxing for the mn10200.
534 1.1 christos
535 1.1 christos There are quite a few relaxing opportunities available on the mn10200:
536 1.8 christos
537 1.1 christos * jsr:24 -> jsr:16 2 bytes
538 1.1 christos
539 1.1 christos * jmp:24 -> jmp:16 2 bytes
540 1.1 christos * jmp:16 -> bra:8 1 byte
541 1.1 christos
542 1.1 christos * If the previous instruction is a conditional branch
543 1.1 christos around the jump/bra, we may be able to reverse its condition
544 1.1 christos and change its target to the jump's target. The jump/bra
545 1.1 christos can then be deleted. 2 bytes
546 1.1 christos
547 1.1 christos * mov abs24 -> mov abs16 2 byte savings
548 1.1 christos
549 1.1 christos * Most instructions which accept imm24 can relax to imm16 2 bytes
550 1.1 christos - Most instructions which accept imm16 can relax to imm8 1 byte
551 1.1 christos
552 1.1 christos * Most instructions which accept d24 can relax to d16 2 bytes
553 1.1 christos - Most instructions which accept d16 can relax to d8 1 byte
554 1.1 christos
555 1.1 christos abs24, imm24, d24 all look the same at the reloc level. It
556 1.1 christos might make the code simpler if we had different relocs for
557 1.1 christos the various relaxable operand types.
558 1.1 christos
559 1.1 christos We don't handle imm16->imm8 or d16->d8 as they're very rare
560 1.1 christos and somewhat more difficult to support. */
561 1.1 christos
562 1.1 christos static bfd_boolean
563 1.1 christos mn10200_elf_relax_section (bfd *abfd,
564 1.1 christos asection *sec,
565 1.1 christos struct bfd_link_info *link_info,
566 1.1 christos bfd_boolean *again)
567 1.1 christos {
568 1.1 christos Elf_Internal_Shdr *symtab_hdr;
569 1.1 christos Elf_Internal_Rela *internal_relocs;
570 1.1 christos Elf_Internal_Rela *irel, *irelend;
571 1.1 christos bfd_byte *contents = NULL;
572 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
573 1.1 christos
574 1.1 christos /* Assume nothing changes. */
575 1.1 christos *again = FALSE;
576 1.1 christos
577 1.1 christos /* We don't have to do anything for a relocatable link, if
578 1.1 christos this section does not have relocs, or if this is not a
579 1.6 christos code section. */
580 1.1 christos if (bfd_link_relocatable (link_info)
581 1.1 christos || (sec->flags & SEC_RELOC) == 0
582 1.1 christos || sec->reloc_count == 0
583 1.1 christos || (sec->flags & SEC_CODE) == 0)
584 1.1 christos return TRUE;
585 1.1 christos
586 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
587 1.1 christos
588 1.1 christos /* Get a copy of the native relocations. */
589 1.1 christos internal_relocs = (_bfd_elf_link_read_relocs
590 1.1 christos (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
591 1.1 christos link_info->keep_memory));
592 1.1 christos if (internal_relocs == NULL)
593 1.1 christos goto error_return;
594 1.1 christos
595 1.1 christos /* Walk through them looking for relaxing opportunities. */
596 1.1 christos irelend = internal_relocs + sec->reloc_count;
597 1.1 christos for (irel = internal_relocs; irel < irelend; irel++)
598 1.1 christos {
599 1.1 christos bfd_vma symval;
600 1.1 christos
601 1.1 christos /* If this isn't something that can be relaxed, then ignore
602 1.1 christos this reloc. */
603 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
604 1.1 christos || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
605 1.1 christos || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
606 1.1 christos continue;
607 1.1 christos
608 1.1 christos /* Get the section contents if we haven't done so already. */
609 1.1 christos if (contents == NULL)
610 1.1 christos {
611 1.1 christos /* Get cached copy if it exists. */
612 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL)
613 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
614 1.1 christos else
615 1.1 christos {
616 1.1 christos /* Go get them off disk. */
617 1.1 christos if (!bfd_malloc_and_get_section (abfd, sec, &contents))
618 1.1 christos goto error_return;
619 1.1 christos }
620 1.1 christos }
621 1.1 christos
622 1.1 christos /* Read this BFD's local symbols if we haven't done so already. */
623 1.1 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0)
624 1.1 christos {
625 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
626 1.1 christos if (isymbuf == NULL)
627 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
628 1.1 christos symtab_hdr->sh_info, 0,
629 1.1 christos NULL, NULL, NULL);
630 1.1 christos if (isymbuf == NULL)
631 1.1 christos goto error_return;
632 1.1 christos }
633 1.1 christos
634 1.1 christos /* Get the value of the symbol referred to by the reloc. */
635 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
636 1.1 christos {
637 1.1 christos /* A local symbol. */
638 1.1 christos Elf_Internal_Sym *isym;
639 1.1 christos asection *sym_sec;
640 1.1 christos
641 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
642 1.1 christos if (isym->st_shndx == SHN_UNDEF)
643 1.1 christos sym_sec = bfd_und_section_ptr;
644 1.1 christos else if (isym->st_shndx == SHN_ABS)
645 1.1 christos sym_sec = bfd_abs_section_ptr;
646 1.1 christos else if (isym->st_shndx == SHN_COMMON)
647 1.1 christos sym_sec = bfd_com_section_ptr;
648 1.1 christos else
649 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
650 1.1 christos symval = (isym->st_value
651 1.1 christos + sym_sec->output_section->vma
652 1.1 christos + sym_sec->output_offset);
653 1.1 christos }
654 1.1 christos else
655 1.1 christos {
656 1.1 christos unsigned long indx;
657 1.1 christos struct elf_link_hash_entry *h;
658 1.1 christos
659 1.1 christos /* An external symbol. */
660 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
661 1.1 christos h = elf_sym_hashes (abfd)[indx];
662 1.1 christos BFD_ASSERT (h != NULL);
663 1.1 christos if (h->root.type != bfd_link_hash_defined
664 1.1 christos && h->root.type != bfd_link_hash_defweak)
665 1.1 christos {
666 1.8 christos /* This appears to be a reference to an undefined
667 1.8 christos symbol. Just ignore it--it will be caught by the
668 1.1 christos regular reloc processing. */
669 1.1 christos continue;
670 1.1 christos }
671 1.1 christos
672 1.1 christos symval = (h->root.u.def.value
673 1.1 christos + h->root.u.def.section->output_section->vma
674 1.1 christos + h->root.u.def.section->output_offset);
675 1.1 christos }
676 1.1 christos
677 1.1 christos /* For simplicity of coding, we are going to modify the section
678 1.1 christos contents, the section relocs, and the BFD symbol table. We
679 1.1 christos must tell the rest of the code not to free up this
680 1.1 christos information. It would be possible to instead create a table
681 1.1 christos of changes which have to be made, as is done in coff-mips.c;
682 1.1 christos that would be more work, but would require less memory when
683 1.1 christos the linker is run. */
684 1.1 christos
685 1.1 christos /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
686 1.1 christos branch/call. */
687 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
688 1.1 christos {
689 1.1 christos bfd_vma value = symval;
690 1.1 christos
691 1.1 christos /* Deal with pc-relative gunk. */
692 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
693 1.1 christos value -= (irel->r_offset + 3);
694 1.1 christos value += irel->r_addend;
695 1.1 christos
696 1.1 christos /* See if the value will fit in 16 bits, note the high value is
697 1.1 christos 0x7fff + 2 as the target will be two bytes closer if we are
698 1.1 christos able to relax. */
699 1.1 christos if ((long) value < 0x8001 && (long) value > -0x8000)
700 1.1 christos {
701 1.1 christos unsigned char code;
702 1.1 christos
703 1.1 christos /* Get the opcode. */
704 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
705 1.1 christos
706 1.1 christos if (code != 0xe0 && code != 0xe1)
707 1.1 christos continue;
708 1.1 christos
709 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
710 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
711 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
712 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
713 1.1 christos
714 1.1 christos /* Fix the opcode. */
715 1.1 christos if (code == 0xe0)
716 1.1 christos bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
717 1.1 christos else if (code == 0xe1)
718 1.1 christos bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
719 1.1 christos
720 1.1 christos /* Fix the relocation's type. */
721 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
722 1.1 christos R_MN10200_PCREL16);
723 1.1 christos
724 1.1 christos /* The opcode got shorter too, so we have to fix the offset. */
725 1.1 christos irel->r_offset -= 1;
726 1.1 christos
727 1.1 christos /* Delete two bytes of data. */
728 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
729 1.1 christos irel->r_offset + 1, 2))
730 1.1 christos goto error_return;
731 1.1 christos
732 1.1 christos /* That will change things, so, we should relax again.
733 1.1 christos Note that this is not required, and it may be slow. */
734 1.1 christos *again = TRUE;
735 1.1 christos }
736 1.1 christos }
737 1.1 christos
738 1.1 christos /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
739 1.1 christos branch. */
740 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
741 1.1 christos {
742 1.1 christos bfd_vma value = symval;
743 1.1 christos
744 1.1 christos /* Deal with pc-relative gunk. */
745 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
746 1.1 christos value -= (irel->r_offset + 2);
747 1.1 christos value += irel->r_addend;
748 1.1 christos
749 1.1 christos /* See if the value will fit in 8 bits, note the high value is
750 1.1 christos 0x7f + 1 as the target will be one bytes closer if we are
751 1.1 christos able to relax. */
752 1.1 christos if ((long) value < 0x80 && (long) value > -0x80)
753 1.1 christos {
754 1.1 christos unsigned char code;
755 1.1 christos
756 1.1 christos /* Get the opcode. */
757 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
758 1.1 christos
759 1.1 christos if (code != 0xfc)
760 1.1 christos continue;
761 1.1 christos
762 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
763 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
764 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
765 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
766 1.1 christos
767 1.1 christos /* Fix the opcode. */
768 1.1 christos bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
769 1.1 christos
770 1.1 christos /* Fix the relocation's type. */
771 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
772 1.1 christos R_MN10200_PCREL8);
773 1.1 christos
774 1.1 christos /* Delete one byte of data. */
775 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
776 1.1 christos irel->r_offset + 1, 1))
777 1.1 christos goto error_return;
778 1.1 christos
779 1.1 christos /* That will change things, so, we should relax again.
780 1.1 christos Note that this is not required, and it may be slow. */
781 1.1 christos *again = TRUE;
782 1.1 christos }
783 1.1 christos }
784 1.1 christos
785 1.1 christos /* Try to eliminate an unconditional 8 bit pc-relative branch
786 1.1 christos which immediately follows a conditional 8 bit pc-relative
787 1.1 christos branch around the unconditional branch.
788 1.1 christos
789 1.1 christos original: new:
790 1.1 christos bCC lab1 bCC' lab2
791 1.1 christos bra lab2
792 1.1 christos lab1: lab1:
793 1.1 christos
794 1.1 christos This happens when the bCC can't reach lab2 at assembly time,
795 1.1 christos but due to other relaxations it can reach at link time. */
796 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
797 1.1 christos {
798 1.1 christos Elf_Internal_Rela *nrel;
799 1.1 christos bfd_vma value = symval;
800 1.1 christos unsigned char code;
801 1.1 christos
802 1.1 christos /* Deal with pc-relative gunk. */
803 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
804 1.1 christos value -= (irel->r_offset + 1);
805 1.1 christos value += irel->r_addend;
806 1.1 christos
807 1.1 christos /* Do nothing if this reloc is the last byte in the section. */
808 1.1 christos if (irel->r_offset == sec->size)
809 1.1 christos continue;
810 1.1 christos
811 1.1 christos /* See if the next instruction is an unconditional pc-relative
812 1.1 christos branch, more often than not this test will fail, so we
813 1.1 christos test it first to speed things up. */
814 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
815 1.1 christos if (code != 0xea)
816 1.1 christos continue;
817 1.1 christos
818 1.1 christos /* Also make sure the next relocation applies to the next
819 1.1 christos instruction and that it's a pc-relative 8 bit branch. */
820 1.1 christos nrel = irel + 1;
821 1.1 christos if (nrel == irelend
822 1.1 christos || irel->r_offset + 2 != nrel->r_offset
823 1.1 christos || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
824 1.1 christos continue;
825 1.1 christos
826 1.1 christos /* Make sure our destination immediately follows the
827 1.1 christos unconditional branch. */
828 1.1 christos if (symval != (sec->output_section->vma + sec->output_offset
829 1.1 christos + irel->r_offset + 3))
830 1.1 christos continue;
831 1.1 christos
832 1.1 christos /* Now make sure we are a conditional branch. This may not
833 1.1 christos be necessary, but why take the chance.
834 1.1 christos
835 1.1 christos Note these checks assume that R_MN10200_PCREL8 relocs
836 1.1 christos only occur on bCC and bCCx insns. If they occured
837 1.1 christos elsewhere, we'd need to know the start of this insn
838 1.1 christos for this check to be accurate. */
839 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
840 1.1 christos if (code != 0xe0 && code != 0xe1 && code != 0xe2
841 1.1 christos && code != 0xe3 && code != 0xe4 && code != 0xe5
842 1.1 christos && code != 0xe6 && code != 0xe7 && code != 0xe8
843 1.1 christos && code != 0xe9 && code != 0xec && code != 0xed
844 1.1 christos && code != 0xee && code != 0xef && code != 0xfc
845 1.1 christos && code != 0xfd && code != 0xfe && code != 0xff)
846 1.1 christos continue;
847 1.1 christos
848 1.1 christos /* We also have to be sure there is no symbol/label
849 1.1 christos at the unconditional branch. */
850 1.1 christos if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
851 1.1 christos irel->r_offset + 1))
852 1.1 christos continue;
853 1.1 christos
854 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
855 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
856 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
857 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
858 1.1 christos
859 1.1 christos /* Reverse the condition of the first branch. */
860 1.1 christos switch (code)
861 1.1 christos {
862 1.1 christos case 0xfc:
863 1.1 christos code = 0xfd;
864 1.1 christos break;
865 1.1 christos case 0xfd:
866 1.1 christos code = 0xfc;
867 1.1 christos break;
868 1.1 christos case 0xfe:
869 1.1 christos code = 0xff;
870 1.1 christos break;
871 1.1 christos case 0xff:
872 1.1 christos code = 0xfe;
873 1.1 christos break;
874 1.1 christos case 0xe8:
875 1.1 christos code = 0xe9;
876 1.1 christos break;
877 1.1 christos case 0xe9:
878 1.1 christos code = 0xe8;
879 1.1 christos break;
880 1.1 christos case 0xe0:
881 1.1 christos code = 0xe2;
882 1.1 christos break;
883 1.1 christos case 0xe2:
884 1.1 christos code = 0xe0;
885 1.1 christos break;
886 1.1 christos case 0xe3:
887 1.1 christos code = 0xe1;
888 1.1 christos break;
889 1.1 christos case 0xe1:
890 1.1 christos code = 0xe3;
891 1.1 christos break;
892 1.1 christos case 0xe4:
893 1.1 christos code = 0xe6;
894 1.1 christos break;
895 1.1 christos case 0xe6:
896 1.1 christos code = 0xe4;
897 1.1 christos break;
898 1.1 christos case 0xe7:
899 1.1 christos code = 0xe5;
900 1.1 christos break;
901 1.1 christos case 0xe5:
902 1.1 christos code = 0xe7;
903 1.1 christos break;
904 1.1 christos case 0xec:
905 1.1 christos code = 0xed;
906 1.1 christos break;
907 1.1 christos case 0xed:
908 1.1 christos code = 0xec;
909 1.1 christos break;
910 1.1 christos case 0xee:
911 1.1 christos code = 0xef;
912 1.1 christos break;
913 1.1 christos case 0xef:
914 1.1 christos code = 0xee;
915 1.1 christos break;
916 1.1 christos }
917 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
918 1.1 christos
919 1.1 christos /* Set the reloc type and symbol for the first branch
920 1.1 christos from the second branch. */
921 1.1 christos irel->r_info = nrel->r_info;
922 1.1 christos
923 1.1 christos /* Make the reloc for the second branch a null reloc. */
924 1.1 christos nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
925 1.1 christos R_MN10200_NONE);
926 1.1 christos
927 1.1 christos /* Delete two bytes of data. */
928 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
929 1.1 christos irel->r_offset + 1, 2))
930 1.1 christos goto error_return;
931 1.1 christos
932 1.1 christos /* That will change things, so, we should relax again.
933 1.1 christos Note that this is not required, and it may be slow. */
934 1.1 christos *again = TRUE;
935 1.1 christos }
936 1.1 christos
937 1.1 christos /* Try to turn a 24bit immediate, displacement or absolute address
938 1.1 christos into a 16bit immediate, displacement or absolute address. */
939 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
940 1.1 christos {
941 1.1 christos bfd_vma value = symval;
942 1.1 christos
943 1.1 christos /* See if the value will fit in 16 bits.
944 1.1 christos We allow any 16bit match here. We prune those we can't
945 1.1 christos handle below. */
946 1.1 christos if ((long) value < 0x7fff && (long) value > -0x8000)
947 1.1 christos {
948 1.1 christos unsigned char code;
949 1.1 christos
950 1.1 christos /* All insns which have 24bit operands are 5 bytes long,
951 1.1 christos the first byte will always be 0xf4, but we double check
952 1.1 christos it just in case. */
953 1.1 christos
954 1.1 christos /* Get the first opcode. */
955 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
956 1.1 christos
957 1.1 christos if (code != 0xf4)
958 1.1 christos continue;
959 1.1 christos
960 1.1 christos /* Get the second opcode. */
961 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
962 1.1 christos
963 1.1 christos switch (code & 0xfc)
964 1.1 christos {
965 1.1 christos /* mov imm24,dn -> mov imm16,dn */
966 1.1 christos case 0x70:
967 1.1 christos /* Not safe if the high bit is on as relaxing may
968 1.1 christos move the value out of high mem and thus not fit
969 1.1 christos in a signed 16bit value. */
970 1.1 christos if (value & 0x8000)
971 1.1 christos continue;
972 1.1 christos
973 1.1 christos /* Note that we've changed the relocation contents, etc. */
974 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
975 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
976 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
977 1.1 christos
978 1.1 christos /* Fix the opcode. */
979 1.1 christos bfd_put_8 (abfd, 0xf8 + (code & 0x03),
980 1.1 christos contents + irel->r_offset - 2);
981 1.1 christos
982 1.1 christos /* Fix the relocation's type. */
983 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
984 1.1 christos R_MN10200_16);
985 1.1 christos
986 1.1 christos /* The opcode got shorter too, so we have to fix the
987 1.1 christos offset. */
988 1.1 christos irel->r_offset -= 1;
989 1.1 christos
990 1.1 christos /* Delete two bytes of data. */
991 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
992 1.1 christos irel->r_offset + 1, 2))
993 1.1 christos goto error_return;
994 1.1 christos
995 1.1 christos /* That will change things, so, we should relax again.
996 1.1 christos Note that this is not required, and it may be slow. */
997 1.1 christos *again = TRUE;
998 1.1 christos break;
999 1.1 christos
1000 1.1 christos /* mov imm24,an -> mov imm16,an
1001 1.1 christos cmp imm24,an -> cmp imm16,an
1002 1.1 christos mov (abs24),dn -> mov (abs16),dn
1003 1.1 christos mov dn,(abs24) -> mov dn,(abs16)
1004 1.1 christos movb dn,(abs24) -> movb dn,(abs16)
1005 1.1 christos movbu (abs24),dn -> movbu (abs16),dn */
1006 1.1 christos case 0x74:
1007 1.1 christos case 0x7c:
1008 1.1 christos case 0xc0:
1009 1.1 christos case 0x40:
1010 1.1 christos case 0x44:
1011 1.1 christos case 0xc8:
1012 1.1 christos /* Note that we've changed the relocation contents, etc. */
1013 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1014 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1015 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1016 1.1 christos
1017 1.1 christos if ((code & 0xfc) == 0x74)
1018 1.1 christos code = 0xdc + (code & 0x03);
1019 1.1 christos else if ((code & 0xfc) == 0x7c)
1020 1.1 christos code = 0xec + (code & 0x03);
1021 1.1 christos else if ((code & 0xfc) == 0xc0)
1022 1.1 christos code = 0xc8 + (code & 0x03);
1023 1.1 christos else if ((code & 0xfc) == 0x40)
1024 1.1 christos code = 0xc0 + (code & 0x03);
1025 1.1 christos else if ((code & 0xfc) == 0x44)
1026 1.1 christos code = 0xc4 + (code & 0x03);
1027 1.1 christos else if ((code & 0xfc) == 0xc8)
1028 1.1 christos code = 0xcc + (code & 0x03);
1029 1.1 christos
1030 1.1 christos /* Fix the opcode. */
1031 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
1032 1.1 christos
1033 1.1 christos /* Fix the relocation's type. */
1034 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1035 1.1 christos R_MN10200_16);
1036 1.1 christos
1037 1.1 christos /* The opcode got shorter too, so we have to fix the
1038 1.1 christos offset. */
1039 1.1 christos irel->r_offset -= 1;
1040 1.1 christos
1041 1.1 christos /* Delete two bytes of data. */
1042 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1043 1.1 christos irel->r_offset + 1, 2))
1044 1.1 christos goto error_return;
1045 1.1 christos
1046 1.1 christos /* That will change things, so, we should relax again.
1047 1.1 christos Note that this is not required, and it may be slow. */
1048 1.1 christos *again = TRUE;
1049 1.1 christos break;
1050 1.1 christos
1051 1.1 christos /* cmp imm24,dn -> cmp imm16,dn
1052 1.1 christos mov (abs24),an -> mov (abs16),an
1053 1.1 christos mov an,(abs24) -> mov an,(abs16)
1054 1.1 christos add imm24,dn -> add imm16,dn
1055 1.1 christos add imm24,an -> add imm16,an
1056 1.1 christos sub imm24,dn -> sub imm16,dn
1057 1.1 christos sub imm24,an -> sub imm16,an
1058 1.1 christos And all d24->d16 in memory ops. */
1059 1.1 christos case 0x78:
1060 1.1 christos case 0xd0:
1061 1.1 christos case 0x50:
1062 1.1 christos case 0x60:
1063 1.1 christos case 0x64:
1064 1.1 christos case 0x68:
1065 1.1 christos case 0x6c:
1066 1.1 christos case 0x80:
1067 1.1 christos case 0xf0:
1068 1.1 christos case 0x00:
1069 1.1 christos case 0x10:
1070 1.1 christos case 0xb0:
1071 1.1 christos case 0x30:
1072 1.1 christos case 0xa0:
1073 1.1 christos case 0x20:
1074 1.1 christos case 0x90:
1075 1.1 christos /* Not safe if the high bit is on as relaxing may
1076 1.1 christos move the value out of high mem and thus not fit
1077 1.1 christos in a signed 16bit value. */
1078 1.1 christos if (((code & 0xfc) == 0x78
1079 1.1 christos || (code & 0xfc) == 0x60
1080 1.1 christos || (code & 0xfc) == 0x64
1081 1.1 christos || (code & 0xfc) == 0x68
1082 1.1 christos || (code & 0xfc) == 0x6c
1083 1.1 christos || (code & 0xfc) == 0x80
1084 1.1 christos || (code & 0xfc) == 0xf0
1085 1.1 christos || (code & 0xfc) == 0x00
1086 1.1 christos || (code & 0xfc) == 0x10
1087 1.1 christos || (code & 0xfc) == 0xb0
1088 1.1 christos || (code & 0xfc) == 0x30
1089 1.1 christos || (code & 0xfc) == 0xa0
1090 1.1 christos || (code & 0xfc) == 0x20
1091 1.1 christos || (code & 0xfc) == 0x90)
1092 1.1 christos && (value & 0x8000) != 0)
1093 1.1 christos continue;
1094 1.1 christos
1095 1.1 christos /* Note that we've changed the relocation contents, etc. */
1096 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1097 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1098 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1099 1.1 christos
1100 1.1 christos /* Fix the opcode. */
1101 1.1 christos bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
1102 1.1 christos
1103 1.1 christos if ((code & 0xfc) == 0x78)
1104 1.1 christos code = 0x48 + (code & 0x03);
1105 1.1 christos else if ((code & 0xfc) == 0xd0)
1106 1.1 christos code = 0x30 + (code & 0x03);
1107 1.1 christos else if ((code & 0xfc) == 0x50)
1108 1.1 christos code = 0x20 + (code & 0x03);
1109 1.1 christos else if ((code & 0xfc) == 0x60)
1110 1.1 christos code = 0x18 + (code & 0x03);
1111 1.1 christos else if ((code & 0xfc) == 0x64)
1112 1.1 christos code = 0x08 + (code & 0x03);
1113 1.1 christos else if ((code & 0xfc) == 0x68)
1114 1.1 christos code = 0x1c + (code & 0x03);
1115 1.1 christos else if ((code & 0xfc) == 0x6c)
1116 1.1 christos code = 0x0c + (code & 0x03);
1117 1.1 christos else if ((code & 0xfc) == 0x80)
1118 1.1 christos code = 0xc0 + (code & 0x07);
1119 1.1 christos else if ((code & 0xfc) == 0xf0)
1120 1.1 christos code = 0xb0 + (code & 0x07);
1121 1.1 christos else if ((code & 0xfc) == 0x00)
1122 1.1 christos code = 0x80 + (code & 0x07);
1123 1.1 christos else if ((code & 0xfc) == 0x10)
1124 1.1 christos code = 0xa0 + (code & 0x07);
1125 1.1 christos else if ((code & 0xfc) == 0xb0)
1126 1.1 christos code = 0x70 + (code & 0x07);
1127 1.1 christos else if ((code & 0xfc) == 0x30)
1128 1.1 christos code = 0x60 + (code & 0x07);
1129 1.1 christos else if ((code & 0xfc) == 0xa0)
1130 1.1 christos code = 0xd0 + (code & 0x07);
1131 1.1 christos else if ((code & 0xfc) == 0x20)
1132 1.1 christos code = 0x90 + (code & 0x07);
1133 1.1 christos else if ((code & 0xfc) == 0x90)
1134 1.1 christos code = 0x50 + (code & 0x07);
1135 1.1 christos
1136 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1137 1.1 christos
1138 1.1 christos /* Fix the relocation's type. */
1139 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1140 1.1 christos R_MN10200_16);
1141 1.1 christos
1142 1.1 christos /* Delete one bytes of data. */
1143 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1144 1.1 christos irel->r_offset + 2, 1))
1145 1.1 christos goto error_return;
1146 1.1 christos
1147 1.1 christos /* That will change things, so, we should relax again.
1148 1.1 christos Note that this is not required, and it may be slow. */
1149 1.1 christos *again = TRUE;
1150 1.1 christos break;
1151 1.1 christos
1152 1.1 christos /* movb (abs24),dn ->movbu (abs16),dn extxb bn */
1153 1.1 christos case 0xc4:
1154 1.1 christos /* Note that we've changed the reldection contents, etc. */
1155 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1156 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1157 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1158 1.1 christos
1159 1.1 christos bfd_put_8 (abfd, 0xcc + (code & 0x03),
1160 1.1 christos contents + irel->r_offset - 2);
1161 1.1 christos
1162 1.1 christos bfd_put_8 (abfd, 0xb8 + (code & 0x03),
1163 1.1 christos contents + irel->r_offset - 1);
1164 1.1 christos
1165 1.1 christos /* Fix the relocation's type. */
1166 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1167 1.1 christos R_MN10200_16);
1168 1.1 christos
1169 1.1 christos /* The reloc will be applied one byte in front of its
1170 1.1 christos current location. */
1171 1.1 christos irel->r_offset -= 1;
1172 1.1 christos
1173 1.1 christos /* Delete one bytes of data. */
1174 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1175 1.1 christos irel->r_offset + 2, 1))
1176 1.1 christos goto error_return;
1177 1.1 christos
1178 1.1 christos /* That will change things, so, we should relax again.
1179 1.1 christos Note that this is not required, and it may be slow. */
1180 1.1 christos *again = TRUE;
1181 1.1 christos break;
1182 1.1 christos }
1183 1.1 christos }
1184 1.1 christos }
1185 1.1 christos }
1186 1.1 christos
1187 1.1 christos if (isymbuf != NULL
1188 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1189 1.1 christos {
1190 1.1 christos if (! link_info->keep_memory)
1191 1.1 christos free (isymbuf);
1192 1.1 christos else
1193 1.1 christos {
1194 1.1 christos /* Cache the symbols for elf_link_input_bfd. */
1195 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1196 1.1 christos }
1197 1.1 christos }
1198 1.1 christos
1199 1.1 christos if (contents != NULL
1200 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents)
1201 1.1 christos {
1202 1.1 christos if (! link_info->keep_memory)
1203 1.1 christos free (contents);
1204 1.1 christos else
1205 1.1 christos {
1206 1.1 christos /* Cache the section contents for elf_link_input_bfd. */
1207 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1208 1.1 christos }
1209 1.1 christos }
1210 1.9 christos
1211 1.1 christos if (elf_section_data (sec)->relocs != internal_relocs)
1212 1.1 christos free (internal_relocs);
1213 1.1 christos
1214 1.1 christos return TRUE;
1215 1.1 christos
1216 1.9 christos error_return:
1217 1.1 christos if (symtab_hdr->contents != (unsigned char *) isymbuf)
1218 1.9 christos free (isymbuf);
1219 1.1 christos if (elf_section_data (sec)->this_hdr.contents != contents)
1220 1.9 christos free (contents);
1221 1.1 christos if (elf_section_data (sec)->relocs != internal_relocs)
1222 1.1 christos free (internal_relocs);
1223 1.1 christos
1224 1.1 christos return FALSE;
1225 1.1 christos }
1226 1.1 christos
1227 1.1 christos /* Return TRUE if a symbol exists at the given address, else return
1228 1.1 christos FALSE. */
1229 1.1 christos static bfd_boolean
1230 1.1 christos mn10200_elf_symbol_address_p (bfd *abfd,
1231 1.1 christos asection *sec,
1232 1.1 christos Elf_Internal_Sym *isym,
1233 1.1 christos bfd_vma addr)
1234 1.1 christos {
1235 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1236 1.1 christos unsigned int sec_shndx;
1237 1.1 christos Elf_Internal_Sym *isymend;
1238 1.1 christos struct elf_link_hash_entry **sym_hashes;
1239 1.1 christos struct elf_link_hash_entry **end_hashes;
1240 1.1 christos unsigned int symcount;
1241 1.1 christos
1242 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1243 1.1 christos
1244 1.1 christos /* Examine all the local symbols. */
1245 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1246 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1247 1.1 christos {
1248 1.1 christos if (isym->st_shndx == sec_shndx
1249 1.1 christos && isym->st_value == addr)
1250 1.1 christos return TRUE;
1251 1.1 christos }
1252 1.1 christos
1253 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1254 1.1 christos - symtab_hdr->sh_info);
1255 1.1 christos sym_hashes = elf_sym_hashes (abfd);
1256 1.1 christos end_hashes = sym_hashes + symcount;
1257 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++)
1258 1.1 christos {
1259 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
1260 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined
1261 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak)
1262 1.1 christos && sym_hash->root.u.def.section == sec
1263 1.1 christos && sym_hash->root.u.def.value == addr)
1264 1.1 christos return TRUE;
1265 1.1 christos }
1266 1.1 christos
1267 1.1 christos return FALSE;
1268 1.1 christos }
1269 1.1 christos
1270 1.1 christos /* This is a version of bfd_generic_get_relocated_section_contents
1271 1.1 christos which uses mn10200_elf_relocate_section. */
1272 1.1 christos
1273 1.1 christos static bfd_byte *
1274 1.1 christos mn10200_elf_get_relocated_section_contents (bfd *output_bfd,
1275 1.1 christos struct bfd_link_info *link_info,
1276 1.1 christos struct bfd_link_order *link_order,
1277 1.1 christos bfd_byte *data,
1278 1.1 christos bfd_boolean relocatable,
1279 1.1 christos asymbol **symbols)
1280 1.1 christos {
1281 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1282 1.1 christos asection *input_section = link_order->u.indirect.section;
1283 1.1 christos bfd *input_bfd = input_section->owner;
1284 1.1 christos asection **sections = NULL;
1285 1.1 christos Elf_Internal_Rela *internal_relocs = NULL;
1286 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
1287 1.1 christos
1288 1.1 christos /* We only need to handle the case of relaxing, or of having a
1289 1.1 christos particular set of section contents, specially. */
1290 1.1 christos if (relocatable
1291 1.1 christos || elf_section_data (input_section)->this_hdr.contents == NULL)
1292 1.1 christos return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1293 1.1 christos link_order, data,
1294 1.1 christos relocatable,
1295 1.1 christos symbols);
1296 1.1 christos
1297 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1298 1.1 christos
1299 1.1 christos memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1300 1.1 christos (size_t) input_section->size);
1301 1.1 christos
1302 1.1 christos if ((input_section->flags & SEC_RELOC) != 0
1303 1.1 christos && input_section->reloc_count > 0)
1304 1.1 christos {
1305 1.1 christos Elf_Internal_Sym *isym;
1306 1.1 christos Elf_Internal_Sym *isymend;
1307 1.1 christos asection **secpp;
1308 1.1 christos bfd_size_type amt;
1309 1.1 christos
1310 1.1 christos internal_relocs = (_bfd_elf_link_read_relocs
1311 1.1 christos (input_bfd, input_section, NULL,
1312 1.1 christos (Elf_Internal_Rela *) NULL, FALSE));
1313 1.1 christos if (internal_relocs == NULL)
1314 1.1 christos goto error_return;
1315 1.1 christos
1316 1.1 christos if (symtab_hdr->sh_info != 0)
1317 1.1 christos {
1318 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1319 1.1 christos if (isymbuf == NULL)
1320 1.1 christos isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1321 1.1 christos symtab_hdr->sh_info, 0,
1322 1.1 christos NULL, NULL, NULL);
1323 1.1 christos if (isymbuf == NULL)
1324 1.1 christos goto error_return;
1325 1.1 christos }
1326 1.1 christos
1327 1.1 christos amt = symtab_hdr->sh_info;
1328 1.1 christos amt *= sizeof (asection *);
1329 1.1 christos sections = (asection **) bfd_malloc (amt);
1330 1.1 christos if (sections == NULL && amt != 0)
1331 1.1 christos goto error_return;
1332 1.1 christos
1333 1.1 christos isymend = isymbuf + symtab_hdr->sh_info;
1334 1.1 christos for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1335 1.1 christos {
1336 1.1 christos asection *isec;
1337 1.1 christos
1338 1.1 christos if (isym->st_shndx == SHN_UNDEF)
1339 1.1 christos isec = bfd_und_section_ptr;
1340 1.1 christos else if (isym->st_shndx == SHN_ABS)
1341 1.1 christos isec = bfd_abs_section_ptr;
1342 1.1 christos else if (isym->st_shndx == SHN_COMMON)
1343 1.1 christos isec = bfd_com_section_ptr;
1344 1.1 christos else
1345 1.1 christos isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1346 1.1 christos
1347 1.1 christos *secpp = isec;
1348 1.1 christos }
1349 1.1 christos
1350 1.1 christos if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
1351 1.1 christos input_section, data, internal_relocs,
1352 1.1 christos isymbuf, sections))
1353 1.1 christos goto error_return;
1354 1.9 christos
1355 1.9 christos free (sections);
1356 1.1 christos if (symtab_hdr->contents != (unsigned char *) isymbuf)
1357 1.1 christos free (isymbuf);
1358 1.1 christos if (elf_section_data (input_section)->relocs != internal_relocs)
1359 1.1 christos free (internal_relocs);
1360 1.1 christos }
1361 1.1 christos
1362 1.1 christos return data;
1363 1.1 christos
1364 1.9 christos error_return:
1365 1.9 christos free (sections);
1366 1.1 christos if (symtab_hdr->contents != (unsigned char *) isymbuf)
1367 1.9 christos free (isymbuf);
1368 1.1 christos if (elf_section_data (input_section)->relocs != internal_relocs)
1369 1.1 christos free (internal_relocs);
1370 1.1 christos return NULL;
1371 1.1 christos }
1372 1.3 christos
1373 1.1 christos #define TARGET_LITTLE_SYM mn10200_elf32_vec
1374 1.1 christos #define TARGET_LITTLE_NAME "elf32-mn10200"
1375 1.1 christos #define ELF_ARCH bfd_arch_mn10200
1376 1.1 christos #define ELF_MACHINE_CODE EM_MN10200
1377 1.1 christos #define ELF_MACHINE_ALT1 EM_CYGNUS_MN10200
1378 1.1 christos #define ELF_MAXPAGESIZE 0x1000
1379 1.1 christos
1380 1.1 christos #define elf_backend_rela_normal 1
1381 1.8 christos #define elf_info_to_howto mn10200_info_to_howto
1382 1.1 christos #define elf_info_to_howto_rel NULL
1383 1.1 christos #define elf_backend_relocate_section mn10200_elf_relocate_section
1384 1.1 christos #define bfd_elf32_bfd_relax_section mn10200_elf_relax_section
1385 1.1 christos #define bfd_elf32_bfd_get_relocated_section_contents \
1386 1.1 christos mn10200_elf_get_relocated_section_contents
1387 1.1 christos
1388 1.1 christos #define elf_symbol_leading_char '_'
1389 1.1 christos
1390 #include "elf32-target.h"
1391