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
)
1018 bfd_boolean error
= FALSE
;
1020 new_flags
= elf_elfheader (ibfd
)->e_flags
;
1021 old_flags
= elf_elfheader (obfd
)->e_flags
;
1023 if (!elf_flags_init (obfd
))
1025 /* First call, no flags set. */
1026 elf_flags_init (obfd
) = TRUE
;
1027 elf_elfheader (obfd
)->e_flags
= new_flags
;
1034 rl78_elf_print_private_bfd_data (bfd
* abfd
, void * ptr
)
1036 FILE * file
= (FILE *) ptr
;
1039 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
1041 /* Print normal ELF private data. */
1042 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
1044 flags
= elf_elfheader (abfd
)->e_flags
;
1045 fprintf (file
, _("private flags = 0x%lx:"), (long) flags
);
1051 /* Return the MACH for an e_flags value. */
1054 elf32_rl78_machine (bfd
* abfd
)
1056 if ((elf_elfheader (abfd
)->e_flags
& EF_RL78_CPU_MASK
) == EF_RL78_CPU_RL78
)
1057 return bfd_mach_rl78
;
1063 rl78_elf_object_p (bfd
* abfd
)
1065 bfd_default_set_arch_mach (abfd
, bfd_arch_rl78
,
1066 elf32_rl78_machine (abfd
));
1072 rl78_dump_symtab (bfd
* abfd
, void * internal_syms
, void * external_syms
)
1075 Elf_Internal_Sym
* isymbuf
;
1076 Elf_Internal_Sym
* isymend
;
1077 Elf_Internal_Sym
* isym
;
1078 Elf_Internal_Shdr
* symtab_hdr
;
1079 bfd_boolean free_internal
= FALSE
, free_external
= FALSE
;
1081 char * st_info_stb_str
;
1082 char * st_other_str
;
1083 char * st_shndx_str
;
1085 if (! internal_syms
)
1087 internal_syms
= bfd_malloc (1000);
1090 if (! external_syms
)
1092 external_syms
= bfd_malloc (1000);
1096 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1097 locsymcount
= symtab_hdr
->sh_size
/ get_elf_backend_data (abfd
)->s
->sizeof_sym
;
1099 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
1100 symtab_hdr
->sh_info
, 0,
1101 internal_syms
, external_syms
, NULL
);
1103 isymbuf
= internal_syms
;
1104 isymend
= isymbuf
+ locsymcount
;
1106 for (isym
= isymbuf
; isym
< isymend
; isym
++)
1108 switch (ELF_ST_TYPE (isym
->st_info
))
1110 case STT_FUNC
: st_info_str
= "STT_FUNC";
1111 case STT_SECTION
: st_info_str
= "STT_SECTION";
1112 case STT_FILE
: st_info_str
= "STT_FILE";
1113 case STT_OBJECT
: st_info_str
= "STT_OBJECT";
1114 case STT_TLS
: st_info_str
= "STT_TLS";
1115 default: st_info_str
= "";
1117 switch (ELF_ST_BIND (isym
->st_info
))
1119 case STB_LOCAL
: st_info_stb_str
= "STB_LOCAL";
1120 case STB_GLOBAL
: st_info_stb_str
= "STB_GLOBAL";
1121 default: st_info_stb_str
= "";
1123 switch (ELF_ST_VISIBILITY (isym
->st_other
))
1125 case STV_DEFAULT
: st_other_str
= "STV_DEFAULT";
1126 case STV_INTERNAL
: st_other_str
= "STV_INTERNAL";
1127 case STV_PROTECTED
: st_other_str
= "STV_PROTECTED";
1128 default: st_other_str
= "";
1130 switch (isym
->st_shndx
)
1132 case SHN_ABS
: st_shndx_str
= "SHN_ABS";
1133 case SHN_COMMON
: st_shndx_str
= "SHN_COMMON";
1134 case SHN_UNDEF
: st_shndx_str
= "SHN_UNDEF";
1135 default: st_shndx_str
= "";
1138 printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
1139 "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
1141 (unsigned long) isym
->st_value
,
1142 (unsigned long) isym
->st_size
,
1144 bfd_elf_string_from_elf_section (abfd
, symtab_hdr
->sh_link
,
1146 isym
->st_info
, st_info_str
, st_info_stb_str
,
1147 isym
->st_other
, st_other_str
,
1148 isym
->st_shndx
, st_shndx_str
);
1151 free (internal_syms
);
1153 free (external_syms
);
1157 rl78_get_reloc (long reloc
)
1159 if (0 <= reloc
&& reloc
< R_RL78_max
)
1160 return rl78_elf_howto_table
[reloc
].name
;
1166 /* support PLT for 16-bit references to 24-bit functions. */
1168 /* We support 16-bit pointers to code above 64k by generating a thunk
1169 below 64k containing a JMP instruction to the final address. */
1172 rl78_elf_check_relocs
1174 struct bfd_link_info
* info
,
1176 const Elf_Internal_Rela
* relocs
)
1178 Elf_Internal_Shdr
* symtab_hdr
;
1179 struct elf_link_hash_entry
** sym_hashes
;
1180 const Elf_Internal_Rela
* rel
;
1181 const Elf_Internal_Rela
* rel_end
;
1182 bfd_vma
*local_plt_offsets
;
1186 if (info
->relocatable
)
1189 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1190 sym_hashes
= elf_sym_hashes (abfd
);
1191 local_plt_offsets
= elf_local_got_offsets (abfd
);
1193 dynobj
= elf_hash_table(info
)->dynobj
;
1195 rel_end
= relocs
+ sec
->reloc_count
;
1196 for (rel
= relocs
; rel
< rel_end
; rel
++)
1198 struct elf_link_hash_entry
*h
;
1199 unsigned long r_symndx
;
1202 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1203 if (r_symndx
< symtab_hdr
->sh_info
)
1207 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1208 while (h
->root
.type
== bfd_link_hash_indirect
1209 || h
->root
.type
== bfd_link_hash_warning
)
1210 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1213 switch (ELF32_R_TYPE (rel
->r_info
))
1215 /* This relocation describes a 16-bit pointer to a function.
1216 We may need to allocate a thunk in low memory; reserve memory
1220 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
1223 splt
= bfd_get_section_by_name (dynobj
, ".plt");
1226 flagword flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
1227 | SEC_IN_MEMORY
| SEC_LINKER_CREATED
1228 | SEC_READONLY
| SEC_CODE
);
1229 splt
= bfd_make_section_with_flags (dynobj
, ".plt", flags
);
1231 || ! bfd_set_section_alignment (dynobj
, splt
, 1))
1237 offset
= &h
->plt
.offset
;
1240 if (local_plt_offsets
== NULL
)
1245 size
= symtab_hdr
->sh_info
* sizeof (bfd_vma
);
1246 local_plt_offsets
= (bfd_vma
*) bfd_alloc (abfd
, size
);
1247 if (local_plt_offsets
== NULL
)
1249 elf_local_got_offsets (abfd
) = local_plt_offsets
;
1251 for (i
= 0; i
< symtab_hdr
->sh_info
; i
++)
1252 local_plt_offsets
[i
] = (bfd_vma
) -1;
1254 offset
= &local_plt_offsets
[r_symndx
];
1257 if (*offset
== (bfd_vma
) -1)
1259 *offset
= splt
->size
;
1269 /* This must exist if dynobj is ever set. */
1272 rl78_elf_finish_dynamic_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
1273 struct bfd_link_info
*info
)
1278 /* As an extra sanity check, verify that all plt entries have
1281 if ((dynobj
= elf_hash_table (info
)->dynobj
) != NULL
1282 && (splt
= bfd_get_section_by_name (dynobj
, ".plt")) != NULL
)
1284 bfd_byte
*contents
= splt
->contents
;
1285 unsigned int i
, size
= splt
->size
;
1286 for (i
= 0; i
< size
; i
+= 4)
1288 unsigned int x
= bfd_get_32 (dynobj
, contents
+ i
);
1289 BFD_ASSERT (x
!= 0);
1297 rl78_elf_always_size_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
1298 struct bfd_link_info
*info
)
1303 if (info
->relocatable
)
1306 dynobj
= elf_hash_table (info
)->dynobj
;
1310 splt
= bfd_get_section_by_name (dynobj
, ".plt");
1311 BFD_ASSERT (splt
!= NULL
);
1313 splt
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, splt
->size
);
1314 if (splt
->contents
== NULL
)
1322 /* Handle relaxing. */
1324 /* A subroutine of rl78_elf_relax_section. If the global symbol H
1325 is within the low 64k, remove any entry for it in the plt. */
1327 struct relax_plt_data
1334 rl78_relax_plt_check (struct elf_link_hash_entry
*h
,
1337 struct relax_plt_data
*data
= (struct relax_plt_data
*) xdata
;
1339 if (h
->plt
.offset
!= (bfd_vma
) -1)
1343 if (h
->root
.type
== bfd_link_hash_undefined
1344 || h
->root
.type
== bfd_link_hash_undefweak
)
1347 address
= (h
->root
.u
.def
.section
->output_section
->vma
1348 + h
->root
.u
.def
.section
->output_offset
1349 + h
->root
.u
.def
.value
);
1351 if (valid_16bit_address (address
))
1354 data
->splt
->size
-= 4;
1355 *data
->again
= TRUE
;
1362 /* A subroutine of rl78_elf_relax_section. If the global symbol H
1363 previously had a plt entry, give it a new entry offset. */
1366 rl78_relax_plt_realloc (struct elf_link_hash_entry
*h
,
1369 bfd_vma
*entry
= (bfd_vma
*) xdata
;
1371 if (h
->plt
.offset
!= (bfd_vma
) -1)
1373 h
->plt
.offset
= *entry
;
1381 rl78_elf_relax_plt_section (bfd
*dynobj
,
1383 struct bfd_link_info
*info
,
1386 struct relax_plt_data relax_plt_data
;
1389 /* Assume nothing changes. */
1392 if (info
->relocatable
)
1395 /* We only relax the .plt section at the moment. */
1396 if (dynobj
!= elf_hash_table (info
)->dynobj
1397 || strcmp (splt
->name
, ".plt") != 0)
1400 /* Quick check for an empty plt. */
1401 if (splt
->size
== 0)
1404 /* Map across all global symbols; see which ones happen to
1405 fall in the low 64k. */
1406 relax_plt_data
.splt
= splt
;
1407 relax_plt_data
.again
= again
;
1408 elf_link_hash_traverse (elf_hash_table (info
), rl78_relax_plt_check
,
1411 /* Likewise for local symbols, though that's somewhat less convenient
1412 as we have to walk the list of input bfds and swap in symbol data. */
1413 for (ibfd
= info
->input_bfds
; ibfd
; ibfd
= ibfd
->link_next
)
1415 bfd_vma
*local_plt_offsets
= elf_local_got_offsets (ibfd
);
1416 Elf_Internal_Shdr
*symtab_hdr
;
1417 Elf_Internal_Sym
*isymbuf
= NULL
;
1420 if (! local_plt_offsets
)
1423 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
1424 if (symtab_hdr
->sh_info
!= 0)
1426 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1427 if (isymbuf
== NULL
)
1428 isymbuf
= bfd_elf_get_elf_syms (ibfd
, symtab_hdr
,
1429 symtab_hdr
->sh_info
, 0,
1431 if (isymbuf
== NULL
)
1435 for (idx
= 0; idx
< symtab_hdr
->sh_info
; ++idx
)
1437 Elf_Internal_Sym
*isym
;
1441 if (local_plt_offsets
[idx
] == (bfd_vma
) -1)
1444 isym
= &isymbuf
[idx
];
1445 if (isym
->st_shndx
== SHN_UNDEF
)
1447 else if (isym
->st_shndx
== SHN_ABS
)
1448 tsec
= bfd_abs_section_ptr
;
1449 else if (isym
->st_shndx
== SHN_COMMON
)
1450 tsec
= bfd_com_section_ptr
;
1452 tsec
= bfd_section_from_elf_index (ibfd
, isym
->st_shndx
);
1454 address
= (tsec
->output_section
->vma
1455 + tsec
->output_offset
1457 if (valid_16bit_address (address
))
1459 local_plt_offsets
[idx
] = -1;
1466 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1468 if (! info
->keep_memory
)
1472 /* Cache the symbols for elf_link_input_bfd. */
1473 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1478 /* If we changed anything, walk the symbols again to reallocate
1479 .plt entry addresses. */
1480 if (*again
&& splt
->size
> 0)
1484 elf_link_hash_traverse (elf_hash_table (info
),
1485 rl78_relax_plt_realloc
, &entry
);
1487 for (ibfd
= info
->input_bfds
; ibfd
; ibfd
= ibfd
->link_next
)
1489 bfd_vma
*local_plt_offsets
= elf_local_got_offsets (ibfd
);
1490 unsigned int nlocals
= elf_tdata (ibfd
)->symtab_hdr
.sh_info
;
1493 if (! local_plt_offsets
)
1496 for (idx
= 0; idx
< nlocals
; ++idx
)
1497 if (local_plt_offsets
[idx
] != (bfd_vma
) -1)
1499 local_plt_offsets
[idx
] = entry
;
1509 rl78_elf_relax_section
1512 struct bfd_link_info
* link_info
,
1513 bfd_boolean
* again
)
1515 if (abfd
== elf_hash_table (link_info
)->dynobj
1516 && strcmp (sec
->name
, ".plt") == 0)
1517 return rl78_elf_relax_plt_section (abfd
, sec
, link_info
, again
);
1519 /* Assume nothing changes. */
1526 #define ELF_ARCH bfd_arch_rl78
1527 #define ELF_MACHINE_CODE EM_RL78
1528 #define ELF_MAXPAGESIZE 0x1000
1530 #define TARGET_LITTLE_SYM bfd_elf32_rl78_vec
1531 #define TARGET_LITTLE_NAME "elf32-rl78"
1533 #define elf_info_to_howto_rel NULL
1534 #define elf_info_to_howto rl78_info_to_howto_rela
1535 #define elf_backend_object_p rl78_elf_object_p
1536 #define elf_backend_relocate_section rl78_elf_relocate_section
1537 #define elf_symbol_leading_char ('_')
1538 #define elf_backend_can_gc_sections 1
1540 #define bfd_elf32_bfd_reloc_type_lookup rl78_reloc_type_lookup
1541 #define bfd_elf32_bfd_reloc_name_lookup rl78_reloc_name_lookup
1542 #define bfd_elf32_bfd_set_private_flags rl78_elf_set_private_flags
1543 #define bfd_elf32_bfd_merge_private_bfd_data rl78_elf_merge_private_bfd_data
1544 #define bfd_elf32_bfd_print_private_bfd_data rl78_elf_print_private_bfd_data
1546 #define bfd_elf32_bfd_relax_section rl78_elf_relax_section
1547 #define elf_backend_check_relocs rl78_elf_check_relocs
1548 #define elf_backend_always_size_sections \
1549 rl78_elf_always_size_sections
1550 #define elf_backend_finish_dynamic_sections \
1551 rl78_elf_finish_dynamic_sections
1553 #include "elf32-target.h"