/src/binutils-gdb/bfd/elf32-mt.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Morpho Technologies MT specific support for 32-bit ELF |
2 | | Copyright (C) 2001-2025 Free Software Foundation, Inc. |
3 | | |
4 | | This file is part of BFD, the Binary File Descriptor library. |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3 of the License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with this program; if not, write to the Free Software |
18 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
19 | | MA 02110-1301, USA. */ |
20 | | |
21 | | #include "sysdep.h" |
22 | | #include "bfd.h" |
23 | | #include "libbfd.h" |
24 | | #include "elf-bfd.h" |
25 | | #include "elf/mt.h" |
26 | | |
27 | | /* Prototypes. */ |
28 | | static reloc_howto_type * mt_reloc_type_lookup |
29 | | (bfd *, bfd_reloc_code_real_type); |
30 | | |
31 | | static bool mt_info_to_howto_rela |
32 | | (bfd *, arelent *, Elf_Internal_Rela *); |
33 | | |
34 | | static bfd_reloc_status_type mt_elf_relocate_hi16 |
35 | | (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma); |
36 | | |
37 | | static bfd_reloc_status_type mt_final_link_relocate |
38 | | (reloc_howto_type *, bfd *, asection *, bfd_byte *, |
39 | | Elf_Internal_Rela *, bfd_vma); |
40 | | |
41 | | static int mt_elf_relocate_section |
42 | | (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
43 | | Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); |
44 | | |
45 | | /* Relocation tables. */ |
46 | | static reloc_howto_type mt_elf_howto_table [] = |
47 | | { |
48 | | /* This reloc does nothing. */ |
49 | | HOWTO (R_MT_NONE, /* type */ |
50 | | 0, /* rightshift */ |
51 | | 0, /* size */ |
52 | | 0, /* bitsize */ |
53 | | false, /* pc_relative */ |
54 | | 0, /* bitpos */ |
55 | | complain_overflow_dont, /* complain_on_overflow */ |
56 | | bfd_elf_generic_reloc, /* special_function */ |
57 | | "R_MT_NONE", /* name */ |
58 | | false, /* partial_inplace */ |
59 | | 0 , /* src_mask */ |
60 | | 0, /* dst_mask */ |
61 | | false), /* pcrel_offset */ |
62 | | |
63 | | /* A 16 bit absolute relocation. */ |
64 | | HOWTO (R_MT_16, /* type */ |
65 | | 0, /* rightshift */ |
66 | | 4, /* size */ |
67 | | 16, /* bitsize */ |
68 | | false, /* pc_relative */ |
69 | | 0, /* bitpos */ |
70 | | complain_overflow_dont, /* complain_on_overflow */ |
71 | | bfd_elf_generic_reloc, /* special_function */ |
72 | | "R_MT_16", /* name */ |
73 | | false, /* partial_inplace */ |
74 | | 0 , /* src_mask */ |
75 | | 0xffff, /* dst_mask */ |
76 | | false), /* pcrel_offset */ |
77 | | |
78 | | /* A 32 bit absolute relocation. */ |
79 | | HOWTO (R_MT_32, /* type */ |
80 | | 0, /* rightshift */ |
81 | | 4, /* size */ |
82 | | 32, /* bitsize */ |
83 | | false, /* pc_relative */ |
84 | | 0, /* bitpos */ |
85 | | complain_overflow_dont, /* complain_on_overflow */ |
86 | | bfd_elf_generic_reloc, /* special_function */ |
87 | | "R_MT_32", /* name */ |
88 | | false, /* partial_inplace */ |
89 | | 0 , /* src_mask */ |
90 | | 0xffffffff, /* dst_mask */ |
91 | | false), /* pcrel_offset */ |
92 | | |
93 | | /* A 32 bit pc-relative relocation. */ |
94 | | HOWTO (R_MT_32_PCREL, /* type */ |
95 | | 0, /* rightshift */ |
96 | | 4, /* size */ |
97 | | 32, /* bitsize */ |
98 | | true, /* pc_relative */ |
99 | | 0, /* bitpos */ |
100 | | complain_overflow_dont, /* complain_on_overflow */ |
101 | | bfd_elf_generic_reloc, /* special_function */ |
102 | | "R_MT_32_PCREL", /* name */ |
103 | | false, /* partial_inplace */ |
104 | | 0 , /* src_mask */ |
105 | | 0xffffffff, /* dst_mask */ |
106 | | true), /* pcrel_offset */ |
107 | | |
108 | | /* A 16 bit pc-relative relocation. */ |
109 | | HOWTO (R_MT_PC16, /* type */ |
110 | | 0, /* rightshift */ |
111 | | 4, /* size */ |
112 | | 16, /* bitsize */ |
113 | | true, /* pc_relative */ |
114 | | 0, /* bitpos */ |
115 | | complain_overflow_signed, /* complain_on_overflow */ |
116 | | bfd_elf_generic_reloc, /* special_function */ |
117 | | "R_MT_PC16", /* name */ |
118 | | false, /* partial_inplace */ |
119 | | 0, /* src_mask */ |
120 | | 0xffff, /* dst_mask */ |
121 | | true), /* pcrel_offset */ |
122 | | |
123 | | /* high 16 bits of symbol value. */ |
124 | | HOWTO (R_MT_HI16, /* type */ |
125 | | 0, /* rightshift */ |
126 | | 4, /* size */ |
127 | | 16, /* bitsize */ |
128 | | false, /* pc_relative */ |
129 | | 0, /* bitpos */ |
130 | | complain_overflow_dont, /* complain_on_overflow */ |
131 | | bfd_elf_generic_reloc, /* special_function */ |
132 | | "R_MT_HI16", /* name */ |
133 | | false, /* partial_inplace */ |
134 | | 0xffff0000, /* src_mask */ |
135 | | 0xffff0000, /* dst_mask */ |
136 | | false), /* pcrel_offset */ |
137 | | |
138 | | /* Low 16 bits of symbol value. */ |
139 | | HOWTO (R_MT_LO16, /* type */ |
140 | | 0, /* rightshift */ |
141 | | 4, /* size */ |
142 | | 16, /* bitsize */ |
143 | | false, /* pc_relative */ |
144 | | 0, /* bitpos */ |
145 | | complain_overflow_dont, /* complain_on_overflow */ |
146 | | bfd_elf_generic_reloc, /* special_function */ |
147 | | "R_MT_LO16", /* name */ |
148 | | false, /* partial_inplace */ |
149 | | 0xffff, /* src_mask */ |
150 | | 0xffff, /* dst_mask */ |
151 | | false), /* pcrel_offset */ |
152 | | }; |
153 | | |
154 | | /* Map BFD reloc types to MT ELF reloc types. */ |
155 | | |
156 | | static reloc_howto_type * |
157 | | mt_reloc_type_lookup |
158 | | (bfd * abfd ATTRIBUTE_UNUSED, |
159 | | bfd_reloc_code_real_type code) |
160 | 0 | { |
161 | | /* Note that the mt_elf_howto_table is indxed by the R_ |
162 | | constants. Thus, the order that the howto records appear in the |
163 | | table *must* match the order of the relocation types defined in |
164 | | include/elf/mt.h. */ |
165 | |
|
166 | 0 | switch (code) |
167 | 0 | { |
168 | 0 | case BFD_RELOC_NONE: |
169 | 0 | return &mt_elf_howto_table[ (int) R_MT_NONE]; |
170 | 0 | case BFD_RELOC_16: |
171 | 0 | return &mt_elf_howto_table[ (int) R_MT_16]; |
172 | 0 | case BFD_RELOC_32: |
173 | 0 | return &mt_elf_howto_table[ (int) R_MT_32]; |
174 | 0 | case BFD_RELOC_32_PCREL: |
175 | 0 | return &mt_elf_howto_table[ (int) R_MT_32_PCREL]; |
176 | 0 | case BFD_RELOC_16_PCREL: |
177 | 0 | return &mt_elf_howto_table[ (int) R_MT_PC16]; |
178 | 0 | case BFD_RELOC_HI16: |
179 | 0 | return &mt_elf_howto_table[ (int) R_MT_HI16]; |
180 | 0 | case BFD_RELOC_LO16: |
181 | 0 | return &mt_elf_howto_table[ (int) R_MT_LO16]; |
182 | | |
183 | 0 | default: |
184 | | /* Pacify gcc -Wall. */ |
185 | 0 | return NULL; |
186 | 0 | } |
187 | 0 | return NULL; |
188 | 0 | } |
189 | | |
190 | | static reloc_howto_type * |
191 | | mt_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
192 | | const char *r_name) |
193 | 0 | { |
194 | 0 | unsigned int i; |
195 | |
|
196 | 0 | for (i = 0; |
197 | 0 | i < sizeof (mt_elf_howto_table) / sizeof (mt_elf_howto_table[0]); |
198 | 0 | i++) |
199 | 0 | if (mt_elf_howto_table[i].name != NULL |
200 | 0 | && strcasecmp (mt_elf_howto_table[i].name, r_name) == 0) |
201 | 0 | return &mt_elf_howto_table[i]; |
202 | | |
203 | 0 | return NULL; |
204 | 0 | } |
205 | | |
206 | | bfd_reloc_status_type |
207 | | mt_elf_relocate_hi16 |
208 | | (bfd * input_bfd, |
209 | | Elf_Internal_Rela * relhi, |
210 | | bfd_byte * contents, |
211 | | bfd_vma value) |
212 | 0 | { |
213 | 0 | bfd_vma insn; |
214 | |
|
215 | 0 | insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); |
216 | |
|
217 | 0 | value += relhi->r_addend; |
218 | 0 | value >>= 16; |
219 | 0 | insn = ((insn & ~0xFFFF) | value); |
220 | |
|
221 | 0 | bfd_put_32 (input_bfd, insn, contents + relhi->r_offset); |
222 | 0 | return bfd_reloc_ok; |
223 | 0 | } |
224 | | |
225 | | /* XXX: The following code is the result of a cut&paste. This unfortunate |
226 | | practice is very widespread in the various target back-end files. */ |
227 | | |
228 | | /* Set the howto pointer for a MT ELF reloc. */ |
229 | | |
230 | | static bool |
231 | | mt_info_to_howto_rela (bfd *abfd, |
232 | | arelent *cache_ptr, |
233 | | Elf_Internal_Rela *dst) |
234 | 0 | { |
235 | 0 | unsigned int r_type; |
236 | |
|
237 | 0 | r_type = ELF32_R_TYPE (dst->r_info); |
238 | 0 | if (r_type >= (unsigned int) R_MT_max) |
239 | 0 | { |
240 | | /* xgettext:c-format */ |
241 | 0 | _bfd_error_handler (_("%pB: unsupported relocation type %#x"), |
242 | 0 | abfd, r_type); |
243 | 0 | bfd_set_error (bfd_error_bad_value); |
244 | 0 | return false; |
245 | 0 | } |
246 | 0 | cache_ptr->howto = & mt_elf_howto_table [r_type]; |
247 | 0 | return true; |
248 | 0 | } |
249 | | |
250 | | /* Perform a single relocation. By default we use the standard BFD |
251 | | routines. */ |
252 | | |
253 | | static bfd_reloc_status_type |
254 | | mt_final_link_relocate |
255 | | (reloc_howto_type * howto, |
256 | | bfd * input_bfd, |
257 | | asection * input_section, |
258 | | bfd_byte * contents, |
259 | | Elf_Internal_Rela * rel, |
260 | | bfd_vma relocation) |
261 | 0 | { |
262 | 0 | return _bfd_final_link_relocate (howto, input_bfd, input_section, |
263 | 0 | contents, rel->r_offset, |
264 | 0 | relocation, rel->r_addend); |
265 | 0 | } |
266 | | |
267 | | /* Relocate a MT ELF section. |
268 | | There is some attempt to make this function usable for many architectures, |
269 | | both USE_REL and USE_RELA ['twould be nice if such a critter existed], |
270 | | if only to serve as a learning tool. |
271 | | |
272 | | The RELOCATE_SECTION function is called by the new ELF backend linker |
273 | | to handle the relocations for a section. |
274 | | |
275 | | The relocs are always passed as Rela structures; if the section |
276 | | actually uses Rel structures, the r_addend field will always be |
277 | | zero. |
278 | | |
279 | | This function is responsible for adjusting the section contents as |
280 | | necessary, and (if using Rela relocs and generating a relocatable |
281 | | output file) adjusting the reloc addend as necessary. |
282 | | |
283 | | This function does not have to worry about setting the reloc |
284 | | address or the reloc symbol index. |
285 | | |
286 | | LOCAL_SYMS is a pointer to the swapped in local symbols. |
287 | | |
288 | | LOCAL_SECTIONS is an array giving the section in the input file |
289 | | corresponding to the st_shndx field of each local symbol. |
290 | | |
291 | | The global hash table entry for the global symbols can be found |
292 | | via elf_sym_hashes (input_bfd). |
293 | | |
294 | | When generating relocatable output, this function must handle |
295 | | STB_LOCAL/STT_SECTION symbols specially. The output symbol is |
296 | | going to be the section symbol corresponding to the output |
297 | | section, which means that the addend must be adjusted |
298 | | accordingly. */ |
299 | | |
300 | | static int |
301 | | mt_elf_relocate_section |
302 | | (bfd * output_bfd ATTRIBUTE_UNUSED, |
303 | | struct bfd_link_info * info, |
304 | | bfd * input_bfd, |
305 | | asection * input_section, |
306 | | bfd_byte * contents, |
307 | | Elf_Internal_Rela * relocs, |
308 | | Elf_Internal_Sym * local_syms, |
309 | | asection ** local_sections) |
310 | 0 | { |
311 | 0 | Elf_Internal_Shdr * symtab_hdr; |
312 | 0 | struct elf_link_hash_entry ** sym_hashes; |
313 | 0 | Elf_Internal_Rela * rel; |
314 | 0 | Elf_Internal_Rela * relend; |
315 | |
|
316 | 0 | symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; |
317 | 0 | sym_hashes = elf_sym_hashes (input_bfd); |
318 | 0 | relend = relocs + input_section->reloc_count; |
319 | |
|
320 | 0 | for (rel = relocs; rel < relend; rel ++) |
321 | 0 | { |
322 | 0 | reloc_howto_type * howto; |
323 | 0 | unsigned long r_symndx; |
324 | 0 | Elf_Internal_Sym * sym; |
325 | 0 | asection * sec; |
326 | 0 | struct elf_link_hash_entry * h; |
327 | 0 | bfd_vma relocation; |
328 | 0 | bfd_reloc_status_type r; |
329 | 0 | const char * name = NULL; |
330 | 0 | int r_type; |
331 | |
|
332 | 0 | r_type = ELF32_R_TYPE (rel->r_info); |
333 | |
|
334 | 0 | r_symndx = ELF32_R_SYM (rel->r_info); |
335 | |
|
336 | 0 | howto = mt_elf_howto_table + ELF32_R_TYPE (rel->r_info); |
337 | 0 | h = NULL; |
338 | 0 | sym = NULL; |
339 | 0 | sec = NULL; |
340 | |
|
341 | 0 | if (r_symndx < symtab_hdr->sh_info) |
342 | 0 | { |
343 | 0 | sym = local_syms + r_symndx; |
344 | 0 | sec = local_sections [r_symndx]; |
345 | 0 | relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); |
346 | |
|
347 | 0 | name = bfd_elf_string_from_elf_section |
348 | 0 | (input_bfd, symtab_hdr->sh_link, sym->st_name); |
349 | 0 | name = name == NULL ? bfd_section_name (sec) : name; |
350 | 0 | } |
351 | 0 | else |
352 | 0 | { |
353 | 0 | bool unresolved_reloc; |
354 | 0 | bool warned, ignored; |
355 | |
|
356 | 0 | RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
357 | 0 | r_symndx, symtab_hdr, sym_hashes, |
358 | 0 | h, sec, relocation, |
359 | 0 | unresolved_reloc, warned, ignored); |
360 | | |
361 | 0 | name = h->root.root.string; |
362 | 0 | } |
363 | | |
364 | 0 | if (sec != NULL && discarded_section (sec)) |
365 | 0 | RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
366 | 0 | rel, 1, relend, howto, 0, contents); |
367 | |
|
368 | 0 | if (bfd_link_relocatable (info)) |
369 | 0 | continue; |
370 | | |
371 | | /* Finally, the sole MT-specific part. */ |
372 | 0 | switch (r_type) |
373 | 0 | { |
374 | 0 | case R_MT_HI16: |
375 | 0 | r = mt_elf_relocate_hi16 (input_bfd, rel, contents, relocation); |
376 | 0 | break; |
377 | 0 | default: |
378 | 0 | r = mt_final_link_relocate (howto, input_bfd, input_section, |
379 | 0 | contents, rel, relocation); |
380 | 0 | break; |
381 | 0 | } |
382 | | |
383 | | |
384 | 0 | if (r != bfd_reloc_ok) |
385 | 0 | { |
386 | 0 | const char * msg = (const char *) NULL; |
387 | |
|
388 | 0 | switch (r) |
389 | 0 | { |
390 | 0 | case bfd_reloc_overflow: |
391 | 0 | (*info->callbacks->reloc_overflow) |
392 | 0 | (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, |
393 | 0 | input_bfd, input_section, rel->r_offset); |
394 | 0 | break; |
395 | | |
396 | 0 | case bfd_reloc_undefined: |
397 | 0 | (*info->callbacks->undefined_symbol) |
398 | 0 | (info, name, input_bfd, input_section, rel->r_offset, true); |
399 | 0 | break; |
400 | | |
401 | 0 | case bfd_reloc_outofrange: |
402 | 0 | msg = _("internal error: out of range error"); |
403 | 0 | break; |
404 | | |
405 | 0 | case bfd_reloc_dangerous: |
406 | 0 | msg = _("internal error: dangerous relocation"); |
407 | 0 | break; |
408 | | |
409 | 0 | default: |
410 | 0 | msg = _("internal error: unknown error"); |
411 | 0 | break; |
412 | 0 | } |
413 | | |
414 | 0 | if (msg) |
415 | 0 | (*info->callbacks->warning) (info, msg, name, input_bfd, |
416 | 0 | input_section, rel->r_offset); |
417 | 0 | } |
418 | 0 | } |
419 | | |
420 | 0 | return true; |
421 | 0 | } |
422 | | |
423 | | /* Look through the relocs for a section during the first phase. |
424 | | Since we don't do .gots or .plts, we just need to consider the |
425 | | virtual table relocs for gc. */ |
426 | | |
427 | | static bool |
428 | | mt_elf_check_relocs (bfd *abfd, |
429 | | struct bfd_link_info *info, |
430 | | asection *sec, |
431 | | const Elf_Internal_Rela *relocs) |
432 | 0 | { |
433 | 0 | Elf_Internal_Shdr *symtab_hdr; |
434 | 0 | struct elf_link_hash_entry **sym_hashes; |
435 | 0 | const Elf_Internal_Rela *rel; |
436 | 0 | const Elf_Internal_Rela *rel_end; |
437 | |
|
438 | 0 | if (bfd_link_relocatable (info)) |
439 | 0 | return true; |
440 | | |
441 | 0 | symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
442 | 0 | sym_hashes = elf_sym_hashes (abfd); |
443 | |
|
444 | 0 | rel_end = relocs + sec->reloc_count; |
445 | 0 | for (rel = relocs; rel < rel_end; rel++) |
446 | 0 | { |
447 | 0 | struct elf_link_hash_entry *h; |
448 | 0 | unsigned long r_symndx; |
449 | |
|
450 | 0 | r_symndx = ELF32_R_SYM (rel->r_info); |
451 | 0 | if (r_symndx < symtab_hdr->sh_info) |
452 | 0 | h = NULL; |
453 | 0 | else |
454 | 0 | { |
455 | 0 | h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
456 | 0 | while (h->root.type == bfd_link_hash_indirect |
457 | 0 | || h->root.type == bfd_link_hash_warning) |
458 | 0 | h = (struct elf_link_hash_entry *) h->root.u.i.link; |
459 | 0 | } |
460 | 0 | } |
461 | |
|
462 | 0 | return true; |
463 | 0 | } |
464 | | |
465 | | /* Return the MACH for an e_flags value. */ |
466 | | |
467 | | static int |
468 | | elf32_mt_machine (bfd *abfd) |
469 | 487 | { |
470 | 487 | switch (elf_elfheader (abfd)->e_flags & EF_MT_CPU_MASK) |
471 | 487 | { |
472 | 2 | case EF_MT_CPU_MRISC: return bfd_mach_ms1; |
473 | 20 | case EF_MT_CPU_MRISC2: return bfd_mach_mrisc2; |
474 | 2 | case EF_MT_CPU_MS2: return bfd_mach_ms2; |
475 | 487 | } |
476 | | |
477 | 463 | return bfd_mach_ms1; |
478 | 487 | } |
479 | | |
480 | | static bool |
481 | | mt_elf_object_p (bfd *abfd) |
482 | 487 | { |
483 | 487 | bfd_default_set_arch_mach (abfd, bfd_arch_mt, elf32_mt_machine (abfd)); |
484 | | |
485 | 487 | return true; |
486 | 487 | } |
487 | | |
488 | | /* Function to set the ELF flag bits. */ |
489 | | |
490 | | static bool |
491 | | mt_elf_set_private_flags (bfd *abfd, flagword flags) |
492 | 0 | { |
493 | 0 | elf_elfheader (abfd)->e_flags = flags; |
494 | 0 | elf_flags_init (abfd) = true; |
495 | 0 | return true; |
496 | 0 | } |
497 | | |
498 | | /* Merge backend specific data from an object file to the output |
499 | | object file when linking. */ |
500 | | |
501 | | static bool |
502 | | mt_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) |
503 | 0 | { |
504 | 0 | bfd *obfd = info->output_bfd; |
505 | 0 | flagword old_flags, new_flags; |
506 | 0 | bool ok = true; |
507 | | |
508 | | /* Check if we have the same endianness. */ |
509 | 0 | if (!_bfd_generic_verify_endian_match (ibfd, info)) |
510 | 0 | return false; |
511 | | |
512 | | /* If they're not both mt, then merging is meaningless, so just |
513 | | don't do it. */ |
514 | 0 | if (strcmp (ibfd->arch_info->arch_name, "mt") != 0) |
515 | 0 | return true; |
516 | 0 | if (strcmp (obfd->arch_info->arch_name, "mt") != 0) |
517 | 0 | return true; |
518 | | |
519 | 0 | new_flags = elf_elfheader (ibfd)->e_flags; |
520 | 0 | old_flags = elf_elfheader (obfd)->e_flags; |
521 | |
|
522 | | #ifdef DEBUG |
523 | | _bfd_error_handler ("%pB: old_flags = 0x%.8x, new_flags = 0x%.8x, init = %s", |
524 | | ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no"); |
525 | | #endif |
526 | |
|
527 | 0 | if (!elf_flags_init (obfd)) |
528 | 0 | { |
529 | 0 | old_flags = new_flags; |
530 | 0 | elf_flags_init (obfd) = true; |
531 | 0 | } |
532 | 0 | else if ((new_flags & EF_MT_CPU_MASK) != (old_flags & EF_MT_CPU_MASK)) |
533 | 0 | { |
534 | | /* CPU has changed. This is invalid, because MRISC, MRISC2 and |
535 | | MS2 are not subsets of each other. */ |
536 | 0 | ok = false; |
537 | 0 | } |
538 | |
|
539 | 0 | if (ok) |
540 | 0 | { |
541 | 0 | obfd->arch_info = ibfd->arch_info; |
542 | 0 | elf_elfheader (obfd)->e_flags = old_flags; |
543 | 0 | } |
544 | |
|
545 | 0 | return ok; |
546 | 0 | } |
547 | | |
548 | | static bool |
549 | | mt_elf_print_private_bfd_data (bfd *abfd, void *ptr) |
550 | 10 | { |
551 | 10 | FILE *file = (FILE *) ptr; |
552 | 10 | flagword flags; |
553 | | |
554 | 10 | BFD_ASSERT (abfd != NULL && ptr != NULL); |
555 | | |
556 | | /* Print normal ELF private data. */ |
557 | 10 | _bfd_elf_print_private_bfd_data (abfd, ptr); |
558 | | |
559 | 10 | flags = elf_elfheader (abfd)->e_flags; |
560 | 10 | fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags); |
561 | | |
562 | 10 | switch (flags & EF_MT_CPU_MASK) |
563 | 10 | { |
564 | 0 | default: |
565 | 0 | case EF_MT_CPU_MRISC: fprintf (file, " ms1-16-002"); break; |
566 | 10 | case EF_MT_CPU_MRISC2: fprintf (file, " ms1-16-003"); break; |
567 | 0 | case EF_MT_CPU_MS2: fprintf (file, " ms2"); break; |
568 | 10 | } |
569 | | |
570 | 10 | fputc ('\n', file); |
571 | | |
572 | 10 | return true; |
573 | 10 | } |
574 | | |
575 | | |
576 | | #define TARGET_BIG_SYM mt_elf32_vec |
577 | | #define TARGET_BIG_NAME "elf32-mt" |
578 | | |
579 | | #define ELF_ARCH bfd_arch_mt |
580 | | #define ELF_MACHINE_CODE EM_MT |
581 | | #define ELF_MAXPAGESIZE 1 /* No pages on the MT. */ |
582 | | |
583 | | #define elf_info_to_howto_rel NULL |
584 | | #define elf_info_to_howto mt_info_to_howto_rela |
585 | | |
586 | | #define elf_backend_relocate_section mt_elf_relocate_section |
587 | | |
588 | | #define bfd_elf32_bfd_reloc_type_lookup mt_reloc_type_lookup |
589 | | #define bfd_elf32_bfd_reloc_name_lookup mt_reloc_name_lookup |
590 | | |
591 | | #define elf_backend_check_relocs mt_elf_check_relocs |
592 | | #define elf_backend_object_p mt_elf_object_p |
593 | | #define elf_backend_rela_normal 1 |
594 | | |
595 | | #define elf_backend_can_gc_sections 1 |
596 | | |
597 | | #define bfd_elf32_bfd_set_private_flags mt_elf_set_private_flags |
598 | | #define bfd_elf32_bfd_merge_private_bfd_data mt_elf_merge_private_bfd_data |
599 | | #define bfd_elf32_bfd_print_private_bfd_data mt_elf_print_private_bfd_data |
600 | | |
601 | | #include "elf32-target.h" |