elf-m10200.c revision 1.5 1 1.1 christos /* Matsushita 10200 specific support for 32-bit ELF
2 1.3 christos Copyright (C) 1996-2015 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.1 christos
387 1.1 christos if (info->relocatable)
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.1 christos case bfd_reloc_overflow:
414 1.1 christos if (! ((*info->callbacks->reloc_overflow)
415 1.1 christos (info, (h ? &h->root : NULL), name, howto->name,
416 1.1 christos (bfd_vma) 0, input_bfd, input_section,
417 1.1 christos rel->r_offset)))
418 1.1 christos return FALSE;
419 1.1 christos break;
420 1.1 christos
421 1.1 christos case bfd_reloc_undefined:
422 1.1 christos if (! ((*info->callbacks->undefined_symbol)
423 1.1 christos (info, name, input_bfd, input_section,
424 1.1 christos rel->r_offset, TRUE)))
425 1.1 christos return FALSE;
426 1.1 christos break;
427 1.1 christos
428 1.1 christos case bfd_reloc_outofrange:
429 1.1 christos msg = _("internal error: out of range error");
430 1.1 christos goto common_error;
431 1.1 christos
432 1.1 christos case bfd_reloc_notsupported:
433 1.1 christos msg = _("internal error: unsupported relocation error");
434 1.1 christos goto common_error;
435 1.1 christos
436 1.1 christos case bfd_reloc_dangerous:
437 1.1 christos msg = _("internal error: dangerous error");
438 1.1 christos goto common_error;
439 1.1 christos
440 1.1 christos default:
441 1.1 christos msg = _("internal error: unknown error");
442 1.1 christos /* fall through */
443 1.1 christos
444 1.1 christos common_error:
445 1.1 christos if (!((*info->callbacks->warning)
446 1.1 christos (info, msg, name, input_bfd, input_section,
447 1.1 christos rel->r_offset)))
448 1.1 christos return FALSE;
449 1.1 christos break;
450 1.1 christos }
451 1.1 christos }
452 1.1 christos }
453 1.1 christos
454 1.1 christos return TRUE;
455 1.1 christos }
456 1.1 christos
457 1.1 christos /* Delete some bytes from a section while relaxing. */
458 1.1 christos
459 1.1 christos static bfd_boolean
460 1.1 christos mn10200_elf_relax_delete_bytes (bfd *abfd, asection *sec,
461 1.1 christos bfd_vma addr, int count)
462 1.1 christos {
463 1.1 christos Elf_Internal_Shdr *symtab_hdr;
464 1.1 christos unsigned int sec_shndx;
465 1.1 christos bfd_byte *contents;
466 1.1 christos Elf_Internal_Rela *irel, *irelend;
467 1.1 christos bfd_vma toaddr;
468 1.1 christos Elf_Internal_Sym *isym;
469 1.1 christos Elf_Internal_Sym *isymend;
470 1.1 christos struct elf_link_hash_entry **sym_hashes;
471 1.1 christos struct elf_link_hash_entry **end_hashes;
472 1.1 christos unsigned int symcount;
473 1.1 christos
474 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
475 1.1 christos
476 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
477 1.1 christos
478 1.1 christos toaddr = sec->size;
479 1.1 christos
480 1.1 christos irel = elf_section_data (sec)->relocs;
481 1.1 christos irelend = irel + sec->reloc_count;
482 1.1 christos
483 1.1 christos /* Actually delete the bytes. */
484 1.1 christos memmove (contents + addr, contents + addr + count,
485 1.1 christos (size_t) (toaddr - addr - count));
486 1.1 christos sec->size -= count;
487 1.1 christos
488 1.1 christos /* Adjust all the relocs. */
489 1.1 christos for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
490 1.1 christos {
491 1.1 christos /* Get the new reloc address. */
492 1.1 christos if ((irel->r_offset > addr
493 1.1 christos && irel->r_offset < toaddr))
494 1.1 christos irel->r_offset -= count;
495 1.1 christos }
496 1.1 christos
497 1.1 christos /* Adjust the local symbols defined in this section. */
498 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
499 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents;
500 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
501 1.1 christos {
502 1.1 christos if (isym->st_shndx == sec_shndx
503 1.1 christos && isym->st_value > addr
504 1.1 christos && isym->st_value < toaddr)
505 1.1 christos isym->st_value -= count;
506 1.1 christos }
507 1.1 christos
508 1.1 christos /* Now adjust the global symbols defined in this section. */
509 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
510 1.1 christos - symtab_hdr->sh_info);
511 1.1 christos sym_hashes = elf_sym_hashes (abfd);
512 1.1 christos end_hashes = sym_hashes + symcount;
513 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++)
514 1.1 christos {
515 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
516 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined
517 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak)
518 1.1 christos && sym_hash->root.u.def.section == sec
519 1.1 christos && sym_hash->root.u.def.value > addr
520 1.1 christos && sym_hash->root.u.def.value < toaddr)
521 1.1 christos {
522 1.1 christos sym_hash->root.u.def.value -= count;
523 1.1 christos }
524 1.1 christos }
525 1.1 christos
526 1.1 christos return TRUE;
527 1.1 christos }
528 1.1 christos
529 1.1 christos /* This function handles relaxing for the mn10200.
530 1.1 christos
531 1.1 christos There are quite a few relaxing opportunities available on the mn10200:
532 1.1 christos
533 1.1 christos * jsr:24 -> jsr:16 2 bytes
534 1.1 christos
535 1.1 christos * jmp:24 -> jmp:16 2 bytes
536 1.1 christos * jmp:16 -> bra:8 1 byte
537 1.1 christos
538 1.1 christos * If the previous instruction is a conditional branch
539 1.1 christos around the jump/bra, we may be able to reverse its condition
540 1.1 christos and change its target to the jump's target. The jump/bra
541 1.1 christos can then be deleted. 2 bytes
542 1.1 christos
543 1.1 christos * mov abs24 -> mov abs16 2 byte savings
544 1.1 christos
545 1.1 christos * Most instructions which accept imm24 can relax to imm16 2 bytes
546 1.1 christos - Most instructions which accept imm16 can relax to imm8 1 byte
547 1.1 christos
548 1.1 christos * Most instructions which accept d24 can relax to d16 2 bytes
549 1.1 christos - Most instructions which accept d16 can relax to d8 1 byte
550 1.1 christos
551 1.1 christos abs24, imm24, d24 all look the same at the reloc level. It
552 1.1 christos might make the code simpler if we had different relocs for
553 1.1 christos the various relaxable operand types.
554 1.1 christos
555 1.1 christos We don't handle imm16->imm8 or d16->d8 as they're very rare
556 1.1 christos and somewhat more difficult to support. */
557 1.1 christos
558 1.1 christos static bfd_boolean
559 1.1 christos mn10200_elf_relax_section (bfd *abfd,
560 1.1 christos asection *sec,
561 1.1 christos struct bfd_link_info *link_info,
562 1.1 christos bfd_boolean *again)
563 1.1 christos {
564 1.1 christos Elf_Internal_Shdr *symtab_hdr;
565 1.1 christos Elf_Internal_Rela *internal_relocs;
566 1.1 christos Elf_Internal_Rela *irel, *irelend;
567 1.1 christos bfd_byte *contents = NULL;
568 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
569 1.1 christos
570 1.1 christos /* Assume nothing changes. */
571 1.1 christos *again = FALSE;
572 1.1 christos
573 1.1 christos /* We don't have to do anything for a relocatable link, if
574 1.1 christos this section does not have relocs, or if this is not a
575 1.1 christos code section. */
576 1.1 christos if (link_info->relocatable
577 1.1 christos || (sec->flags & SEC_RELOC) == 0
578 1.1 christos || sec->reloc_count == 0
579 1.1 christos || (sec->flags & SEC_CODE) == 0)
580 1.1 christos return TRUE;
581 1.1 christos
582 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
583 1.1 christos
584 1.1 christos /* Get a copy of the native relocations. */
585 1.1 christos internal_relocs = (_bfd_elf_link_read_relocs
586 1.1 christos (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
587 1.1 christos link_info->keep_memory));
588 1.1 christos if (internal_relocs == NULL)
589 1.1 christos goto error_return;
590 1.1 christos
591 1.1 christos /* Walk through them looking for relaxing opportunities. */
592 1.1 christos irelend = internal_relocs + sec->reloc_count;
593 1.1 christos for (irel = internal_relocs; irel < irelend; irel++)
594 1.1 christos {
595 1.1 christos bfd_vma symval;
596 1.1 christos
597 1.1 christos /* If this isn't something that can be relaxed, then ignore
598 1.1 christos this reloc. */
599 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
600 1.1 christos || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
601 1.1 christos || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
602 1.1 christos continue;
603 1.1 christos
604 1.1 christos /* Get the section contents if we haven't done so already. */
605 1.1 christos if (contents == NULL)
606 1.1 christos {
607 1.1 christos /* Get cached copy if it exists. */
608 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL)
609 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
610 1.1 christos else
611 1.1 christos {
612 1.1 christos /* Go get them off disk. */
613 1.1 christos if (!bfd_malloc_and_get_section (abfd, sec, &contents))
614 1.1 christos goto error_return;
615 1.1 christos }
616 1.1 christos }
617 1.1 christos
618 1.1 christos /* Read this BFD's local symbols if we haven't done so already. */
619 1.1 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0)
620 1.1 christos {
621 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
622 1.1 christos if (isymbuf == NULL)
623 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
624 1.1 christos symtab_hdr->sh_info, 0,
625 1.1 christos NULL, NULL, NULL);
626 1.1 christos if (isymbuf == NULL)
627 1.1 christos goto error_return;
628 1.1 christos }
629 1.1 christos
630 1.1 christos /* Get the value of the symbol referred to by the reloc. */
631 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
632 1.1 christos {
633 1.1 christos /* A local symbol. */
634 1.1 christos Elf_Internal_Sym *isym;
635 1.1 christos asection *sym_sec;
636 1.1 christos
637 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
638 1.1 christos if (isym->st_shndx == SHN_UNDEF)
639 1.1 christos sym_sec = bfd_und_section_ptr;
640 1.1 christos else if (isym->st_shndx == SHN_ABS)
641 1.1 christos sym_sec = bfd_abs_section_ptr;
642 1.1 christos else if (isym->st_shndx == SHN_COMMON)
643 1.1 christos sym_sec = bfd_com_section_ptr;
644 1.1 christos else
645 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
646 1.1 christos symval = (isym->st_value
647 1.1 christos + sym_sec->output_section->vma
648 1.1 christos + sym_sec->output_offset);
649 1.1 christos }
650 1.1 christos else
651 1.1 christos {
652 1.1 christos unsigned long indx;
653 1.1 christos struct elf_link_hash_entry *h;
654 1.1 christos
655 1.1 christos /* An external symbol. */
656 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
657 1.1 christos h = elf_sym_hashes (abfd)[indx];
658 1.1 christos BFD_ASSERT (h != NULL);
659 1.1 christos if (h->root.type != bfd_link_hash_defined
660 1.1 christos && h->root.type != bfd_link_hash_defweak)
661 1.1 christos {
662 1.1 christos /* This appears to be a reference to an undefined
663 1.1 christos symbol. Just ignore it--it will be caught by the
664 1.1 christos regular reloc processing. */
665 1.1 christos continue;
666 1.1 christos }
667 1.1 christos
668 1.1 christos symval = (h->root.u.def.value
669 1.1 christos + h->root.u.def.section->output_section->vma
670 1.1 christos + h->root.u.def.section->output_offset);
671 1.1 christos }
672 1.1 christos
673 1.1 christos /* For simplicity of coding, we are going to modify the section
674 1.1 christos contents, the section relocs, and the BFD symbol table. We
675 1.1 christos must tell the rest of the code not to free up this
676 1.1 christos information. It would be possible to instead create a table
677 1.1 christos of changes which have to be made, as is done in coff-mips.c;
678 1.1 christos that would be more work, but would require less memory when
679 1.1 christos the linker is run. */
680 1.1 christos
681 1.1 christos /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
682 1.1 christos branch/call. */
683 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
684 1.1 christos {
685 1.1 christos bfd_vma value = symval;
686 1.1 christos
687 1.1 christos /* Deal with pc-relative gunk. */
688 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
689 1.1 christos value -= (irel->r_offset + 3);
690 1.1 christos value += irel->r_addend;
691 1.1 christos
692 1.1 christos /* See if the value will fit in 16 bits, note the high value is
693 1.1 christos 0x7fff + 2 as the target will be two bytes closer if we are
694 1.1 christos able to relax. */
695 1.1 christos if ((long) value < 0x8001 && (long) value > -0x8000)
696 1.1 christos {
697 1.1 christos unsigned char code;
698 1.1 christos
699 1.1 christos /* Get the opcode. */
700 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
701 1.1 christos
702 1.1 christos if (code != 0xe0 && code != 0xe1)
703 1.1 christos continue;
704 1.1 christos
705 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
706 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
707 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
708 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
709 1.1 christos
710 1.1 christos /* Fix the opcode. */
711 1.1 christos if (code == 0xe0)
712 1.1 christos bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
713 1.1 christos else if (code == 0xe1)
714 1.1 christos bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
715 1.1 christos
716 1.1 christos /* Fix the relocation's type. */
717 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
718 1.1 christos R_MN10200_PCREL16);
719 1.1 christos
720 1.1 christos /* The opcode got shorter too, so we have to fix the offset. */
721 1.1 christos irel->r_offset -= 1;
722 1.1 christos
723 1.1 christos /* Delete two bytes of data. */
724 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
725 1.1 christos irel->r_offset + 1, 2))
726 1.1 christos goto error_return;
727 1.1 christos
728 1.1 christos /* That will change things, so, we should relax again.
729 1.1 christos Note that this is not required, and it may be slow. */
730 1.1 christos *again = TRUE;
731 1.1 christos }
732 1.1 christos }
733 1.1 christos
734 1.1 christos /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
735 1.1 christos branch. */
736 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
737 1.1 christos {
738 1.1 christos bfd_vma value = symval;
739 1.1 christos
740 1.1 christos /* Deal with pc-relative gunk. */
741 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
742 1.1 christos value -= (irel->r_offset + 2);
743 1.1 christos value += irel->r_addend;
744 1.1 christos
745 1.1 christos /* See if the value will fit in 8 bits, note the high value is
746 1.1 christos 0x7f + 1 as the target will be one bytes closer if we are
747 1.1 christos able to relax. */
748 1.1 christos if ((long) value < 0x80 && (long) value > -0x80)
749 1.1 christos {
750 1.1 christos unsigned char code;
751 1.1 christos
752 1.1 christos /* Get the opcode. */
753 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
754 1.1 christos
755 1.1 christos if (code != 0xfc)
756 1.1 christos continue;
757 1.1 christos
758 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
759 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
760 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
761 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
762 1.1 christos
763 1.1 christos /* Fix the opcode. */
764 1.1 christos bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
765 1.1 christos
766 1.1 christos /* Fix the relocation's type. */
767 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
768 1.1 christos R_MN10200_PCREL8);
769 1.1 christos
770 1.1 christos /* Delete one byte of data. */
771 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
772 1.1 christos irel->r_offset + 1, 1))
773 1.1 christos goto error_return;
774 1.1 christos
775 1.1 christos /* That will change things, so, we should relax again.
776 1.1 christos Note that this is not required, and it may be slow. */
777 1.1 christos *again = TRUE;
778 1.1 christos }
779 1.1 christos }
780 1.1 christos
781 1.1 christos /* Try to eliminate an unconditional 8 bit pc-relative branch
782 1.1 christos which immediately follows a conditional 8 bit pc-relative
783 1.1 christos branch around the unconditional branch.
784 1.1 christos
785 1.1 christos original: new:
786 1.1 christos bCC lab1 bCC' lab2
787 1.1 christos bra lab2
788 1.1 christos lab1: lab1:
789 1.1 christos
790 1.1 christos This happens when the bCC can't reach lab2 at assembly time,
791 1.1 christos but due to other relaxations it can reach at link time. */
792 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
793 1.1 christos {
794 1.1 christos Elf_Internal_Rela *nrel;
795 1.1 christos bfd_vma value = symval;
796 1.1 christos unsigned char code;
797 1.1 christos
798 1.1 christos /* Deal with pc-relative gunk. */
799 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
800 1.1 christos value -= (irel->r_offset + 1);
801 1.1 christos value += irel->r_addend;
802 1.1 christos
803 1.1 christos /* Do nothing if this reloc is the last byte in the section. */
804 1.1 christos if (irel->r_offset == sec->size)
805 1.1 christos continue;
806 1.1 christos
807 1.1 christos /* See if the next instruction is an unconditional pc-relative
808 1.1 christos branch, more often than not this test will fail, so we
809 1.1 christos test it first to speed things up. */
810 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
811 1.1 christos if (code != 0xea)
812 1.1 christos continue;
813 1.1 christos
814 1.1 christos /* Also make sure the next relocation applies to the next
815 1.1 christos instruction and that it's a pc-relative 8 bit branch. */
816 1.1 christos nrel = irel + 1;
817 1.1 christos if (nrel == irelend
818 1.1 christos || irel->r_offset + 2 != nrel->r_offset
819 1.1 christos || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
820 1.1 christos continue;
821 1.1 christos
822 1.1 christos /* Make sure our destination immediately follows the
823 1.1 christos unconditional branch. */
824 1.1 christos if (symval != (sec->output_section->vma + sec->output_offset
825 1.1 christos + irel->r_offset + 3))
826 1.1 christos continue;
827 1.1 christos
828 1.1 christos /* Now make sure we are a conditional branch. This may not
829 1.1 christos be necessary, but why take the chance.
830 1.1 christos
831 1.1 christos Note these checks assume that R_MN10200_PCREL8 relocs
832 1.1 christos only occur on bCC and bCCx insns. If they occured
833 1.1 christos elsewhere, we'd need to know the start of this insn
834 1.1 christos for this check to be accurate. */
835 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
836 1.1 christos if (code != 0xe0 && code != 0xe1 && code != 0xe2
837 1.1 christos && code != 0xe3 && code != 0xe4 && code != 0xe5
838 1.1 christos && code != 0xe6 && code != 0xe7 && code != 0xe8
839 1.1 christos && code != 0xe9 && code != 0xec && code != 0xed
840 1.1 christos && code != 0xee && code != 0xef && code != 0xfc
841 1.1 christos && code != 0xfd && code != 0xfe && code != 0xff)
842 1.1 christos continue;
843 1.1 christos
844 1.1 christos /* We also have to be sure there is no symbol/label
845 1.1 christos at the unconditional branch. */
846 1.1 christos if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
847 1.1 christos irel->r_offset + 1))
848 1.1 christos continue;
849 1.1 christos
850 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
851 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
852 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
853 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
854 1.1 christos
855 1.1 christos /* Reverse the condition of the first branch. */
856 1.1 christos switch (code)
857 1.1 christos {
858 1.1 christos case 0xfc:
859 1.1 christos code = 0xfd;
860 1.1 christos break;
861 1.1 christos case 0xfd:
862 1.1 christos code = 0xfc;
863 1.1 christos break;
864 1.1 christos case 0xfe:
865 1.1 christos code = 0xff;
866 1.1 christos break;
867 1.1 christos case 0xff:
868 1.1 christos code = 0xfe;
869 1.1 christos break;
870 1.1 christos case 0xe8:
871 1.1 christos code = 0xe9;
872 1.1 christos break;
873 1.1 christos case 0xe9:
874 1.1 christos code = 0xe8;
875 1.1 christos break;
876 1.1 christos case 0xe0:
877 1.1 christos code = 0xe2;
878 1.1 christos break;
879 1.1 christos case 0xe2:
880 1.1 christos code = 0xe0;
881 1.1 christos break;
882 1.1 christos case 0xe3:
883 1.1 christos code = 0xe1;
884 1.1 christos break;
885 1.1 christos case 0xe1:
886 1.1 christos code = 0xe3;
887 1.1 christos break;
888 1.1 christos case 0xe4:
889 1.1 christos code = 0xe6;
890 1.1 christos break;
891 1.1 christos case 0xe6:
892 1.1 christos code = 0xe4;
893 1.1 christos break;
894 1.1 christos case 0xe7:
895 1.1 christos code = 0xe5;
896 1.1 christos break;
897 1.1 christos case 0xe5:
898 1.1 christos code = 0xe7;
899 1.1 christos break;
900 1.1 christos case 0xec:
901 1.1 christos code = 0xed;
902 1.1 christos break;
903 1.1 christos case 0xed:
904 1.1 christos code = 0xec;
905 1.1 christos break;
906 1.1 christos case 0xee:
907 1.1 christos code = 0xef;
908 1.1 christos break;
909 1.1 christos case 0xef:
910 1.1 christos code = 0xee;
911 1.1 christos break;
912 1.1 christos }
913 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
914 1.1 christos
915 1.1 christos /* Set the reloc type and symbol for the first branch
916 1.1 christos from the second branch. */
917 1.1 christos irel->r_info = nrel->r_info;
918 1.1 christos
919 1.1 christos /* Make the reloc for the second branch a null reloc. */
920 1.1 christos nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
921 1.1 christos R_MN10200_NONE);
922 1.1 christos
923 1.1 christos /* Delete two bytes of data. */
924 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
925 1.1 christos irel->r_offset + 1, 2))
926 1.1 christos goto error_return;
927 1.1 christos
928 1.1 christos /* That will change things, so, we should relax again.
929 1.1 christos Note that this is not required, and it may be slow. */
930 1.1 christos *again = TRUE;
931 1.1 christos }
932 1.1 christos
933 1.1 christos /* Try to turn a 24bit immediate, displacement or absolute address
934 1.1 christos into a 16bit immediate, displacement or absolute address. */
935 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
936 1.1 christos {
937 1.1 christos bfd_vma value = symval;
938 1.1 christos
939 1.1 christos /* See if the value will fit in 16 bits.
940 1.1 christos We allow any 16bit match here. We prune those we can't
941 1.1 christos handle below. */
942 1.1 christos if ((long) value < 0x7fff && (long) value > -0x8000)
943 1.1 christos {
944 1.1 christos unsigned char code;
945 1.1 christos
946 1.1 christos /* All insns which have 24bit operands are 5 bytes long,
947 1.1 christos the first byte will always be 0xf4, but we double check
948 1.1 christos it just in case. */
949 1.1 christos
950 1.1 christos /* Get the first opcode. */
951 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
952 1.1 christos
953 1.1 christos if (code != 0xf4)
954 1.1 christos continue;
955 1.1 christos
956 1.1 christos /* Get the second opcode. */
957 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
958 1.1 christos
959 1.1 christos switch (code & 0xfc)
960 1.1 christos {
961 1.1 christos /* mov imm24,dn -> mov imm16,dn */
962 1.1 christos case 0x70:
963 1.1 christos /* Not safe if the high bit is on as relaxing may
964 1.1 christos move the value out of high mem and thus not fit
965 1.1 christos in a signed 16bit value. */
966 1.1 christos if (value & 0x8000)
967 1.1 christos continue;
968 1.1 christos
969 1.1 christos /* Note that we've changed the relocation contents, etc. */
970 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
971 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
972 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
973 1.1 christos
974 1.1 christos /* Fix the opcode. */
975 1.1 christos bfd_put_8 (abfd, 0xf8 + (code & 0x03),
976 1.1 christos contents + irel->r_offset - 2);
977 1.1 christos
978 1.1 christos /* Fix the relocation's type. */
979 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
980 1.1 christos R_MN10200_16);
981 1.1 christos
982 1.1 christos /* The opcode got shorter too, so we have to fix the
983 1.1 christos offset. */
984 1.1 christos irel->r_offset -= 1;
985 1.1 christos
986 1.1 christos /* Delete two bytes of data. */
987 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
988 1.1 christos irel->r_offset + 1, 2))
989 1.1 christos goto error_return;
990 1.1 christos
991 1.1 christos /* That will change things, so, we should relax again.
992 1.1 christos Note that this is not required, and it may be slow. */
993 1.1 christos *again = TRUE;
994 1.1 christos break;
995 1.1 christos
996 1.1 christos /* mov imm24,an -> mov imm16,an
997 1.1 christos cmp imm24,an -> cmp imm16,an
998 1.1 christos mov (abs24),dn -> mov (abs16),dn
999 1.1 christos mov dn,(abs24) -> mov dn,(abs16)
1000 1.1 christos movb dn,(abs24) -> movb dn,(abs16)
1001 1.1 christos movbu (abs24),dn -> movbu (abs16),dn */
1002 1.1 christos case 0x74:
1003 1.1 christos case 0x7c:
1004 1.1 christos case 0xc0:
1005 1.1 christos case 0x40:
1006 1.1 christos case 0x44:
1007 1.1 christos case 0xc8:
1008 1.1 christos /* Note that we've changed the relocation contents, etc. */
1009 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1010 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1011 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1012 1.1 christos
1013 1.1 christos if ((code & 0xfc) == 0x74)
1014 1.1 christos code = 0xdc + (code & 0x03);
1015 1.1 christos else if ((code & 0xfc) == 0x7c)
1016 1.1 christos code = 0xec + (code & 0x03);
1017 1.1 christos else if ((code & 0xfc) == 0xc0)
1018 1.1 christos code = 0xc8 + (code & 0x03);
1019 1.1 christos else if ((code & 0xfc) == 0x40)
1020 1.1 christos code = 0xc0 + (code & 0x03);
1021 1.1 christos else if ((code & 0xfc) == 0x44)
1022 1.1 christos code = 0xc4 + (code & 0x03);
1023 1.1 christos else if ((code & 0xfc) == 0xc8)
1024 1.1 christos code = 0xcc + (code & 0x03);
1025 1.1 christos
1026 1.1 christos /* Fix the opcode. */
1027 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
1028 1.1 christos
1029 1.1 christos /* Fix the relocation's type. */
1030 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1031 1.1 christos R_MN10200_16);
1032 1.1 christos
1033 1.1 christos /* The opcode got shorter too, so we have to fix the
1034 1.1 christos offset. */
1035 1.1 christos irel->r_offset -= 1;
1036 1.1 christos
1037 1.1 christos /* Delete two bytes of data. */
1038 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1039 1.1 christos irel->r_offset + 1, 2))
1040 1.1 christos goto error_return;
1041 1.1 christos
1042 1.1 christos /* That will change things, so, we should relax again.
1043 1.1 christos Note that this is not required, and it may be slow. */
1044 1.1 christos *again = TRUE;
1045 1.1 christos break;
1046 1.1 christos
1047 1.1 christos /* cmp imm24,dn -> cmp imm16,dn
1048 1.1 christos mov (abs24),an -> mov (abs16),an
1049 1.1 christos mov an,(abs24) -> mov an,(abs16)
1050 1.1 christos add imm24,dn -> add imm16,dn
1051 1.1 christos add imm24,an -> add imm16,an
1052 1.1 christos sub imm24,dn -> sub imm16,dn
1053 1.1 christos sub imm24,an -> sub imm16,an
1054 1.1 christos And all d24->d16 in memory ops. */
1055 1.1 christos case 0x78:
1056 1.1 christos case 0xd0:
1057 1.1 christos case 0x50:
1058 1.1 christos case 0x60:
1059 1.1 christos case 0x64:
1060 1.1 christos case 0x68:
1061 1.1 christos case 0x6c:
1062 1.1 christos case 0x80:
1063 1.1 christos case 0xf0:
1064 1.1 christos case 0x00:
1065 1.1 christos case 0x10:
1066 1.1 christos case 0xb0:
1067 1.1 christos case 0x30:
1068 1.1 christos case 0xa0:
1069 1.1 christos case 0x20:
1070 1.1 christos case 0x90:
1071 1.1 christos /* Not safe if the high bit is on as relaxing may
1072 1.1 christos move the value out of high mem and thus not fit
1073 1.1 christos in a signed 16bit value. */
1074 1.1 christos if (((code & 0xfc) == 0x78
1075 1.1 christos || (code & 0xfc) == 0x60
1076 1.1 christos || (code & 0xfc) == 0x64
1077 1.1 christos || (code & 0xfc) == 0x68
1078 1.1 christos || (code & 0xfc) == 0x6c
1079 1.1 christos || (code & 0xfc) == 0x80
1080 1.1 christos || (code & 0xfc) == 0xf0
1081 1.1 christos || (code & 0xfc) == 0x00
1082 1.1 christos || (code & 0xfc) == 0x10
1083 1.1 christos || (code & 0xfc) == 0xb0
1084 1.1 christos || (code & 0xfc) == 0x30
1085 1.1 christos || (code & 0xfc) == 0xa0
1086 1.1 christos || (code & 0xfc) == 0x20
1087 1.1 christos || (code & 0xfc) == 0x90)
1088 1.1 christos && (value & 0x8000) != 0)
1089 1.1 christos continue;
1090 1.1 christos
1091 1.1 christos /* Note that we've changed the relocation contents, etc. */
1092 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1093 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1094 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1095 1.1 christos
1096 1.1 christos /* Fix the opcode. */
1097 1.1 christos bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
1098 1.1 christos
1099 1.1 christos if ((code & 0xfc) == 0x78)
1100 1.1 christos code = 0x48 + (code & 0x03);
1101 1.1 christos else if ((code & 0xfc) == 0xd0)
1102 1.1 christos code = 0x30 + (code & 0x03);
1103 1.1 christos else if ((code & 0xfc) == 0x50)
1104 1.1 christos code = 0x20 + (code & 0x03);
1105 1.1 christos else if ((code & 0xfc) == 0x60)
1106 1.1 christos code = 0x18 + (code & 0x03);
1107 1.1 christos else if ((code & 0xfc) == 0x64)
1108 1.1 christos code = 0x08 + (code & 0x03);
1109 1.1 christos else if ((code & 0xfc) == 0x68)
1110 1.1 christos code = 0x1c + (code & 0x03);
1111 1.1 christos else if ((code & 0xfc) == 0x6c)
1112 1.1 christos code = 0x0c + (code & 0x03);
1113 1.1 christos else if ((code & 0xfc) == 0x80)
1114 1.1 christos code = 0xc0 + (code & 0x07);
1115 1.1 christos else if ((code & 0xfc) == 0xf0)
1116 1.1 christos code = 0xb0 + (code & 0x07);
1117 1.1 christos else if ((code & 0xfc) == 0x00)
1118 1.1 christos code = 0x80 + (code & 0x07);
1119 1.1 christos else if ((code & 0xfc) == 0x10)
1120 1.1 christos code = 0xa0 + (code & 0x07);
1121 1.1 christos else if ((code & 0xfc) == 0xb0)
1122 1.1 christos code = 0x70 + (code & 0x07);
1123 1.1 christos else if ((code & 0xfc) == 0x30)
1124 1.1 christos code = 0x60 + (code & 0x07);
1125 1.1 christos else if ((code & 0xfc) == 0xa0)
1126 1.1 christos code = 0xd0 + (code & 0x07);
1127 1.1 christos else if ((code & 0xfc) == 0x20)
1128 1.1 christos code = 0x90 + (code & 0x07);
1129 1.1 christos else if ((code & 0xfc) == 0x90)
1130 1.1 christos code = 0x50 + (code & 0x07);
1131 1.1 christos
1132 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1133 1.1 christos
1134 1.1 christos /* Fix the relocation's type. */
1135 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1136 1.1 christos R_MN10200_16);
1137 1.1 christos
1138 1.1 christos /* Delete one bytes of data. */
1139 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1140 1.1 christos irel->r_offset + 2, 1))
1141 1.1 christos goto error_return;
1142 1.1 christos
1143 1.1 christos /* That will change things, so, we should relax again.
1144 1.1 christos Note that this is not required, and it may be slow. */
1145 1.1 christos *again = TRUE;
1146 1.1 christos break;
1147 1.1 christos
1148 1.1 christos /* movb (abs24),dn ->movbu (abs16),dn extxb bn */
1149 1.1 christos case 0xc4:
1150 1.1 christos /* Note that we've changed the reldection contents, etc. */
1151 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1152 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1153 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1154 1.1 christos
1155 1.1 christos bfd_put_8 (abfd, 0xcc + (code & 0x03),
1156 1.1 christos contents + irel->r_offset - 2);
1157 1.1 christos
1158 1.1 christos bfd_put_8 (abfd, 0xb8 + (code & 0x03),
1159 1.1 christos contents + irel->r_offset - 1);
1160 1.1 christos
1161 1.1 christos /* Fix the relocation's type. */
1162 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1163 1.1 christos R_MN10200_16);
1164 1.1 christos
1165 1.1 christos /* The reloc will be applied one byte in front of its
1166 1.1 christos current location. */
1167 1.1 christos irel->r_offset -= 1;
1168 1.1 christos
1169 1.1 christos /* Delete one bytes of data. */
1170 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1171 1.1 christos irel->r_offset + 2, 1))
1172 1.1 christos goto error_return;
1173 1.1 christos
1174 1.1 christos /* That will change things, so, we should relax again.
1175 1.1 christos Note that this is not required, and it may be slow. */
1176 1.1 christos *again = TRUE;
1177 1.1 christos break;
1178 1.1 christos }
1179 1.1 christos }
1180 1.1 christos }
1181 1.1 christos }
1182 1.1 christos
1183 1.1 christos if (isymbuf != NULL
1184 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1185 1.1 christos {
1186 1.1 christos if (! link_info->keep_memory)
1187 1.1 christos free (isymbuf);
1188 1.1 christos else
1189 1.1 christos {
1190 1.1 christos /* Cache the symbols for elf_link_input_bfd. */
1191 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1192 1.1 christos }
1193 1.1 christos }
1194 1.1 christos
1195 1.1 christos if (contents != NULL
1196 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents)
1197 1.1 christos {
1198 1.1 christos if (! link_info->keep_memory)
1199 1.1 christos free (contents);
1200 1.1 christos else
1201 1.1 christos {
1202 1.1 christos /* Cache the section contents for elf_link_input_bfd. */
1203 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1204 1.1 christos }
1205 1.1 christos }
1206 1.1 christos
1207 1.1 christos if (internal_relocs != NULL
1208 1.1 christos && elf_section_data (sec)->relocs != internal_relocs)
1209 1.1 christos free (internal_relocs);
1210 1.1 christos
1211 1.1 christos return TRUE;
1212 1.1 christos
1213 1.1 christos error_return:
1214 1.1 christos if (isymbuf != NULL
1215 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1216 1.1 christos free (isymbuf);
1217 1.1 christos if (contents != NULL
1218 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents)
1219 1.1 christos free (contents);
1220 1.1 christos if (internal_relocs != NULL
1221 1.1 christos && 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.1 christos
1355 1.1 christos if (sections != NULL)
1356 1.1 christos free (sections);
1357 1.1 christos if (isymbuf != NULL
1358 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1359 1.1 christos free (isymbuf);
1360 1.1 christos if (elf_section_data (input_section)->relocs != internal_relocs)
1361 1.1 christos free (internal_relocs);
1362 1.1 christos }
1363 1.1 christos
1364 1.1 christos return data;
1365 1.1 christos
1366 1.1 christos error_return:
1367 1.1 christos if (sections != NULL)
1368 1.1 christos free (sections);
1369 1.1 christos if (isymbuf != NULL
1370 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1371 1.1 christos free (isymbuf);
1372 1.1 christos if (internal_relocs != NULL
1373 1.1 christos && elf_section_data (input_section)->relocs != internal_relocs)
1374 1.1 christos free (internal_relocs);
1375 1.1 christos return NULL;
1376 1.1 christos }
1377 1.3 christos
1378 1.1 christos #define TARGET_LITTLE_SYM mn10200_elf32_vec
1379 1.1 christos #define TARGET_LITTLE_NAME "elf32-mn10200"
1380 1.1 christos #define ELF_ARCH bfd_arch_mn10200
1381 1.1 christos #define ELF_MACHINE_CODE EM_MN10200
1382 1.1 christos #define ELF_MACHINE_ALT1 EM_CYGNUS_MN10200
1383 1.1 christos #define ELF_MAXPAGESIZE 0x1000
1384 1.1 christos
1385 1.1 christos #define elf_backend_rela_normal 1
1386 1.1 christos #define elf_info_to_howto mn10200_info_to_howto
1387 1.1 christos #define elf_info_to_howto_rel 0
1388 1.1 christos #define elf_backend_relocate_section mn10200_elf_relocate_section
1389 1.1 christos #define bfd_elf32_bfd_relax_section mn10200_elf_relax_section
1390 1.1 christos #define bfd_elf32_bfd_get_relocated_section_contents \
1391 1.1 christos mn10200_elf_get_relocated_section_contents
1392 1.1 christos
1393 1.1 christos #define elf_symbol_leading_char '_'
1394 1.1 christos
1395 #include "elf32-target.h"
1396