version 1.5, 2018/04/14 15:49:38 |
version 1.6, 2020/04/03 17:51:04 |
|
|
/* Motorola 68HC12-specific support for 32-bit ELF |
/* Motorola 68HC12-specific support for 32-bit ELF |
Copyright (C) 1999-2016 Free Software Foundation, Inc. |
Copyright (C) 1999-2018 Free Software Foundation, Inc. |
Contributed by Stephane Carrez (stcarrez@nerim.fr) |
Contributed by Stephane Carrez (stcarrez@nerim.fr) |
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com)) |
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com)) |
|
|
|
|
/* Relocation functions. */ |
/* Relocation functions. */ |
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup |
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup |
(bfd *, bfd_reloc_code_real_type); |
(bfd *, bfd_reloc_code_real_type); |
static void m68hc11_info_to_howto_rel |
static bfd_boolean m68hc11_info_to_howto_rel |
(bfd *, arelent *, Elf_Internal_Rela *); |
(bfd *, arelent *, Elf_Internal_Rela *); |
|
|
/* Trampoline generation. */ |
/* Trampoline generation. */ |
Line 62 static void m68hc11_info_to_howto_rel |
|
Line 62 static void m68hc11_info_to_howto_rel |
|
|
|
Banked |
Banked |
Address Space |
Address Space |
| | Page n |
| | Page n |
+---------------+ 0x1010000 |
+---------------+ 0x1010000 |
| | |
| | |
| jsr _foo | |
| jsr _foo | |
| .. | Page 3 |
| .. | Page 3 |
| _foo: | |
| _foo: | |
+---------------+ 0x100C000 |
+---------------+ 0x100C000 |
| | |
| | |
| call _bar | |
| call _bar | |
| .. | Page 2 |
| .. | Page 2 |
| _bar: | |
| _bar: | |
+---------------+ 0x1008000 |
+---------------+ 0x1008000 |
/------>| | |
/------>| | |
| | call _foo | Page 1 |
| | call _foo | Page 1 |
| | | |
| | | |
| +---------------+ 0x1004000 |
| +---------------+ 0x1004000 |
Physical | | | |
Physical | | | |
Address Space | | | Page 0 |
Address Space | | | Page 0 |
| | | |
| | | |
+-----------+ 0x00FFFF | +---------------+ 0x1000000 |
+-----------+ 0x00FFFF | +---------------+ 0x1000000 |
| | | |
| | | |
| call _foo | | |
| call _foo | | |
| | | |
| | | |
+-----------+ 0x00BFFF -+---/ |
+-----------+ 0x00BFFF -+---/ |
| | | |
| | | |
| | | |
| | | |
| | 16K | |
| | 16K | |
| | | |
| | | |
Line 177 static reloc_howto_type elf_m68hc11_howt |
|
Line 177 static reloc_howto_type elf_m68hc11_howt |
|
FALSE, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
0x00ff, /* src_mask */ |
0x00ff, /* src_mask */ |
0x00ff, /* dst_mask */ |
0x00ff, /* dst_mask */ |
TRUE), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
|
|
/* A 16 bit absolute relocation */ |
/* A 16 bit absolute relocation */ |
HOWTO (R_M68HC11_16, /* type */ |
HOWTO (R_M68HC11_16, /* type */ |
Line 238 static reloc_howto_type elf_m68hc11_howt |
|
Line 238 static reloc_howto_type elf_m68hc11_howt |
|
FALSE, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
0xffff, /* src_mask */ |
0xffff, /* src_mask */ |
0xffff, /* dst_mask */ |
0xffff, /* dst_mask */ |
TRUE), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
|
|
/* GNU extension to record C++ vtable hierarchy */ |
/* GNU extension to record C++ vtable hierarchy */ |
HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */ |
HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */ |
Line 271 static reloc_howto_type elf_m68hc11_howt |
|
Line 271 static reloc_howto_type elf_m68hc11_howt |
|
FALSE), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
|
|
/* A 24 bit relocation */ |
/* A 24 bit relocation */ |
HOWTO (R_M68HC11_24, /* type */ |
HOWTO (R_M68HC11_24, /* type */ |
0, /* rightshift */ |
0, /* rightshift */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
24, /* bitsize */ |
24, /* bitsize */ |
Line 286 static reloc_howto_type elf_m68hc11_howt |
|
Line 286 static reloc_howto_type elf_m68hc11_howt |
|
FALSE), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
|
|
/* A 16-bit low relocation */ |
/* A 16-bit low relocation */ |
HOWTO (R_M68HC11_LO16, /* type */ |
HOWTO (R_M68HC11_LO16, /* type */ |
0, /* rightshift */ |
0, /* rightshift */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
16, /* bitsize */ |
16, /* bitsize */ |
Line 301 static reloc_howto_type elf_m68hc11_howt |
|
Line 301 static reloc_howto_type elf_m68hc11_howt |
|
FALSE), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
|
|
/* A page relocation */ |
/* A page relocation */ |
HOWTO (R_M68HC11_PAGE, /* type */ |
HOWTO (R_M68HC11_PAGE, /* type */ |
0, /* rightshift */ |
0, /* rightshift */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
8, /* bitsize */ |
8, /* bitsize */ |
Line 328 static reloc_howto_type elf_m68hc11_howt |
|
Line 328 static reloc_howto_type elf_m68hc11_howt |
|
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
"R_M68HC12_16B", /* name */ |
"R_M68HC12_16B", /* name */ |
FALSE, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
0xffff, /* src_mask */ |
0xffff, /* src_mask */ |
0xffff, /* dst_mask */ |
0xffff, /* dst_mask */ |
FALSE), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
|
|
/* A 9 bit PC-rel relocation. */ |
/* A 9 bit PC-rel relocation. */ |
Line 345 static reloc_howto_type elf_m68hc11_howt |
|
Line 345 static reloc_howto_type elf_m68hc11_howt |
|
TRUE, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
0xfe00, /* src_mask */ |
0xfe00, /* src_mask */ |
0x01ff, /* dst_mask */ |
0x01ff, /* dst_mask */ |
TRUE), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
|
|
/* A 10 bit PC-rel relocation. */ |
/* A 10 bit PC-rel relocation. */ |
HOWTO (R_M68HC12_PCREL_10, /* type */ |
HOWTO (R_M68HC12_PCREL_10, /* type */ |
Line 360 static reloc_howto_type elf_m68hc11_howt |
|
Line 360 static reloc_howto_type elf_m68hc11_howt |
|
TRUE, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
0xfc00, /* src_mask */ |
0xfc00, /* src_mask */ |
0x03ff, /* dst_mask */ |
0x03ff, /* dst_mask */ |
TRUE), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
|
|
/* A 8 bit absolute relocation (upper address). */ |
/* A 8 bit absolute relocation (upper address). */ |
HOWTO (R_M68HC12_HI8XG, /* type */ |
HOWTO (R_M68HC12_HI8XG, /* type */ |
Line 405 static reloc_howto_type elf_m68hc11_howt |
|
Line 405 static reloc_howto_type elf_m68hc11_howt |
|
TRUE, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
0, /* src_mask */ |
0, /* src_mask */ |
0, /* dst_mask */ |
0, /* dst_mask */ |
TRUE), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
|
|
/* Mark beginning of Gcc relaxation group instruction. */ |
/* Mark beginning of Gcc relaxation group instruction. */ |
HOWTO (R_M68HC11_RL_GROUP, /* type */ |
HOWTO (R_M68HC11_RL_GROUP, /* type */ |
Line 420 static reloc_howto_type elf_m68hc11_howt |
|
Line 420 static reloc_howto_type elf_m68hc11_howt |
|
TRUE, /* partial_inplace */ |
TRUE, /* partial_inplace */ |
0, /* src_mask */ |
0, /* src_mask */ |
0, /* dst_mask */ |
0, /* dst_mask */ |
TRUE), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
}; |
}; |
|
|
/* Map BFD reloc types to M68HC11 ELF reloc types. */ |
/* Map BFD reloc types to M68HC11 ELF reloc types. */ |
Line 463 static const struct m68hc11_reloc_map m6 |
|
Line 463 static const struct m68hc11_reloc_map m6 |
|
|
|
static reloc_howto_type * |
static reloc_howto_type * |
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
bfd_reloc_code_real_type code) |
bfd_reloc_code_real_type code) |
{ |
{ |
unsigned int i; |
unsigned int i; |
|
|
Line 497 bfd_elf32_bfd_reloc_name_lookup (bfd *ab |
|
Line 497 bfd_elf32_bfd_reloc_name_lookup (bfd *ab |
|
|
|
/* Set the howto pointer for an M68HC11 ELF reloc. */ |
/* Set the howto pointer for an M68HC11 ELF reloc. */ |
|
|
static void |
static bfd_boolean |
m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, |
m68hc11_info_to_howto_rel (bfd *abfd, |
arelent *cache_ptr, Elf_Internal_Rela *dst) |
arelent *cache_ptr, Elf_Internal_Rela *dst) |
{ |
{ |
unsigned int r_type; |
unsigned int r_type; |
|
|
r_type = ELF32_R_TYPE (dst->r_info); |
r_type = ELF32_R_TYPE (dst->r_info); |
if (r_type >= (unsigned int) R_M68HC11_max) |
if (r_type >= (unsigned int) R_M68HC11_max) |
{ |
{ |
_bfd_error_handler (_("%B: invalid M68HC12 reloc number: %d"), abfd, r_type); |
/* xgettext:c-format */ |
r_type = 0; |
_bfd_error_handler (_("%pB: unsupported relocation type %#x"), |
|
abfd, r_type); |
|
bfd_set_error (bfd_error_bad_value); |
|
return FALSE; |
} |
} |
cache_ptr->howto = &elf_m68hc11_howto_table[r_type]; |
cache_ptr->howto = &elf_m68hc11_howto_table[r_type]; |
|
return TRUE; |
} |
} |
|
|
|
|
Line 549 m68hc12_elf_build_one_stub (struct bfd_h |
|
Line 553 m68hc12_elf_build_one_stub (struct bfd_h |
|
|
|
*/ |
*/ |
sym_value = (stub_entry->target_value |
sym_value = (stub_entry->target_value |
+ stub_entry->target_section->output_offset |
+ stub_entry->target_section->output_offset |
+ stub_entry->target_section->output_section->vma); |
+ stub_entry->target_section->output_section->vma); |
phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value); |
phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value); |
phys_page = m68hc11_phys_page (&htab->pinfo, sym_value); |
phys_page = m68hc11_phys_page (&htab->pinfo, sym_value); |
|
|
Line 572 m68hc12_elf_build_one_stub (struct bfd_h |
|
Line 576 m68hc12_elf_build_one_stub (struct bfd_h |
|
|
|
static bfd_boolean |
static bfd_boolean |
m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry, |
m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry, |
void *in_arg ATTRIBUTE_UNUSED) |
void *in_arg ATTRIBUTE_UNUSED) |
{ |
{ |
struct elf32_m68hc11_stub_hash_entry *stub_entry; |
struct elf32_m68hc11_stub_hash_entry *stub_entry; |
|
|
Line 615 m68hc12_elf_set_mach_from_flags (bfd *ab |
|
Line 619 m68hc12_elf_set_mach_from_flags (bfd *ab |
|
break; |
break; |
case EF_M68HC11_GENERIC: |
case EF_M68HC11_GENERIC: |
bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, |
bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, |
bfd_mach_m6812_default); |
bfd_mach_m6812_default); |
break; |
break; |
default: |
default: |
return FALSE; |
return FALSE; |
Line 634 static const struct bfd_elf_special_sect |
|
Line 638 static const struct bfd_elf_special_sect |
|
{ STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, |
{ STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, |
{ STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, |
{ STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, |
{ STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC }, |
{ STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC }, |
{ NULL, 0, 0, 0, 0 } |
{ NULL, 0, 0, 0, 0 } |
}; |
}; |
|
|
#define ELF_ARCH bfd_arch_m68hc12 |
#define ELF_ARCH bfd_arch_m68hc12 |
Line 642 static const struct bfd_elf_special_sect |
|
Line 646 static const struct bfd_elf_special_sect |
|
#define ELF_MACHINE_CODE EM_68HC12 |
#define ELF_MACHINE_CODE EM_68HC12 |
#define ELF_MAXPAGESIZE 0x1000 |
#define ELF_MAXPAGESIZE 0x1000 |
|
|
#define TARGET_BIG_SYM m68hc12_elf32_vec |
#define TARGET_BIG_SYM m68hc12_elf32_vec |
#define TARGET_BIG_NAME "elf32-m68hc12" |
#define TARGET_BIG_NAME "elf32-m68hc12" |
|
|
#define elf_info_to_howto 0 |
#define elf_info_to_howto NULL |
#define elf_info_to_howto_rel m68hc11_info_to_howto_rel |
#define elf_info_to_howto_rel m68hc11_info_to_howto_rel |
#define elf_backend_check_relocs elf32_m68hc11_check_relocs |
#define elf_backend_check_relocs elf32_m68hc11_check_relocs |
#define elf_backend_relocate_section elf32_m68hc11_relocate_section |
#define elf_backend_relocate_section elf32_m68hc11_relocate_section |
Line 658 static const struct bfd_elf_special_sect |
|
Line 662 static const struct bfd_elf_special_sect |
|
#define elf_backend_merge_symbol_attribute elf32_m68hc11_merge_symbol_attribute |
#define elf_backend_merge_symbol_attribute elf32_m68hc11_merge_symbol_attribute |
|
|
#define bfd_elf32_bfd_link_hash_table_create \ |
#define bfd_elf32_bfd_link_hash_table_create \ |
m68hc12_elf_bfd_link_hash_table_create |
m68hc12_elf_bfd_link_hash_table_create |
#define bfd_elf32_bfd_merge_private_bfd_data \ |
#define bfd_elf32_bfd_merge_private_bfd_data \ |
_bfd_m68hc11_elf_merge_private_bfd_data |
_bfd_m68hc11_elf_merge_private_bfd_data |
#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags |
#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags |