1 /* Renesas RL78 specific support for 32-bit ELF.
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "bfd_stdint.h"
27 #include "libiberty.h"
29 #define valid_16bit_address(v) ((v) <= 0x0ffff || (v) >= 0xf0000)
31 #define RL78REL(n,sz,bit,shift,complain,pcrel) \
32 HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
33 bfd_elf_generic_reloc, "R_RL78_" #n, FALSE, 0, ~0, FALSE)
35 /* Note that the relocations around 0x7f are internal to this file;
36 feel free to move them as needed to avoid conflicts with published
37 relocation numbers. */
39 static reloc_howto_type rl78_elf_howto_table
[] =
41 RL78REL (NONE
, 0, 0, 0, dont
, FALSE
),
42 RL78REL (DIR32
, 2, 32, 0, signed, FALSE
),
43 RL78REL (DIR24S
, 2, 24, 0, signed, FALSE
),
44 RL78REL (DIR16
, 1, 16, 0, dont
, FALSE
),
45 RL78REL (DIR16U
, 1, 16, 0, unsigned, FALSE
),
46 RL78REL (DIR16S
, 1, 16, 0, signed, FALSE
),
47 RL78REL (DIR8
, 0, 8, 0, dont
, FALSE
),
48 RL78REL (DIR8U
, 0, 8, 0, unsigned, FALSE
),
49 RL78REL (DIR8S
, 0, 8, 0, signed, FALSE
),
50 RL78REL (DIR24S_PCREL
, 2, 24, 0, signed, TRUE
),
51 RL78REL (DIR16S_PCREL
, 1, 16, 0, signed, TRUE
),
52 RL78REL (DIR8S_PCREL
, 0, 8, 0, signed, TRUE
),
53 RL78REL (DIR16UL
, 1, 16, 2, unsigned, FALSE
),
54 RL78REL (DIR16UW
, 1, 16, 1, unsigned, FALSE
),
55 RL78REL (DIR8UL
, 0, 8, 2, unsigned, FALSE
),
56 RL78REL (DIR8UW
, 0, 8, 1, unsigned, FALSE
),
57 RL78REL (DIR32_REV
, 1, 16, 0, dont
, FALSE
),
58 RL78REL (DIR16_REV
, 1, 16, 0, dont
, FALSE
),
59 RL78REL (DIR3U_PCREL
, 0, 3, 0, dont
, TRUE
),
110 RL78REL (ABS32
, 2, 32, 0, dont
, FALSE
),
111 RL78REL (ABS24S
, 2, 24, 0, signed, FALSE
),
112 RL78REL (ABS16
, 1, 16, 0, dont
, FALSE
),
113 RL78REL (ABS16U
, 1, 16, 0, unsigned, FALSE
),
114 RL78REL (ABS16S
, 1, 16, 0, signed, FALSE
),
115 RL78REL (ABS8
, 0, 8, 0, dont
, FALSE
),
116 RL78REL (ABS8U
, 0, 8, 0, unsigned, FALSE
),
117 RL78REL (ABS8S
, 0, 8, 0, signed, FALSE
),
118 RL78REL (ABS24S_PCREL
, 2, 24, 0, signed, TRUE
),
119 RL78REL (ABS16S_PCREL
, 1, 16, 0, signed, TRUE
),
120 RL78REL (ABS8S_PCREL
, 0, 8, 0, signed, TRUE
),
121 RL78REL (ABS16UL
, 1, 16, 0, unsigned, FALSE
),
122 RL78REL (ABS16UW
, 1, 16, 0, unsigned, FALSE
),
123 RL78REL (ABS8UL
, 0, 8, 0, unsigned, FALSE
),
124 RL78REL (ABS8UW
, 0, 8, 0, unsigned, FALSE
),
125 RL78REL (ABS32_REV
, 2, 32, 0, dont
, FALSE
),
126 RL78REL (ABS16_REV
, 1, 16, 0, dont
, FALSE
),
128 #define STACK_REL_P(x) ((x) <= R_RL78_ABS16_REV && (x) >= R_RL78_ABS32)
178 RL78REL (SYM
, 2, 32, 0, dont
, FALSE
),
179 RL78REL (OPneg
, 2, 32, 0, dont
, FALSE
),
180 RL78REL (OPadd
, 2, 32, 0, dont
, FALSE
),
181 RL78REL (OPsub
, 2, 32, 0, dont
, FALSE
),
182 RL78REL (OPmul
, 2, 32, 0, dont
, FALSE
),
183 RL78REL (OPdiv
, 2, 32, 0, dont
, FALSE
),
184 RL78REL (OPshla
, 2, 32, 0, dont
, FALSE
),
185 RL78REL (OPshra
, 2, 32, 0, dont
, FALSE
),
186 RL78REL (OPsctsize
, 2, 32, 0, dont
, FALSE
),
191 RL78REL (OPscttop
, 2, 32, 0, dont
, FALSE
),
194 RL78REL (OPand
, 2, 32, 0, dont
, FALSE
),
195 RL78REL (OPor
, 2, 32, 0, dont
, FALSE
),
196 RL78REL (OPxor
, 2, 32, 0, dont
, FALSE
),
197 RL78REL (OPnot
, 2, 32, 0, dont
, FALSE
),
198 RL78REL (OPmod
, 2, 32, 0, dont
, FALSE
),
199 RL78REL (OPromtop
, 2, 32, 0, dont
, FALSE
),
200 RL78REL (OPramtop
, 2, 32, 0, dont
, FALSE
)
203 /* Map BFD reloc types to RL78 ELF reloc types. */
205 struct rl78_reloc_map
207 bfd_reloc_code_real_type bfd_reloc_val
;
208 unsigned int rl78_reloc_val
;
211 static const struct rl78_reloc_map rl78_reloc_map
[] =
213 { BFD_RELOC_NONE
, R_RL78_NONE
},
214 { BFD_RELOC_8
, R_RL78_DIR8S
},
215 { BFD_RELOC_16
, R_RL78_DIR16S
},
216 { BFD_RELOC_24
, R_RL78_DIR24S
},
217 { BFD_RELOC_32
, R_RL78_DIR32
},
218 { BFD_RELOC_RL78_16_OP
, R_RL78_DIR16
},
219 { BFD_RELOC_RL78_DIR3U_PCREL
, R_RL78_DIR3U_PCREL
},
220 { BFD_RELOC_8_PCREL
, R_RL78_DIR8S_PCREL
},
221 { BFD_RELOC_16_PCREL
, R_RL78_DIR16S_PCREL
},
222 { BFD_RELOC_24_PCREL
, R_RL78_DIR24S_PCREL
},
223 { BFD_RELOC_RL78_8U
, R_RL78_DIR8U
},
224 { BFD_RELOC_RL78_16U
, R_RL78_DIR16U
},
225 { BFD_RELOC_RL78_SYM
, R_RL78_SYM
},
226 { BFD_RELOC_RL78_OP_SUBTRACT
, R_RL78_OPsub
},
227 { BFD_RELOC_RL78_OP_NEG
, R_RL78_OPneg
},
228 { BFD_RELOC_RL78_OP_AND
, R_RL78_OPand
},
229 { BFD_RELOC_RL78_OP_SHRA
, R_RL78_OPshra
},
230 { BFD_RELOC_RL78_ABS8
, R_RL78_ABS8
},
231 { BFD_RELOC_RL78_ABS16
, R_RL78_ABS16
},
232 { BFD_RELOC_RL78_ABS16_REV
, R_RL78_ABS16_REV
},
233 { BFD_RELOC_RL78_ABS32
, R_RL78_ABS32
},
234 { BFD_RELOC_RL78_ABS32_REV
, R_RL78_ABS32_REV
},
235 { BFD_RELOC_RL78_ABS16UL
, R_RL78_ABS16UL
},
236 { BFD_RELOC_RL78_ABS16UW
, R_RL78_ABS16UW
},
237 { BFD_RELOC_RL78_ABS16U
, R_RL78_ABS16U
}
240 static reloc_howto_type
*
241 rl78_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
242 bfd_reloc_code_real_type code
)
246 if (code
== BFD_RELOC_RL78_32_OP
)
247 return rl78_elf_howto_table
+ R_RL78_DIR32
;
249 for (i
= ARRAY_SIZE (rl78_reloc_map
); --i
;)
250 if (rl78_reloc_map
[i
].bfd_reloc_val
== code
)
251 return rl78_elf_howto_table
+ rl78_reloc_map
[i
].rl78_reloc_val
;
256 static reloc_howto_type
*
257 rl78_reloc_name_lookup (bfd
* abfd ATTRIBUTE_UNUSED
, const char * r_name
)
261 for (i
= 0; i
< ARRAY_SIZE (rl78_elf_howto_table
); i
++)
262 if (rl78_elf_howto_table
[i
].name
!= NULL
263 && strcasecmp (rl78_elf_howto_table
[i
].name
, r_name
) == 0)
264 return rl78_elf_howto_table
+ i
;
269 /* Set the howto pointer for an RL78 ELF reloc. */
272 rl78_info_to_howto_rela (bfd
* abfd ATTRIBUTE_UNUSED
,
274 Elf_Internal_Rela
* dst
)
278 r_type
= ELF32_R_TYPE (dst
->r_info
);
279 BFD_ASSERT (r_type
< (unsigned int) R_RL78_max
);
280 cache_ptr
->howto
= rl78_elf_howto_table
+ r_type
;
284 get_symbol_value (const char * name
,
285 bfd_reloc_status_type
* status
,
286 struct bfd_link_info
* info
,
288 asection
* input_section
,
292 struct bfd_link_hash_entry
* h
;
294 h
= bfd_link_hash_lookup (info
->hash
, name
, FALSE
, FALSE
, TRUE
);
297 || (h
->type
!= bfd_link_hash_defined
298 && h
->type
!= bfd_link_hash_defweak
))
299 * status
= info
->callbacks
->undefined_symbol
300 (info
, name
, input_bfd
, input_section
, offset
, TRUE
);
302 value
= (h
->u
.def
.value
303 + h
->u
.def
.section
->output_section
->vma
304 + h
->u
.def
.section
->output_offset
);
310 get_romstart (bfd_reloc_status_type
* status
,
311 struct bfd_link_info
* info
,
316 static bfd_boolean cached
= FALSE
;
317 static bfd_vma cached_value
= 0;
321 cached_value
= get_symbol_value ("_start", status
, info
, abfd
, sec
, offset
);
328 get_ramstart (bfd_reloc_status_type
* status
,
329 struct bfd_link_info
* info
,
334 static bfd_boolean cached
= FALSE
;
335 static bfd_vma cached_value
= 0;
339 cached_value
= get_symbol_value ("__datastart", status
, info
, abfd
, sec
, offset
);
345 #define NUM_STACK_ENTRIES 16
346 static int32_t rl78_stack
[ NUM_STACK_ENTRIES
];
347 static unsigned int rl78_stack_top
;
349 #define RL78_STACK_PUSH(val) \
352 if (rl78_stack_top < NUM_STACK_ENTRIES) \
353 rl78_stack [rl78_stack_top ++] = (val); \
355 r = bfd_reloc_dangerous; \
359 #define RL78_STACK_POP(dest) \
362 if (rl78_stack_top > 0) \
363 (dest) = rl78_stack [-- rl78_stack_top]; \
365 (dest) = 0, r = bfd_reloc_dangerous; \
369 /* Relocate an RL78 ELF section.
370 There is some attempt to make this function usable for many architectures,
371 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
372 if only to serve as a learning tool.
374 The RELOCATE_SECTION function is called by the new ELF backend linker
375 to handle the relocations for a section.
377 The relocs are always passed as Rela structures; if the section
378 actually uses Rel structures, the r_addend field will always be
381 This function is responsible for adjusting the section contents as
382 necessary, and (if using Rela relocs and generating a relocatable
383 output file) adjusting the reloc addend as necessary.
385 This function does not have to worry about setting the reloc
386 address or the reloc symbol index.
388 LOCAL_SYMS is a pointer to the swapped in local symbols.
390 LOCAL_SECTIONS is an array giving the section in the input file
391 corresponding to the st_shndx field of each local symbol.
393 The global hash table entry for the global symbols can be found
394 via elf_sym_hashes (input_bfd).
396 When generating relocatable output, this function must handle
397 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
398 going to be the section symbol corresponding to the output
399 section, which means that the addend must be adjusted
403 rl78_elf_relocate_section
405 struct bfd_link_info
* info
,
407 asection
* input_section
,
409 Elf_Internal_Rela
* relocs
,
410 Elf_Internal_Sym
* local_syms
,
411 asection
** local_sections
)
413 Elf_Internal_Shdr
* symtab_hdr
;
414 struct elf_link_hash_entry
** sym_hashes
;
415 Elf_Internal_Rela
* rel
;
416 Elf_Internal_Rela
* relend
;
420 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
421 sym_hashes
= elf_sym_hashes (input_bfd
);
422 relend
= relocs
+ input_section
->reloc_count
;
424 dynobj
= elf_hash_table (info
)->dynobj
;
427 splt
= bfd_get_section_by_name (dynobj
, ".plt");
429 for (rel
= relocs
; rel
< relend
; rel
++)
431 reloc_howto_type
* howto
;
432 unsigned long r_symndx
;
433 Elf_Internal_Sym
* sym
;
435 struct elf_link_hash_entry
* h
;
437 bfd_reloc_status_type r
;
438 const char * name
= NULL
;
439 bfd_boolean unresolved_reloc
= TRUE
;
442 r_type
= ELF32_R_TYPE (rel
->r_info
);
443 r_symndx
= ELF32_R_SYM (rel
->r_info
);
445 howto
= rl78_elf_howto_table
+ ELF32_R_TYPE (rel
->r_info
);
451 if (r_symndx
< symtab_hdr
->sh_info
)
453 sym
= local_syms
+ r_symndx
;
454 sec
= local_sections
[r_symndx
];
455 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, & sec
, rel
);
457 name
= bfd_elf_string_from_elf_section
458 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
459 name
= (sym
->st_name
== 0) ? bfd_section_name (input_bfd
, sec
) : name
;
465 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
466 r_symndx
, symtab_hdr
, sym_hashes
, h
,
467 sec
, relocation
, unresolved_reloc
,
470 name
= h
->root
.root
.string
;
473 if (sec
!= NULL
&& elf_discarded_section (sec
))
474 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
475 rel
, relend
, howto
, contents
);
477 if (info
->relocatable
)
479 /* This is a relocatable link. We don't have to change
480 anything, unless the reloc is against a section symbol,
481 in which case we have to adjust according to where the
482 section symbol winds up in the output section. */
483 if (sym
!= NULL
&& ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
484 rel
->r_addend
+= sec
->output_offset
;
488 switch (ELF32_R_TYPE (rel
->r_info
))
495 plt_offset
= &h
->plt
.offset
;
497 plt_offset
= elf_local_got_offsets (input_bfd
) + r_symndx
;
499 /* printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
500 relocation, *plt_offset);*/
501 if (valid_16bit_address (relocation
))
503 /* If the symbol is in range for a 16-bit address, we should
504 have deallocated the plt entry in relax_section. */
505 BFD_ASSERT (*plt_offset
== (bfd_vma
) -1);
509 /* If the symbol is out of range for a 16-bit address,
510 we must have allocated a plt entry. */
511 BFD_ASSERT (*plt_offset
!= (bfd_vma
) -1);
513 /* If this is the first time we've processed this symbol,
514 fill in the plt entry with the correct symbol address. */
515 if ((*plt_offset
& 1) == 0)
519 x
= 0x000000ec; /* br !!abs24 */
520 x
|= (relocation
<< 8) & 0xffffff00;
521 bfd_put_32 (input_bfd
, x
, splt
->contents
+ *plt_offset
);
525 relocation
= (splt
->output_section
->vma
526 + splt
->output_offset
527 + (*plt_offset
& -2));
530 char *newname
= bfd_malloc (strlen(name
)+5);
531 strcpy (newname
, name
);
532 strcat(newname
, ".plt");
533 _bfd_generic_link_add_one_symbol (info
,
536 BSF_FUNCTION
| BSF_WEAK
,
549 if (h
!= NULL
&& h
->root
.type
== bfd_link_hash_undefweak
)
550 /* If the symbol is undefined and weak
551 then the relocation resolves to zero. */
555 if (howto
->pc_relative
)
557 relocation
-= (input_section
->output_section
->vma
558 + input_section
->output_offset
560 relocation
-= bfd_get_reloc_size (howto
);
563 relocation
+= rel
->r_addend
;
568 #define RANGE(a,b) if (a > (long) relocation || (long) relocation > b) r = bfd_reloc_overflow
569 #define ALIGN(m) if (relocation & m) r = bfd_reloc_other;
570 #define OP(i) (contents[rel->r_offset + (i)])
572 /* Opcode relocs are always big endian. Data relocs are bi-endian. */
578 case R_RL78_DIR8S_PCREL
:
593 case R_RL78_DIR16S_PCREL
:
594 RANGE (-32768, 32767);
596 OP (1) = relocation
>> 8;
600 if ((relocation
& 0xf0000) == 0xf0000)
601 relocation
&= 0xffff;
602 RANGE (-32768, 65535);
604 OP (1) = relocation
>> 8;
610 OP (1) = relocation
>> 8;
614 RANGE (-32768, 65536);
616 OP (1) = relocation
>> 8;
619 case R_RL78_DIR16_REV
:
620 RANGE (-32768, 65536);
622 OP (0) = relocation
>> 8;
625 case R_RL78_DIR3U_PCREL
:
628 OP (0) |= relocation
& 0x07;
631 case R_RL78_DIR24S_PCREL
:
632 RANGE (-0x800000, 0x7fffff);
634 OP (1) = relocation
>> 8;
635 OP (2) = relocation
>> 16;
639 RANGE (-0x800000, 0x7fffff);
641 OP (1) = relocation
>> 8;
642 OP (2) = relocation
>> 16;
647 OP (1) = relocation
>> 8;
648 OP (2) = relocation
>> 16;
649 OP (3) = relocation
>> 24;
652 case R_RL78_DIR32_REV
:
654 OP (2) = relocation
>> 8;
655 OP (1) = relocation
>> 16;
656 OP (0) = relocation
>> 24;
659 /* Complex reloc handling: */
662 RL78_STACK_POP (relocation
);
664 OP (1) = relocation
>> 8;
665 OP (2) = relocation
>> 16;
666 OP (3) = relocation
>> 24;
669 case R_RL78_ABS32_REV
:
670 RL78_STACK_POP (relocation
);
672 OP (2) = relocation
>> 8;
673 OP (1) = relocation
>> 16;
674 OP (0) = relocation
>> 24;
677 case R_RL78_ABS24S_PCREL
:
679 RL78_STACK_POP (relocation
);
680 RANGE (-0x800000, 0x7fffff);
682 OP (1) = relocation
>> 8;
683 OP (2) = relocation
>> 16;
687 RL78_STACK_POP (relocation
);
688 RANGE (-32768, 65535);
690 OP (1) = relocation
>> 8;
693 case R_RL78_ABS16_REV
:
694 RL78_STACK_POP (relocation
);
695 RANGE (-32768, 65535);
697 OP (0) = relocation
>> 8;
700 case R_RL78_ABS16S_PCREL
:
702 RL78_STACK_POP (relocation
);
703 RANGE (-32768, 32767);
705 OP (1) = relocation
>> 8;
709 RL78_STACK_POP (relocation
);
712 OP (1) = relocation
>> 8;
716 RL78_STACK_POP (relocation
);
720 OP (1) = relocation
>> 8;
724 RL78_STACK_POP (relocation
);
728 OP (1) = relocation
>> 8;
732 RL78_STACK_POP (relocation
);
738 RL78_STACK_POP (relocation
);
744 RL78_STACK_POP (relocation
);
751 RL78_STACK_POP (relocation
);
757 case R_RL78_ABS8S_PCREL
:
759 RL78_STACK_POP (relocation
);
765 if (r_symndx
< symtab_hdr
->sh_info
)
766 RL78_STACK_PUSH (sec
->output_section
->vma
773 && (h
->root
.type
== bfd_link_hash_defined
774 || h
->root
.type
== bfd_link_hash_defweak
))
775 RL78_STACK_PUSH (h
->root
.u
.def
.value
776 + sec
->output_section
->vma
780 _bfd_error_handler (_("Warning: RL78_SYM reloc with an unknown symbol"));
788 RL78_STACK_POP (tmp
);
790 RL78_STACK_PUSH (tmp
);
798 RL78_STACK_POP (tmp2
);
799 RL78_STACK_POP (tmp1
);
801 RL78_STACK_PUSH (tmp1
);
809 RL78_STACK_POP (tmp2
);
810 RL78_STACK_POP (tmp1
);
812 RL78_STACK_PUSH (tmp2
);
820 RL78_STACK_POP (tmp2
);
821 RL78_STACK_POP (tmp1
);
823 RL78_STACK_PUSH (tmp1
);
831 RL78_STACK_POP (tmp2
);
832 RL78_STACK_POP (tmp1
);
834 RL78_STACK_PUSH (tmp1
);
842 RL78_STACK_POP (tmp2
);
843 RL78_STACK_POP (tmp1
);
845 RL78_STACK_PUSH (tmp1
);
853 RL78_STACK_POP (tmp2
);
854 RL78_STACK_POP (tmp1
);
856 RL78_STACK_PUSH (tmp1
);
860 case R_RL78_OPsctsize
:
861 RL78_STACK_PUSH (input_section
->size
);
864 case R_RL78_OPscttop
:
865 RL78_STACK_PUSH (input_section
->output_section
->vma
);
872 RL78_STACK_POP (tmp2
);
873 RL78_STACK_POP (tmp1
);
875 RL78_STACK_PUSH (tmp1
);
883 RL78_STACK_POP (tmp2
);
884 RL78_STACK_POP (tmp1
);
886 RL78_STACK_PUSH (tmp1
);
894 RL78_STACK_POP (tmp2
);
895 RL78_STACK_POP (tmp1
);
897 RL78_STACK_PUSH (tmp1
);
905 RL78_STACK_POP (tmp
);
907 RL78_STACK_PUSH (tmp
);
915 RL78_STACK_POP (tmp2
);
916 RL78_STACK_POP (tmp1
);
918 RL78_STACK_PUSH (tmp1
);
922 case R_RL78_OPromtop
:
923 RL78_STACK_PUSH (get_romstart (&r
, info
, input_bfd
, input_section
, rel
->r_offset
));
926 case R_RL78_OPramtop
:
927 RL78_STACK_PUSH (get_ramstart (&r
, info
, input_bfd
, input_section
, rel
->r_offset
));
931 r
= bfd_reloc_notsupported
;
935 if (r
!= bfd_reloc_ok
)
937 const char * msg
= NULL
;
941 case bfd_reloc_overflow
:
942 /* Catch the case of a missing function declaration
943 and emit a more helpful error message. */
944 if (r_type
== R_RL78_DIR24S_PCREL
)
945 msg
= _("%B(%A): error: call to undefined function '%s'");
947 r
= info
->callbacks
->reloc_overflow
948 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
949 input_bfd
, input_section
, rel
->r_offset
);
952 case bfd_reloc_undefined
:
953 r
= info
->callbacks
->undefined_symbol
954 (info
, name
, input_bfd
, input_section
, rel
->r_offset
,
958 case bfd_reloc_other
:
959 msg
= _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
962 case bfd_reloc_outofrange
:
963 msg
= _("%B(%A): internal error: out of range error");
966 case bfd_reloc_notsupported
:
967 msg
= _("%B(%A): internal error: unsupported relocation error");
970 case bfd_reloc_dangerous
:
971 msg
= _("%B(%A): internal error: dangerous relocation");
975 msg
= _("%B(%A): internal error: unknown error");
980 _bfd_error_handler (msg
, input_bfd
, input_section
, name
);
990 /* Function to set the ELF flag bits. */
993 rl78_elf_set_private_flags (bfd
* abfd
, flagword flags
)
995 elf_elfheader (abfd
)->e_flags
= flags
;
996 elf_flags_init (abfd
) = TRUE
;
1000 static bfd_boolean no_warn_mismatch
= FALSE
;
1002 void bfd_elf32_rl78_set_target_flags (bfd_boolean
);
1005 bfd_elf32_rl78_set_target_flags (bfd_boolean user_no_warn_mismatch
)
1007 no_warn_mismatch
= user_no_warn_mismatch
;
1010 /* Merge backend specific data from an object file to the output
1011 object file when linking. */
1014 rl78_elf_merge_private_bfd_data (bfd
* ibfd
, bfd
* obfd
)
1017 bfd_boolean error
= FALSE
;
1019 new_flags
= elf_elfheader (ibfd
)->e_flags
;
1021 if (!elf_flags_init (obfd
))
1023 /* First call, no flags set. */
1024 elf_flags_init (obfd
) = TRUE
;
1025 elf_elfheader (obfd
)->e_flags
= new_flags
;
1032 rl78_elf_print_private_bfd_data (bfd
* abfd
, void * ptr
)
1034 FILE * file
= (FILE *) ptr
;
1037 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
1039 /* Print normal ELF private data. */
1040 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
1042 flags
= elf_elfheader (abfd
)->e_flags
;
1043 fprintf (file
, _("private flags = 0x%lx:"), (long) flags
);
1049 /* Return the MACH for an e_flags value. */
1052 elf32_rl78_machine (bfd
* abfd
)
1054 if ((elf_elfheader (abfd
)->e_flags
& EF_RL78_CPU_MASK
) == EF_RL78_CPU_RL78
)
1055 return bfd_mach_rl78
;
1061 rl78_elf_object_p (bfd
* abfd
)
1063 bfd_default_set_arch_mach (abfd
, bfd_arch_rl78
,
1064 elf32_rl78_machine (abfd
));
1070 rl78_dump_symtab (bfd
* abfd
, void * internal_syms
, void * external_syms
)
1073 Elf_Internal_Sym
* isymbuf
;
1074 Elf_Internal_Sym
* isymend
;
1075 Elf_Internal_Sym
* isym
;
1076 Elf_Internal_Shdr
* symtab_hdr
;
1077 bfd_boolean free_internal
= FALSE
, free_external
= FALSE
;
1079 char * st_info_stb_str
;
1080 char * st_other_str
;
1081 char * st_shndx_str
;
1083 if (! internal_syms
)
1085 internal_syms
= bfd_malloc (1000);
1088 if (! external_syms
)
1090 external_syms
= bfd_malloc (1000);
1094 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1095 locsymcount
= symtab_hdr
->sh_size
/ get_elf_backend_data (abfd
)->s
->sizeof_sym
;
1097 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
1098 symtab_hdr
->sh_info
, 0,
1099 internal_syms
, external_syms
, NULL
);
1101 isymbuf
= internal_syms
;
1102 isymend
= isymbuf
+ locsymcount
;
1104 for (isym
= isymbuf
; isym
< isymend
; isym
++)
1106 switch (ELF_ST_TYPE (isym
->st_info
))
1108 case STT_FUNC
: st_info_str
= "STT_FUNC";
1109 case STT_SECTION
: st_info_str
= "STT_SECTION";
1110 case STT_FILE
: st_info_str
= "STT_FILE";
1111 case STT_OBJECT
: st_info_str
= "STT_OBJECT";
1112 case STT_TLS
: st_info_str
= "STT_TLS";
1113 default: st_info_str
= "";
1115 switch (ELF_ST_BIND (isym
->st_info
))
1117 case STB_LOCAL
: st_info_stb_str
= "STB_LOCAL";
1118 case STB_GLOBAL
: st_info_stb_str
= "STB_GLOBAL";
1119 default: st_info_stb_str
= "";
1121 switch (ELF_ST_VISIBILITY (isym
->st_other
))
1123 case STV_DEFAULT
: st_other_str
= "STV_DEFAULT";
1124 case STV_INTERNAL
: st_other_str
= "STV_INTERNAL";
1125 case STV_PROTECTED
: st_other_str
= "STV_PROTECTED";
1126 default: st_other_str
= "";
1128 switch (isym
->st_shndx
)
1130 case SHN_ABS
: st_shndx_str
= "SHN_ABS";
1131 case SHN_COMMON
: st_shndx_str
= "SHN_COMMON";
1132 case SHN_UNDEF
: st_shndx_str
= "SHN_UNDEF";
1133 default: st_shndx_str
= "";
1136 printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
1137 "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
1139 (unsigned long) isym
->st_value
,
1140 (unsigned long) isym
->st_size
,
1142 bfd_elf_string_from_elf_section (abfd
, symtab_hdr
->sh_link
,
1144 isym
->st_info
, st_info_str
, st_info_stb_str
,
1145 isym
->st_other
, st_other_str
,
1146 isym
->st_shndx
, st_shndx_str
);
1149 free (internal_syms
);
1151 free (external_syms
);
1155 rl78_get_reloc (long reloc
)
1157 if (0 <= reloc
&& reloc
< R_RL78_max
)
1158 return rl78_elf_howto_table
[reloc
].name
;
1164 /* support PLT for 16-bit references to 24-bit functions. */
1166 /* We support 16-bit pointers to code above 64k by generating a thunk
1167 below 64k containing a JMP instruction to the final address. */
1170 rl78_elf_check_relocs
1172 struct bfd_link_info
* info
,
1174 const Elf_Internal_Rela
* relocs
)
1176 Elf_Internal_Shdr
* symtab_hdr
;
1177 struct elf_link_hash_entry
** sym_hashes
;
1178 const Elf_Internal_Rela
* rel
;
1179 const Elf_Internal_Rela
* rel_end
;
1180 bfd_vma
*local_plt_offsets
;
1184 if (info
->relocatable
)
1187 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1188 sym_hashes
= elf_sym_hashes (abfd
);
1189 local_plt_offsets
= elf_local_got_offsets (abfd
);
1191 dynobj
= elf_hash_table(info
)->dynobj
;
1193 rel_end
= relocs
+ sec
->reloc_count
;
1194 for (rel
= relocs
; rel
< rel_end
; rel
++)
1196 struct elf_link_hash_entry
*h
;
1197 unsigned long r_symndx
;
1200 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1201 if (r_symndx
< symtab_hdr
->sh_info
)
1205 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1206 while (h
->root
.type
== bfd_link_hash_indirect
1207 || h
->root
.type
== bfd_link_hash_warning
)
1208 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1211 switch (ELF32_R_TYPE (rel
->r_info
))
1213 /* This relocation describes a 16-bit pointer to a function.
1214 We may need to allocate a thunk in low memory; reserve memory
1218 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
1221 splt
= bfd_get_section_by_name (dynobj
, ".plt");
1224 flagword flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
1225 | SEC_IN_MEMORY
| SEC_LINKER_CREATED
1226 | SEC_READONLY
| SEC_CODE
);
1227 splt
= bfd_make_section_with_flags (dynobj
, ".plt", flags
);
1229 || ! bfd_set_section_alignment (dynobj
, splt
, 1))
1235 offset
= &h
->plt
.offset
;
1238 if (local_plt_offsets
== NULL
)
1243 size
= symtab_hdr
->sh_info
* sizeof (bfd_vma
);
1244 local_plt_offsets
= (bfd_vma
*) bfd_alloc (abfd
, size
);
1245 if (local_plt_offsets
== NULL
)
1247 elf_local_got_offsets (abfd
) = local_plt_offsets
;
1249 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
1250 local_plt_offsets
[i
] = (bfd_vma
) -1;
1252 offset
= &local_plt_offsets
[r_symndx
];
1255 if (*offset
== (bfd_vma
) -1)
1257 *offset
= splt
->size
;
1267 /* This must exist if dynobj is ever set. */
1270 rl78_elf_finish_dynamic_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
1271 struct bfd_link_info
*info
)
1276 /* As an extra sanity check, verify that all plt entries have
1279 if ((dynobj
= elf_hash_table (info
)->dynobj
) != NULL
1280 && (splt
= bfd_get_section_by_name (dynobj
, ".plt")) != NULL
)
1282 bfd_byte
*contents
= splt
->contents
;
1283 unsigned int i
, size
= splt
->size
;
1284 for (i
= 0; i
< size
; i
+= 4)
1286 unsigned int x
= bfd_get_32 (dynobj
, contents
+ i
);
1287 BFD_ASSERT (x
!= 0);
1295 rl78_elf_always_size_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
1296 struct bfd_link_info
*info
)
1301 if (info
->relocatable
)
1304 dynobj
= elf_hash_table (info
)->dynobj
;
1308 splt
= bfd_get_section_by_name (dynobj
, ".plt");
1309 BFD_ASSERT (splt
!= NULL
);
1311 splt
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, splt
->size
);
1312 if (splt
->contents
== NULL
)
1320 /* Handle relaxing. */
1322 /* A subroutine of rl78_elf_relax_section. If the global symbol H
1323 is within the low 64k, remove any entry for it in the plt. */
1325 struct relax_plt_data
1332 rl78_relax_plt_check (struct elf_link_hash_entry
*h
,
1335 struct relax_plt_data
*data
= (struct relax_plt_data
*) xdata
;
1337 if (h
->plt
.offset
!= (bfd_vma
) -1)
1341 if (h
->root
.type
== bfd_link_hash_undefined
1342 || h
->root
.type
== bfd_link_hash_undefweak
)
1345 address
= (h
->root
.u
.def
.section
->output_section
->vma
1346 + h
->root
.u
.def
.section
->output_offset
1347 + h
->root
.u
.def
.value
);
1349 if (valid_16bit_address (address
))
1352 data
->splt
->size
-= 4;
1353 *data
->again
= TRUE
;
1360 /* A subroutine of rl78_elf_relax_section. If the global symbol H
1361 previously had a plt entry, give it a new entry offset. */
1364 rl78_relax_plt_realloc (struct elf_link_hash_entry
*h
,
1367 bfd_vma
*entry
= (bfd_vma
*) xdata
;
1369 if (h
->plt
.offset
!= (bfd_vma
) -1)
1371 h
->plt
.offset
= *entry
;
1379 rl78_elf_relax_plt_section (bfd
*dynobj
,
1381 struct bfd_link_info
*info
,
1384 struct relax_plt_data relax_plt_data
;
1387 /* Assume nothing changes. */
1390 if (info
->relocatable
)
1393 /* We only relax the .plt section at the moment. */
1394 if (dynobj
!= elf_hash_table (info
)->dynobj
1395 || strcmp (splt
->name
, ".plt") != 0)
1398 /* Quick check for an empty plt. */
1399 if (splt
->size
== 0)
1402 /* Map across all global symbols; see which ones happen to
1403 fall in the low 64k. */
1404 relax_plt_data
.splt
= splt
;
1405 relax_plt_data
.again
= again
;
1406 elf_link_hash_traverse (elf_hash_table (info
), rl78_relax_plt_check
,
1409 /* Likewise for local symbols, though that's somewhat less convenient
1410 as we have to walk the list of input bfds and swap in symbol data. */
1411 for (ibfd
= info
->input_bfds
; ibfd
; ibfd
= ibfd
->link_next
)
1413 bfd_vma
*local_plt_offsets
= elf_local_got_offsets (ibfd
);
1414 Elf_Internal_Shdr
*symtab_hdr
;
1415 Elf_Internal_Sym
*isymbuf
= NULL
;
1418 if (! local_plt_offsets
)
1421 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
1422 if (symtab_hdr
->sh_info
!= 0)
1424 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1425 if (isymbuf
== NULL
)
1426 isymbuf
= bfd_elf_get_elf_syms (ibfd
, symtab_hdr
,
1427 symtab_hdr
->sh_info
, 0,
1429 if (isymbuf
== NULL
)
1433 for (idx
= 0; idx
< symtab_hdr
->sh_info
; ++idx
)
1435 Elf_Internal_Sym
*isym
;
1439 if (local_plt_offsets
[idx
] == (bfd_vma
) -1)
1442 isym
= &isymbuf
[idx
];
1443 if (isym
->st_shndx
== SHN_UNDEF
)
1445 else if (isym
->st_shndx
== SHN_ABS
)
1446 tsec
= bfd_abs_section_ptr
;
1447 else if (isym
->st_shndx
== SHN_COMMON
)
1448 tsec
= bfd_com_section_ptr
;
1450 tsec
= bfd_section_from_elf_index (ibfd
, isym
->st_shndx
);
1452 address
= (tsec
->output_section
->vma
1453 + tsec
->output_offset
1455 if (valid_16bit_address (address
))
1457 local_plt_offsets
[idx
] = -1;
1464 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1466 if (! info
->keep_memory
)
1470 /* Cache the symbols for elf_link_input_bfd. */
1471 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1476 /* If we changed anything, walk the symbols again to reallocate
1477 .plt entry addresses. */
1478 if (*again
&& splt
->size
> 0)
1482 elf_link_hash_traverse (elf_hash_table (info
),
1483 rl78_relax_plt_realloc
, &entry
);
1485 for (ibfd
= info
->input_bfds
; ibfd
; ibfd
= ibfd
->link_next
)
1487 bfd_vma
*local_plt_offsets
= elf_local_got_offsets (ibfd
);
1488 unsigned int nlocals
= elf_tdata (ibfd
)->symtab_hdr
.sh_info
;
1491 if (! local_plt_offsets
)
1494 for (idx
= 0; idx
< nlocals
; ++idx
)
1495 if (local_plt_offsets
[idx
] != (bfd_vma
) -1)
1497 local_plt_offsets
[idx
] = entry
;
1507 rl78_elf_relax_section
1510 struct bfd_link_info
* link_info
,
1511 bfd_boolean
* again
)
1513 if (abfd
== elf_hash_table (link_info
)->dynobj
1514 && strcmp (sec
->name
, ".plt") == 0)
1515 return rl78_elf_relax_plt_section (abfd
, sec
, link_info
, again
);
1517 /* Assume nothing changes. */
1524 #define ELF_ARCH bfd_arch_rl78
1525 #define ELF_MACHINE_CODE EM_RL78
1526 #define ELF_MAXPAGESIZE 0x1000
1528 #define TARGET_LITTLE_SYM bfd_elf32_rl78_vec
1529 #define TARGET_LITTLE_NAME "elf32-rl78"
1531 #define elf_info_to_howto_rel NULL
1532 #define elf_info_to_howto rl78_info_to_howto_rela
1533 #define elf_backend_object_p rl78_elf_object_p
1534 #define elf_backend_relocate_section rl78_elf_relocate_section
1535 #define elf_symbol_leading_char ('_')
1536 #define elf_backend_can_gc_sections 1
1538 #define bfd_elf32_bfd_reloc_type_lookup rl78_reloc_type_lookup
1539 #define bfd_elf32_bfd_reloc_name_lookup rl78_reloc_name_lookup
1540 #define bfd_elf32_bfd_set_private_flags rl78_elf_set_private_flags
1541 #define bfd_elf32_bfd_merge_private_bfd_data rl78_elf_merge_private_bfd_data
1542 #define bfd_elf32_bfd_print_private_bfd_data rl78_elf_print_private_bfd_data
1544 #define bfd_elf32_bfd_relax_section rl78_elf_relax_section
1545 #define elf_backend_check_relocs rl78_elf_check_relocs
1546 #define elf_backend_always_size_sections \
1547 rl78_elf_always_size_sections
1548 #define elf_backend_finish_dynamic_sections \
1549 rl78_elf_finish_dynamic_sections
1551 #include "elf32-target.h"