/* Motorola 68k series support for 32-bit ELF
Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
#define ELF_ARCH bfd_arch_m68k
+#define ELF_TARGET_ID M68K_ELF_DATA
\f
/* Functions for the m68k ELF linker. */
/* Get the m68k ELF linker hash table from a link_info structure. */
#define elf_m68k_hash_table(p) \
- ((struct elf_m68k_link_hash_table *) (p)->hash)
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == M68K_ELF_DATA ? ((struct elf_m68k_link_hash_table *) ((p)->hash)) : NULL)
/* Shortcut to multi-GOT data. */
#define elf_m68k_multi_got(INFO) (&elf_m68k_hash_table (INFO)->multi_got_)
/* Create an entry in an m68k ELF linker hash table. */
static struct bfd_hash_entry *
-elf_m68k_link_hash_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
+elf_m68k_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
{
struct bfd_hash_entry *ret = entry;
/* Create an m68k ELF linker hash table. */
static struct bfd_link_hash_table *
-elf_m68k_link_hash_table_create (abfd)
- bfd *abfd;
+elf_m68k_link_hash_table_create (bfd *abfd)
{
struct elf_m68k_link_hash_table *ret;
bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table);
if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
elf_m68k_link_hash_newfunc,
- sizeof (struct elf_m68k_link_hash_entry)))
+ sizeof (struct elf_m68k_link_hash_entry),
+ M68K_ELF_DATA))
{
free (ret);
return NULL;
case EF_M68K_CF_EMAC:
mac = "emac";
break;
+ case EF_M68K_CF_EMAC_B:
+ mac = "emac_b";
+ break;
}
if (mac)
fprintf (file, " [%s]", mac);
struct elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel, *relend;
bfd *dynobj;
- asection *sgot;
- asection *srelgot;
struct elf_m68k_got *got;
if (info->relocatable)
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
-
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
got = NULL;
relend = relocs + sec->reloc_count;
}
if (sec != NULL && elf_discarded_section (sec))
- {
- /* For relocs against symbols from removed linkonce sections,
- or sections discarded by a linker script, we just want the
- section contents zeroed. Avoid any special processing. */
- _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
- rel->r_info = 0;
- rel->r_addend = 0;
- continue;
- }
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, relend, howto, contents);
if (info->relocatable)
continue;
case R_68K_PC16:
case R_68K_PC32:
if (info->shared
- && r_symndx != 0
+ && r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
return FALSE;
}
- if (r_symndx != 0
+ if (r_symndx != STN_UNDEF
&& r_type != R_68K_NONE
&& (h == NULL
|| h->root.type == bfd_link_hash_defined
break;
case R_68K_TLS_GD32:
+ /* The value for this relocation is actually put in
+ the second GOT slot. */
+ relocation = bfd_get_signed_32 (output_bfd,
+ (sgot->contents
+ + got_entry_offset + 4));
relocation += dtpoff_base (info);
break;
bfd_elf_m68k_set_target_options (struct bfd_link_info *info, int got_handling)
{
struct elf_m68k_link_hash_table *htab;
-
- htab = elf_m68k_hash_table (info);
+ bfd_boolean use_neg_got_offsets_p;
+ bfd_boolean allow_multigot_p;
+ bfd_boolean local_gp_p;
switch (got_handling)
{
case 0:
/* --got=single. */
- htab->local_gp_p = FALSE;
- htab->use_neg_got_offsets_p = FALSE;
- htab->allow_multigot_p = FALSE;
+ local_gp_p = FALSE;
+ use_neg_got_offsets_p = FALSE;
+ allow_multigot_p = FALSE;
break;
case 1:
/* --got=negative. */
- htab->local_gp_p = TRUE;
- htab->use_neg_got_offsets_p = TRUE;
- htab->allow_multigot_p = FALSE;
+ local_gp_p = TRUE;
+ use_neg_got_offsets_p = TRUE;
+ allow_multigot_p = FALSE;
break;
case 2:
/* --got=multigot. */
- htab->local_gp_p = TRUE;
- htab->use_neg_got_offsets_p = TRUE;
- htab->allow_multigot_p = TRUE;
+ local_gp_p = TRUE;
+ use_neg_got_offsets_p = TRUE;
+ allow_multigot_p = TRUE;
break;
default:
BFD_ASSERT (FALSE);
+ return;
+ }
+
+ htab = elf_m68k_hash_table (info);
+ if (htab != NULL)
+ {
+ htab->local_gp_p = local_gp_p;
+ htab->use_neg_got_offsets_p = use_neg_got_offsets_p;
+ htab->allow_multigot_p = allow_multigot_p;
}
}