/* Renesas / SuperH SH specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ 2006 Free Software Foundation, Inc.
Contributed by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
static bfd_boolean
sh_elf_mkobject (bfd *abfd)
{
- bfd_size_type amt = sizeof (struct sh_elf_obj_tdata);
- abfd->tdata.any = bfd_zalloc (abfd, amt);
if (abfd->tdata.any == NULL)
- return FALSE;
- return TRUE;
+ {
+ bfd_size_type amt = sizeof (struct sh_elf_obj_tdata);
+ abfd->tdata.any = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.any == NULL)
+ return FALSE;
+ }
+ return bfd_elf_mkobject (abfd);
}
/* sh ELF linker hash table. */
if (ret == (struct elf_sh_link_hash_table *) NULL)
return NULL;
- if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
- sh_elf_link_hash_newfunc))
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ sh_elf_link_hash_newfunc,
+ sizeof (struct elf_sh_link_hash_entry)))
{
free (ret);
return NULL;
h = (struct elf_link_hash_entry *) bh;
h->def_regular = 1;
h->type = STT_OBJECT;
+ htab->root.hplt = h;
if (info->shared
&& ! bfd_elf_link_record_dynamic_symbol (info, h))
/* Also discard relocs on undefined weak syms with non-default
visibility. */
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefweak)
- eh->dyn_relocs = NULL;
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
}
else
{
|| !h->def_regular)
&& ((r_type == R_SH_DIR32
&& !h->forced_local)
- || r_type == R_SH_REL32)
+ || (r_type == R_SH_REL32
+ && !SYMBOL_CALLS_LOCAL (info, h)))
&& ((input_section->flags & SEC_ALLOC) != 0
/* DWARF will emit R_SH_DIR32 relocations in its
sections against symbols defined externally
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-sh_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+sh_elf_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
struct elf_sh_link_hash_entry *edir, *eind;
-#ifdef INCLUDE_SHMEDIA
- bfd_signed_vma tmp;
-#endif
edir = (struct elf_sh_link_hash_entry *) dir;
eind = (struct elf_sh_link_hash_entry *) ind;
struct elf_sh_dyn_relocs **pp;
struct elf_sh_dyn_relocs *p;
- BFD_ASSERT (ind->root.type != bfd_link_hash_indirect);
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
edir->gotplt_refcount = eind->gotplt_refcount;
eind->gotplt_refcount = 0;
#ifdef INCLUDE_SHMEDIA
- tmp = edir->datalabel_got.refcount;
- if (tmp < 1)
- {
- edir->datalabel_got.refcount = eind->datalabel_got.refcount;
- eind->datalabel_got.refcount = tmp;
- }
- else
- BFD_ASSERT (eind->datalabel_got.refcount < 1);
+ edir->datalabel_got.refcount += eind->datalabel_got.refcount;
+ eind->datalabel_got.refcount = 0;
#endif
if (ind->root.type == bfd_link_hash_indirect
dir->needs_plt |= ind->needs_plt;
}
else
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
static int
else
{
asection *s;
+ void *vpp;
/* Track dynamic relocs needed for local syms too. */
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
if (s == NULL)
return FALSE;
- head = ((struct elf_sh_dyn_relocs **)
- &elf_section_data (s)->local_dynrel);
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_sh_dyn_relocs **) vpp;
}
p = *head;
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
if (strcmp (h->root.root.string, "_DYNAMIC") == 0
- || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ || h == htab->root.hgot)
sym->st_shndx = SHN_ABS;
return TRUE;
#define TARGET_LITTLE_NAME "elf32-shl-nbsd"
#undef ELF_MAXPAGESIZE
#define ELF_MAXPAGESIZE 0x10000
+#undef ELF_COMMONPAGESIZE
#undef elf_symbol_leading_char
#define elf_symbol_leading_char 0
#undef elf32_bed
#define TARGET_LITTLE_SYM bfd_elf32_shlin_vec
#undef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "elf32-sh-linux"
+#undef ELF_COMMONPAGESIZE
+#define ELF_COMMONPAGESIZE 0x1000
#undef elf_backend_grok_prstatus
#define elf_backend_grok_prstatus elf32_shlin_grok_prstatus