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