/* M32R-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.
This file is part of BFD, the Binary File Descriptor library.
if (ret == NULL)
return NULL;
- if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
- m32r_elf_link_hash_newfunc))
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ m32r_elf_link_hash_newfunc,
+ sizeof (struct elf_m32r_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))
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
struct elf_m32r_dyn_relocs **pp;
struct elf_m32r_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* 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;)
{
eind->dyn_relocs = NULL;
}
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
\f
pp = &p->next;
}
}
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ 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
{
case R_M32R_24_RELA:
case R_M32R_32_RELA:
case R_M32R_REL32:
+ case R_M32R_10_PCREL_RELA:
case R_M32R_18_PCREL_RELA:
case R_M32R_26_PCREL_RELA:
case R_M32R_HI16_ULO_RELA:
if (info->shared
&& r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0
- && ((r_type != R_M32R_18_PCREL_RELA
+ && (( r_type != R_M32R_10_PCREL_RELA
+ && r_type != R_M32R_18_PCREL_RELA
&& r_type != R_M32R_26_PCREL_RELA
&& r_type != R_M32R_REL32)
|| (h != NULL
if (skip)
memset (&outrel, 0, sizeof outrel);
- else if (r_type == R_M32R_18_PCREL_RELA
+ else if ( r_type == R_M32R_10_PCREL_RELA
+ || r_type == R_M32R_18_PCREL_RELA
|| r_type == R_M32R_26_PCREL_RELA
|| r_type == R_M32R_REL32)
{
an addend for the dynamic reloc. */
if (! relocate)
continue;
+ break;
}
- break;
+ else if (r_type != R_M32R_10_PCREL_RELA)
+ break;
+ /* Fall through. */
case (int) R_M32R_10_PCREL :
r = m32r_elf_do_10_pcrel_reloc (input_bfd, howto, input_section,
/* Mark some specially defined symbols 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;
case R_M32R_HI16_SLO_RELA:
case R_M32R_LO16_RELA:
case R_M32R_SDA16_RELA:
+ case R_M32R_10_PCREL_RELA:
case R_M32R_18_PCREL_RELA:
case R_M32R_26_PCREL_RELA:
if (h != NULL)
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
- if (ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
- || ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
+ if ( ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_18_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_10_PCREL_RELA
|| ELF32_R_TYPE (rel->r_info) == R_M32R_REL32)
p->pc_count -= 1;
p->count -= 1;
case R_M32R_HI16_SLO_RELA:
case R_M32R_LO16_RELA:
case R_M32R_SDA16_RELA:
+ case R_M32R_10_PCREL_RELA:
case R_M32R_18_PCREL_RELA:
case R_M32R_26_PCREL_RELA:
symbol. */
if ((info->shared
&& (sec->flags & SEC_ALLOC) != 0
- && ((r_type != R_M32R_26_PCREL_RELA
+ && (( r_type != R_M32R_26_PCREL_RELA
&& r_type != R_M32R_18_PCREL_RELA
+ && r_type != R_M32R_10_PCREL_RELA
&& r_type != R_M32R_REL32)
|| (h != NULL
&& (! info->symbolic
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_m32r_dyn_relocs **)
- &elf_section_data (s)->local_dynrel);
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_m32r_dyn_relocs **) vpp;
}
p = *head;
}
p->count += 1;
- if (ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
- || ELF32_R_TYPE (rel->r_info) == R_M32R_REL32
- || ELF32_R_TYPE (rel->r_info) == R_M32R_18_PCREL_RELA)
+ if ( ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_18_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_10_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_REL32)
p->pc_count += 1;
}
break;