diff options
Diffstat (limited to 'bfd/elf64-sh64.c')
-rw-r--r-- | bfd/elf64-sh64.c | 84 |
1 files changed, 73 insertions, 11 deletions
diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index 4fb695f1011..da02505d5c5 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1588,6 +1588,35 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, continue; } + else if (! howto->partial_inplace) + { + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + relocation |= ((sym->st_other & STO_SH5_ISA32) != 0); + } + else if ((sec->flags & SEC_MERGE) + && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + asection *msec; + + if (howto->rightshift || howto->src_mask != 0xffffffff) + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, howto->name); + return false; + } + + addend = bfd_get_32 (input_bfd, contents + rel->r_offset); + msec = sec; + addend = + _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) + - relocation; + addend += msec->output_section->vma + msec->output_offset; + bfd_put_32 (input_bfd, addend, contents + rel->r_offset); + addend = 0; + } } else { @@ -2915,16 +2944,19 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) if (h == NULL) { /* No previous datalabel symbol. Make one. */ + struct bfd_link_hash_entry *bh = NULL; + struct elf_backend_data *bed = get_elf_backend_data (abfd); + if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name, flags, *secp, *valp, *namep, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h)) + bed->collect, &bh)) { free (dl_name); return false; } + h = (struct elf_link_hash_entry *) bh; h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; h->type = STT_DATALABEL; } @@ -3108,7 +3140,7 @@ static const bfd_byte elf_sh64_pic_plt_entry_be[PLT_ENTRY_SIZE] = 0x6f, 0xf0, 0xff, 0xf0, /* nop */ 0x6f, 0xf0, 0xff, 0xf0, /* nop */ 0xce, 0x00, 0x01, 0x10, /* movi -GOT_BIAS, r17 */ - 0x00, 0xcb, 0x45, 0x10, /* sub r12, r17, r17 */ + 0x00, 0xc9, 0x45, 0x10, /* add r12, r17, r17 */ 0x8d, 0x10, 0x09, 0x90, /* ld.q r17, 16, r25 */ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ 0x8d, 0x10, 0x05, 0x10, /* ld.q r17, 8, r17 */ @@ -3128,7 +3160,7 @@ static const bfd_byte elf_sh64_pic_plt_entry_le[PLT_ENTRY_SIZE] = 0xf0, 0xff, 0xf0, 0x6f, /* nop */ 0xf0, 0xff, 0xf0, 0x6f, /* nop */ 0x10, 0x01, 0x00, 0xce, /* movi -GOT_BIAS, r17 */ - 0x10, 0x45, 0xcb, 0x00, /* sub r12, r17, r17 */ + 0x10, 0x45, 0xc9, 0x00, /* add r12, r17, r17 */ 0x90, 0x09, 0x10, 0x8d, /* ld.q r17, 16, r25 */ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ 0x10, 0x05, 0x10, 0x8d, /* ld.q r17, 8, r17 */ @@ -3287,13 +3319,15 @@ sh64_elf64_create_dynamic_sections (abfd, info) { /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. */ - struct elf_link_hash_entry *h = NULL; + struct elf_link_hash_entry *h; + struct bfd_link_hash_entry *bh = NULL; + if (! (_bfd_generic_link_add_one_symbol (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) + (bfd_vma) 0, (const char *) NULL, false, bed->collect, &bh))) return false; + + h = (struct elf_link_hash_entry *) bh; h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; h->type = STT_OBJECT; @@ -4124,8 +4158,6 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) return true; } - -#ifndef ELF_ARCH #define TARGET_BIG_SYM bfd_elf64_sh64_vec #define TARGET_BIG_NAME "elf64-sh64" #define TARGET_LITTLE_SYM bfd_elf64_sh64l_vec @@ -4135,7 +4167,6 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) #define ELF_MAXPAGESIZE 128 #define elf_symbol_leading_char '_' -#endif /* ELF_ARCH */ #define bfd_elf64_bfd_reloc_type_lookup sh_elf64_reloc_type_lookup #define elf_info_to_howto sh_elf64_info_to_howto @@ -4190,3 +4221,34 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) #define elf_backend_plt_header_size PLT_ENTRY_SIZE #include "elf64-target.h" + +/* NetBSD support. */ +#undef TARGET_BIG_SYM +#define TARGET_BIG_SYM bfd_elf64_sh64nbsd_vec +#undef TARGET_BIG_NAME +#define TARGET_BIG_NAME "elf64-sh64-nbsd" +#undef TARGET_LITTLE_SYM +#define TARGET_LITTLE_SYM bfd_elf64_sh64lnbsd_vec +#undef TARGET_LITTLE_NAME +#define TARGET_LITTLE_NAME "elf64-sh64l-nbsd" +#undef ELF_MAXPAGESIZE +#define ELF_MAXPAGESIZE 0x10000 +#undef elf_symbol_leading_char +#define elf_symbol_leading_char 0 + +#define elf64_bed elf64_sh64_nbsd_bed + +#include "elf64-target.h" + +/* Linux support. */ +#undef TARGET_BIG_SYM +#define TARGET_BIG_SYM bfd_elf64_sh64blin_vec +#undef TARGET_BIG_NAME +#define TARGET_BIG_NAME "elf64-sh64big-linux" +#undef TARGET_LITTLE_SYM +#define TARGET_LITTLE_SYM bfd_elf64_sh64lin_vec +#undef TARGET_LITTLE_NAME +#define TARGET_LITTLE_NAME "elf64-sh64-linux" + +#define INCLUDED_TARGET_FILE +#include "elf64-target.h" |