1 /* Matsushita 10300 specific support for 32-bit ELF
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
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 2 of the License, or
9 (at your option) any later version.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 static reloc_howto_type
*bfd_elf32_bfd_reloc_type_lookup
26 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type code
));
27 static void mn10300_info_to_howto
28 PARAMS ((bfd
*, arelent
*, Elf32_Internal_Rela
*));
29 static bfd_reloc_status_type bfd_elf32_mn10300_reloc
30 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
33 /* We have to use RELA instructions since md_apply_fix3 in the assembler
34 does absolutely nothing. */
49 static reloc_howto_type elf_mn10300_howto_table
[] =
51 /* Dummy relocation. Does nothing. */
52 HOWTO (R_MN10300_NONE
,
58 complain_overflow_bitfield
,
59 bfd_elf_generic_reloc
,
65 /* Standard 32 bit reloc. */
72 complain_overflow_bitfield
,
73 bfd_elf_generic_reloc
,
79 /* Standard 16 bit reloc. */
86 complain_overflow_bitfield
,
87 bfd_elf_generic_reloc
,
93 /* Standard 8 bit reloc. */
100 complain_overflow_bitfield
,
101 bfd_elf_generic_reloc
,
107 /* Standard 32bit pc-relative reloc. */
108 HOWTO (R_MN10300_PCREL32
,
114 complain_overflow_bitfield
,
115 bfd_elf_generic_reloc
,
121 /* Standard 16bit pc-relative reloc. */
122 HOWTO (R_MN10300_PCREL16
,
128 complain_overflow_bitfield
,
129 bfd_elf_generic_reloc
,
135 /* Standard 8 pc-relative reloc. */
136 HOWTO (R_MN10300_PCREL8
,
142 complain_overflow_bitfield
,
143 bfd_elf_generic_reloc
,
151 struct mn10300_reloc_map
153 unsigned char bfd_reloc_val
;
154 unsigned char elf_reloc_val
;
157 static const struct mn10300_reloc_map mn10300_reloc_map
[] =
159 { BFD_RELOC_NONE
, R_MN10300_NONE
, },
160 { BFD_RELOC_32
, R_MN10300_32
, },
161 { BFD_RELOC_16
, R_MN10300_16
, },
162 { BFD_RELOC_8
, R_MN10300_8
, },
163 { BFD_RELOC_32_PCREL
, R_MN10300_PCREL32
, },
164 { BFD_RELOC_16_PCREL
, R_MN10300_PCREL16
, },
165 { BFD_RELOC_8_PCREL
, R_MN10300_PCREL8
, },
168 static reloc_howto_type
*
169 bfd_elf32_bfd_reloc_type_lookup (abfd
, code
)
171 bfd_reloc_code_real_type code
;
176 i
< sizeof (mn10300_reloc_map
) / sizeof (struct mn10300_reloc_map
);
179 if (mn10300_reloc_map
[i
].bfd_reloc_val
== code
)
180 return &elf_mn10300_howto_table
[mn10300_reloc_map
[i
].elf_reloc_val
];
186 /* Set the howto pointer for an MN10300 ELF reloc. */
189 mn10300_info_to_howto (abfd
, cache_ptr
, dst
)
192 Elf32_Internal_Rela
*dst
;
196 r_type
= ELF32_R_TYPE (dst
->r_info
);
197 BFD_ASSERT (r_type
< (unsigned int) R_MN10300_MAX
);
198 cache_ptr
->howto
= &elf_mn10300_howto_table
[r_type
];
201 /* Perform a relocation as part of a final link. */
202 static bfd_reloc_status_type
203 mn10300_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
204 input_section
, contents
, offset
, value
,
205 addend
, info
, sym_sec
, is_local
)
206 reloc_howto_type
*howto
;
209 asection
*input_section
;
214 struct bfd_link_info
*info
;
218 unsigned long r_type
= howto
->type
;
219 bfd_byte
*hit_data
= contents
+ offset
;
229 bfd_put_32 (input_bfd
, value
, hit_data
);
235 if ((long)value
> 0x7fff || (long)value
< -0x8000)
236 return bfd_reloc_overflow
;
238 bfd_put_16 (input_bfd
, value
, hit_data
);
244 if ((long)value
> 0x7fff || (long)value
< -0x8000)
245 return bfd_reloc_overflow
;
247 bfd_put_8 (input_bfd
, value
, hit_data
);
250 case R_MN10300_PCREL8
:
251 value
-= (input_section
->output_section
->vma
252 + input_section
->output_offset
);
256 if ((long)value
> 0xff || (long)value
< -0x100)
257 return bfd_reloc_overflow
;
259 bfd_put_8 (input_bfd
, value
, hit_data
);
262 case R_MN10300_PCREL16
:
263 value
-= (input_section
->output_section
->vma
264 + input_section
->output_offset
);
268 if ((long)value
> 0xffff || (long)value
< -0x10000)
269 return bfd_reloc_overflow
;
271 bfd_put_16 (input_bfd
, value
, hit_data
);
274 case R_MN10300_PCREL32
:
275 value
-= (input_section
->output_section
->vma
276 + input_section
->output_offset
);
280 bfd_put_32 (input_bfd
, value
, hit_data
);
284 return bfd_reloc_notsupported
;
289 /* Relocate an MN10300 ELF section. */
291 mn10300_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
292 contents
, relocs
, local_syms
, local_sections
)
294 struct bfd_link_info
*info
;
296 asection
*input_section
;
298 Elf_Internal_Rela
*relocs
;
299 Elf_Internal_Sym
*local_syms
;
300 asection
**local_sections
;
302 Elf_Internal_Shdr
*symtab_hdr
;
303 struct elf_link_hash_entry
**sym_hashes
;
304 Elf_Internal_Rela
*rel
, *relend
;
306 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
307 sym_hashes
= elf_sym_hashes (input_bfd
);
310 relend
= relocs
+ input_section
->reloc_count
;
311 for (; rel
< relend
; rel
++)
314 reloc_howto_type
*howto
;
315 unsigned long r_symndx
;
316 Elf_Internal_Sym
*sym
;
318 struct elf_link_hash_entry
*h
;
320 bfd_reloc_status_type r
;
322 r_symndx
= ELF32_R_SYM (rel
->r_info
);
323 r_type
= ELF32_R_TYPE (rel
->r_info
);
324 howto
= elf_mn10300_howto_table
+ r_type
;
326 if (info
->relocateable
)
328 /* This is a relocateable link. We don't have to change
329 anything, unless the reloc is against a section symbol,
330 in which case we have to adjust according to where the
331 section symbol winds up in the output section. */
332 if (r_symndx
< symtab_hdr
->sh_info
)
334 sym
= local_syms
+ r_symndx
;
335 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
337 sec
= local_sections
[r_symndx
];
338 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
345 /* This is a final link. */
349 if (r_symndx
< symtab_hdr
->sh_info
)
351 sym
= local_syms
+ r_symndx
;
352 sec
= local_sections
[r_symndx
];
353 relocation
= (sec
->output_section
->vma
359 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
360 while (h
->root
.type
== bfd_link_hash_indirect
361 || h
->root
.type
== bfd_link_hash_warning
)
362 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
363 if (h
->root
.type
== bfd_link_hash_defined
364 || h
->root
.type
== bfd_link_hash_defweak
)
366 sec
= h
->root
.u
.def
.section
;
367 relocation
= (h
->root
.u
.def
.value
368 + sec
->output_section
->vma
369 + sec
->output_offset
);
371 else if (h
->root
.type
== bfd_link_hash_undefweak
)
375 if (! ((*info
->callbacks
->undefined_symbol
)
376 (info
, h
->root
.root
.string
, input_bfd
,
377 input_section
, rel
->r_offset
)))
383 r
= mn10300_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
385 contents
, rel
->r_offset
,
386 relocation
, rel
->r_addend
,
387 info
, sec
, h
== NULL
);
389 if (r
!= bfd_reloc_ok
)
392 const char *msg
= (const char *)0;
395 name
= h
->root
.root
.string
;
398 name
= (bfd_elf_string_from_elf_section
399 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
400 if (name
== NULL
|| *name
== '\0')
401 name
= bfd_section_name (input_bfd
, sec
);
406 case bfd_reloc_overflow
:
407 if (! ((*info
->callbacks
->reloc_overflow
)
408 (info
, name
, howto
->name
, (bfd_vma
) 0,
409 input_bfd
, input_section
, rel
->r_offset
)))
413 case bfd_reloc_undefined
:
414 if (! ((*info
->callbacks
->undefined_symbol
)
415 (info
, name
, input_bfd
, input_section
,
420 case bfd_reloc_outofrange
:
421 msg
= "internal error: out of range error";
424 case bfd_reloc_notsupported
:
425 msg
= "internal error: unsupported relocation error";
428 case bfd_reloc_dangerous
:
429 msg
= "internal error: dangerous error";
433 msg
= "internal error: unknown error";
437 if (!((*info
->callbacks
->warning
)
438 (info
, msg
, name
, input_bfd
, input_section
,
449 #define TARGET_LITTLE_SYM bfd_elf32_mn10300_vec
450 #define TARGET_LITTLE_NAME "elf32-mn10300"
451 #define ELF_ARCH bfd_arch_mn10300
452 #define ELF_MACHINE_CODE EM_CYGNUS_MN10300
453 #define ELF_MAXPAGESIZE 0x1000
455 #define elf_info_to_howto mn10300_info_to_howto
456 #define elf_info_to_howto_rel 0
457 #define elf_backend_relocate_section mn10300_elf_relocate_section
459 #define elf_symbol_leading_char '_'
461 #include "elf32-target.h"