/src/binutils-gdb/bfd/elf32-mt.c
Line | Count | Source |
1 | | /* Morpho Technologies MT specific support for 32-bit ELF |
2 | | Copyright (C) 2001-2026 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, R_MT_NONE, |
367 | 0 | howto, 0, contents); |
368 | |
|
369 | 0 | if (bfd_link_relocatable (info)) |
370 | 0 | continue; |
371 | | |
372 | | /* Finally, the sole MT-specific part. */ |
373 | 0 | switch (r_type) |
374 | 0 | { |
375 | 0 | case R_MT_HI16: |
376 | 0 | r = mt_elf_relocate_hi16 (input_bfd, rel, contents, relocation); |
377 | 0 | break; |
378 | 0 | default: |
379 | 0 | r = mt_final_link_relocate (howto, input_bfd, input_section, |
380 | 0 | contents, rel, relocation); |
381 | 0 | break; |
382 | 0 | } |
383 | | |
384 | | |
385 | 0 | if (r != bfd_reloc_ok) |
386 | 0 | { |
387 | 0 | const char * msg = (const char *) NULL; |
388 | |
|
389 | 0 | switch (r) |
390 | 0 | { |
391 | 0 | case bfd_reloc_overflow: |
392 | 0 | (*info->callbacks->reloc_overflow) |
393 | 0 | (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, |
394 | 0 | input_bfd, input_section, rel->r_offset); |
395 | 0 | break; |
396 | | |
397 | 0 | case bfd_reloc_undefined: |
398 | 0 | (*info->callbacks->undefined_symbol) |
399 | 0 | (info, name, input_bfd, input_section, rel->r_offset, true); |
400 | 0 | break; |
401 | | |
402 | 0 | case bfd_reloc_outofrange: |
403 | 0 | msg = _("internal error: out of range error"); |
404 | 0 | break; |
405 | | |
406 | 0 | case bfd_reloc_dangerous: |
407 | 0 | msg = _("internal error: dangerous relocation"); |
408 | 0 | break; |
409 | | |
410 | 0 | default: |
411 | 0 | msg = _("internal error: unknown error"); |
412 | 0 | break; |
413 | 0 | } |
414 | | |
415 | 0 | if (msg) |
416 | 0 | (*info->callbacks->warning) (info, msg, name, input_bfd, |
417 | 0 | input_section, rel->r_offset); |
418 | 0 | } |
419 | 0 | } |
420 | | |
421 | 0 | return true; |
422 | 0 | } |
423 | | |
424 | | /* Look through the relocs for a section during the first phase. |
425 | | Since we don't do .gots or .plts, we just need to consider the |
426 | | virtual table relocs for gc. */ |
427 | | |
428 | | static bool |
429 | | mt_elf_check_relocs (bfd *abfd, |
430 | | struct bfd_link_info *info, |
431 | | asection *sec, |
432 | | const Elf_Internal_Rela *relocs) |
433 | 0 | { |
434 | 0 | Elf_Internal_Shdr *symtab_hdr; |
435 | 0 | struct elf_link_hash_entry **sym_hashes; |
436 | 0 | const Elf_Internal_Rela *rel; |
437 | 0 | const Elf_Internal_Rela *rel_end; |
438 | |
|
439 | 0 | if (bfd_link_relocatable (info)) |
440 | 0 | return true; |
441 | | |
442 | 0 | symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
443 | 0 | sym_hashes = elf_sym_hashes (abfd); |
444 | |
|
445 | 0 | rel_end = relocs + sec->reloc_count; |
446 | 0 | for (rel = relocs; rel < rel_end; rel++) |
447 | 0 | { |
448 | 0 | struct elf_link_hash_entry *h; |
449 | 0 | unsigned long r_symndx; |
450 | |
|
451 | 0 | r_symndx = ELF32_R_SYM (rel->r_info); |
452 | 0 | if (r_symndx < symtab_hdr->sh_info) |
453 | 0 | h = NULL; |
454 | 0 | else |
455 | 0 | { |
456 | 0 | h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
457 | 0 | while (h->root.type == bfd_link_hash_indirect |
458 | 0 | || h->root.type == bfd_link_hash_warning) |
459 | 0 | h = (struct elf_link_hash_entry *) h->root.u.i.link; |
460 | 0 | } |
461 | 0 | } |
462 | |
|
463 | 0 | return true; |
464 | 0 | } |
465 | | |
466 | | /* Return the MACH for an e_flags value. */ |
467 | | |
468 | | static int |
469 | | elf32_mt_machine (bfd *abfd) |
470 | 58 | { |
471 | 58 | switch (elf_elfheader (abfd)->e_flags & EF_MT_CPU_MASK) |
472 | 58 | { |
473 | 0 | case EF_MT_CPU_MRISC: return bfd_mach_ms1; |
474 | 34 | case EF_MT_CPU_MRISC2: return bfd_mach_mrisc2; |
475 | 6 | case EF_MT_CPU_MS2: return bfd_mach_ms2; |
476 | 58 | } |
477 | | |
478 | 18 | return bfd_mach_ms1; |
479 | 58 | } |
480 | | |
481 | | static bool |
482 | | mt_elf_object_p (bfd *abfd) |
483 | 58 | { |
484 | 58 | bfd_default_set_arch_mach (abfd, bfd_arch_mt, elf32_mt_machine (abfd)); |
485 | | |
486 | 58 | return true; |
487 | 58 | } |
488 | | |
489 | | /* Function to set the ELF flag bits. */ |
490 | | |
491 | | static bool |
492 | | mt_elf_set_private_flags (bfd *abfd, flagword flags) |
493 | 0 | { |
494 | 0 | elf_elfheader (abfd)->e_flags = flags; |
495 | 0 | elf_flags_init (abfd) = true; |
496 | 0 | return true; |
497 | 0 | } |
498 | | |
499 | | /* Merge backend specific data from an object file to the output |
500 | | object file when linking. */ |
501 | | |
502 | | static bool |
503 | | mt_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) |
504 | 0 | { |
505 | 0 | bfd *obfd = info->output_bfd; |
506 | 0 | flagword old_flags, new_flags; |
507 | 0 | bool ok = true; |
508 | | |
509 | | /* Check if we have the same endianness. */ |
510 | 0 | if (!_bfd_generic_verify_endian_match (ibfd, info)) |
511 | 0 | return false; |
512 | | |
513 | | /* If they're not both mt, then merging is meaningless, so just |
514 | | don't do it. */ |
515 | 0 | if (strcmp (ibfd->arch_info->arch_name, "mt") != 0) |
516 | 0 | return true; |
517 | 0 | if (strcmp (obfd->arch_info->arch_name, "mt") != 0) |
518 | 0 | return true; |
519 | | |
520 | 0 | new_flags = elf_elfheader (ibfd)->e_flags; |
521 | 0 | old_flags = elf_elfheader (obfd)->e_flags; |
522 | |
|
523 | | #ifdef DEBUG |
524 | | _bfd_error_handler ("%pB: old_flags = 0x%.8x, new_flags = 0x%.8x, init = %s", |
525 | | ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no"); |
526 | | #endif |
527 | |
|
528 | 0 | if (!elf_flags_init (obfd)) |
529 | 0 | { |
530 | 0 | old_flags = new_flags; |
531 | 0 | elf_flags_init (obfd) = true; |
532 | 0 | } |
533 | 0 | else if ((new_flags & EF_MT_CPU_MASK) != (old_flags & EF_MT_CPU_MASK)) |
534 | 0 | { |
535 | | /* CPU has changed. This is invalid, because MRISC, MRISC2 and |
536 | | MS2 are not subsets of each other. */ |
537 | 0 | ok = false; |
538 | 0 | } |
539 | |
|
540 | 0 | if (ok) |
541 | 0 | { |
542 | 0 | obfd->arch_info = ibfd->arch_info; |
543 | 0 | elf_elfheader (obfd)->e_flags = old_flags; |
544 | 0 | } |
545 | |
|
546 | 0 | return ok; |
547 | 0 | } |
548 | | |
549 | | static bool |
550 | | mt_elf_print_private_bfd_data (bfd *abfd, void *ptr) |
551 | 26 | { |
552 | 26 | FILE *file = (FILE *) ptr; |
553 | 26 | flagword flags; |
554 | | |
555 | 26 | BFD_ASSERT (abfd != NULL && ptr != NULL); |
556 | | |
557 | | /* Print normal ELF private data. */ |
558 | 26 | _bfd_elf_print_private_bfd_data (abfd, ptr); |
559 | | |
560 | 26 | flags = elf_elfheader (abfd)->e_flags; |
561 | 26 | fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags); |
562 | | |
563 | 26 | switch (flags & EF_MT_CPU_MASK) |
564 | 26 | { |
565 | 7 | default: |
566 | 7 | case EF_MT_CPU_MRISC: fprintf (file, " ms1-16-002"); break; |
567 | 16 | case EF_MT_CPU_MRISC2: fprintf (file, " ms1-16-003"); break; |
568 | 3 | case EF_MT_CPU_MS2: fprintf (file, " ms2"); break; |
569 | 26 | } |
570 | | |
571 | 26 | fputc ('\n', file); |
572 | | |
573 | | return true; |
574 | 26 | } |
575 | | |
576 | | |
577 | | #define TARGET_BIG_SYM mt_elf32_vec |
578 | | #define TARGET_BIG_NAME "elf32-mt" |
579 | | |
580 | | #define ELF_ARCH bfd_arch_mt |
581 | | #define ELF_MACHINE_CODE EM_MT |
582 | | #define ELF_MAXPAGESIZE 1 /* No pages on the MT. */ |
583 | | |
584 | | #define elf_info_to_howto_rel NULL |
585 | | #define elf_info_to_howto mt_info_to_howto_rela |
586 | | |
587 | | #define elf_backend_relocate_section mt_elf_relocate_section |
588 | | |
589 | | #define bfd_elf32_bfd_reloc_type_lookup mt_reloc_type_lookup |
590 | | #define bfd_elf32_bfd_reloc_name_lookup mt_reloc_name_lookup |
591 | | |
592 | | #define elf_backend_check_relocs mt_elf_check_relocs |
593 | | #define elf_backend_object_p mt_elf_object_p |
594 | | #define elf_backend_rela_normal 1 |
595 | | |
596 | | #define elf_backend_can_gc_sections 1 |
597 | | |
598 | | #define bfd_elf32_bfd_set_private_flags mt_elf_set_private_flags |
599 | | #define bfd_elf32_bfd_merge_private_bfd_data mt_elf_merge_private_bfd_data |
600 | | #define bfd_elf32_bfd_print_private_bfd_data mt_elf_print_private_bfd_data |
601 | | |
602 | | #include "elf32-target.h" |