static boolean sh_elf64_set_mach_from_flags PARAMS ((bfd *));
static boolean sh_elf64_set_private_flags PARAMS ((bfd *, flagword));
static asection *sh_elf64_gc_mark_hook
- PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+ PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *, Elf_Internal_Sym *));
static boolean sh_elf64_gc_sweep_hook
PARAMS ((bfd *, struct bfd_link_info *, asection *,
static boolean sh64_elf64_add_symbol_hook
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
-extern boolean sh64_elf64_link_output_symbol_hook
+static boolean sh64_elf64_link_output_symbol_hook
PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
asection *));
static boolean sh64_elf64_fake_sections
asymbol **symbols;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
asection *input_section = link_order->u.indirect.section;
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
- Elf64_External_Sym *external_syms = NULL;
- Elf_External_Sym_Shndx *shndx_buf = NULL;
- Elf_External_Sym_Shndx *shndx;
- Elf_Internal_Sym *internal_syms = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
/* We only need to handle the case of relaxing, or of having a
particular set of section contents, specially. */
symbols);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
input_section->_raw_size);
&& input_section->reloc_count > 0)
{
Elf_Internal_Sym *isymp;
+ Elf_Internal_Sym *isymend;
asection **secpp;
- Elf64_External_Sym *esym, *esymend;
- bfd_size_type amt;
- if (symtab_hdr->contents != NULL)
- external_syms = (Elf64_External_Sym *) symtab_hdr->contents;
- else
- {
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf64_External_Sym);
-
- external_syms = (Elf64_External_Sym *) bfd_malloc (amt);
- if (external_syms == NULL && symtab_hdr->sh_info > 0)
- goto error_return;
-
- if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || (bfd_bread ((PTR) external_syms, amt, input_bfd) != amt))
- goto error_return;
- }
-
- if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
+ /* Read this BFD's local symbols. */
+ if (symtab_hdr->sh_info != 0)
{
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
-
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- goto error_return;
-
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
goto error_return;
}
if (internal_relocs == NULL)
goto error_return;
- internal_syms = ((Elf_Internal_Sym *)
- bfd_malloc (symtab_hdr->sh_info
- * sizeof (Elf_Internal_Sym)));
- if (internal_syms == NULL && symtab_hdr->sh_info > 0)
- goto error_return;
-
sections = (asection **) bfd_malloc (symtab_hdr->sh_info
* sizeof (asection *));
if (sections == NULL && symtab_hdr->sh_info > 0)
goto error_return;
- isymp = internal_syms;
secpp = sections;
- esym = external_syms;
- esymend = esym + symtab_hdr->sh_info;
- shndx = shndx_buf;
- for (; esym < esymend;
- ++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isymp = isymbuf; isymp < isymend; ++isymp, ++secpp)
{
asection *isec;
- bfd_elf64_swap_symbol_in (input_bfd, (const PTR) esym,
- (const PTR) shndx, isymp);
-
if (isymp->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
if (! sh_elf64_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
- internal_syms, sections))
+ isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
- sections = NULL;
- if (internal_syms != NULL)
- free (internal_syms);
- internal_syms = NULL;
- if (external_syms != NULL && symtab_hdr->contents == NULL)
- free (external_syms);
- external_syms = NULL;
if (internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
- internal_relocs = NULL;
+ if (isymbuf != NULL
+ && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
}
return data;
error_return:
+ if (sections != NULL)
+ free (sections);
if (internal_relocs != NULL
&& internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
- if (external_syms != NULL && symtab_hdr->contents == NULL)
- free (external_syms);
- if (internal_syms != NULL)
- free (internal_syms);
- if (sections != NULL)
- free (sections);
+ if (isymbuf != NULL
+ && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
return NULL;
}
{
flagword old_flags, new_flags;
- if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
return false;
if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
relocation. */
static asection *
-sh_elf64_gc_mark_hook (abfd, info, rel, h, sym)
- bfd *abfd;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- Elf_Internal_Rela *rel;
- struct elf_link_hash_entry *h;
- Elf_Internal_Sym *sym;
+sh_elf64_gc_mark_hook (sec, info, rel, h, sym)
+ asection *sec;
+ struct bfd_link_info *info ATTRIBUTE_UNUSED;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
{
if (h != NULL)
{
break;
default:
+ while (h->root.type == bfd_link_hash_indirect
+ && h->root.u.i.link)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
switch (h->root.type)
{
case bfd_link_hash_defined:
}
}
else
- {
- return bfd_section_from_elf_index (abfd, sym->st_shndx);
- }
+ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
return NULL;
}
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;
}
we don't need to look up and make sure to emit the main symbol for each
DataLabel symbol. */
-boolean
+static boolean
sh64_elf64_link_output_symbol_hook (abfd, info, cname, sym, input_sec)
bfd *abfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
0xc8, 0x00, 0x01, 0x10, /* shori (.got.plt >> 16) & 65535, r17 */
0xc8, 0x00, 0x01, 0x10, /* shori .got.plt & 65535, r17 */
0x8d, 0x10, 0x09, 0x90, /* ld.q r17, 16, r25 */
- 0x6b, 0xf1, 0x46, 0x00, /* ptabs r17, tr0 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
0x8d, 0x10, 0x05, 0x10, /* ld.q r17, 8, r17 */
0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
0x6f, 0xf0, 0xff, 0xf0, /* nop */
0x10, 0x01, 0x00, 0xc8, /* shori (.got.plt >> 16) & 65535, r17 */
0x10, 0x01, 0x00, 0xc8, /* shori .got.plt & 65535, r17 */
0x90, 0x09, 0x10, 0x8d, /* ld.q r17, 16, r25 */
- 0x00, 0x46, 0xf1, 0x6b, /* ptabs r17, tr0 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
0x10, 0x05, 0x10, 0x8d, /* ld.q r17, 8, r17 */
0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
0xf0, 0xff, 0xf0, 0x6f, /* nop */
0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
0x6f, 0xf0, 0xff, 0xf0, /* nop */
- 0xcc, 0x00, 0x01, 0x90, /* movi .PLT0 >> 16, r25 */
- 0xc8, 0x00, 0x01, 0x90, /* shori .PLT0 & 65535, r25 */
- 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0xcc, 0x00, 0x01, 0x90, /* movi (.+8-.PLT0) >> 16, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori (.+4-.PLT0) & 65535, r25 */
+ 0x6b, 0xf5, 0x66, 0x00, /* ptrel r25, tr0 */
0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */
0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
0xf0, 0xff, 0xf0, 0x6f, /* nop */
- 0x90, 0x01, 0x00, 0xcc, /* movi .PLT0 >> 16, r25 */
- 0x90, 0x01, 0x00, 0xc8, /* shori .PLT0 & 65535, r25 */
- 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0x90, 0x01, 0x00, 0xcc, /* movi (.+8-.PLT0) >> 16, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori (.+4-.PLT0) & 65535, r25 */
+ 0x00, 0x66, 0xf5, 0x6b, /* ptrel r25, tr0 */
0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */
0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
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 */
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 */
{
/* 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;
}
/* Allocate memory for the section contents. */
- s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
if (s->contents == NULL && s->_raw_size != 0)
return false;
}
The first three are reserved. */
got_offset = (plt_index + 3) * 8;
- got_offset -= GOT_BIAS;
+ if (info->shared)
+ got_offset -= GOT_BIAS;
/* Fill in the entry in the procedure linkage table. */
if (! info->shared)
(splt->contents + h->plt.offset
+ elf_sh64_plt_symbol_offset (info)));
+ /* Set bottom bit because its for a branch to SHmedia */
movi_shori_putval (output_bfd,
- (splt->output_section->vma + splt->output_offset),
+ -(h->plt.offset
+ + elf_sh64_plt_plt0_offset (info) + 8)
+ | 1,
(splt->contents + h->plt.offset
+ elf_sh64_plt_plt0_offset (info)));
}
+ elf_sh64_plt_symbol_offset (info)));
}
- got_offset += GOT_BIAS;
+ if (info->shared)
+ got_offset += GOT_BIAS;
movi_shori_putval (output_bfd,
plt_index * sizeof (Elf64_External_Rela),
Elf_Internal_Dyn dyn;
const char *name;
asection *s;
+ struct elf_link_hash_entry *h;
bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
default:
break;
+ case DT_INIT:
+ name = info->init_function;
+ goto get_sym;
+
+ case DT_FINI:
+ name = info->fini_function;
+ get_sym:
+ if (dyn.d_un.d_val != 0)
+ {
+ h = elf_link_hash_lookup (elf_hash_table (info), name,
+ false, false, true);
+ if (h != NULL && (h->other & STO_SH5_ISA32))
+ {
+ dyn.d_un.d_val |= 1;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ break;
+
case DT_PLTGOT:
name = ".got";
goto get_vma;
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
#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
#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"