/* Xilinx MicroBlaze-specific support for 32-bit ELF
- Copyright 2009 Free Software Foundation, Inc.
+ Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
int dbg = 0;
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
/* Get the ELF linker hash table from a link_info structure. */
#define elf32_mb_hash_table(p) \
- ((struct elf32_mb_link_hash_table *) ((p)->hash))
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
/* Create an entry in a microblaze ELF linker hash table. */
return NULL;
if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
- sizeof (struct elf32_mb_link_hash_entry)))
+ sizeof (struct elf32_mb_link_hash_entry),
+ MICROBLAZE_ELF_DATA))
{
free (ret);
return NULL;
microblaze_elf_howto_init ();
htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
local_got_offsets = elf_local_got_offsets (input_bfd);
sreloc = elf_section_data (input_section)->sreloc;
}
/* Sanity check the address. */
- if (offset > bfd_get_section_limit (output_bfd, input_section))
+ if (offset > bfd_get_section_limit (input_bfd, input_section))
{
r = bfd_reloc_outofrange;
goto check_reloc;
/* Only relocate if the symbol is defined. */
if (sec)
{
- name = bfd_get_section_name (abfd, sec);
+ name = bfd_get_section_name (sec->owner, sec);
if (strcmp (name, ".sdata2") == 0
|| strcmp (name, ".sbss2") == 0)
bfd_get_filename (input_bfd),
sym_name,
microblaze_elf_howto_table[(int) r_type]->name,
- bfd_get_section_name (abfd, sec));
+ bfd_get_section_name (sec->owner, sec));
/*bfd_set_error (bfd_error_bad_value); ??? why? */
ret = FALSE;
continue;
/* Only relocate if the symbol is defined. */
if (sec)
{
- name = bfd_get_section_name (abfd, sec);
+ name = bfd_get_section_name (sec->owner, sec);
if (strcmp (name, ".sdata") == 0
|| strcmp (name, ".sbss") == 0)
bfd_get_filename (input_bfd),
sym_name,
microblaze_elf_howto_table[(int) r_type]->name,
- bfd_get_section_name (abfd, sec));
+ bfd_get_section_name (sec->owner, sec));
/*bfd_set_error (bfd_error_bad_value); ??? why? */
ret = FALSE;
continue;
case (int) R_MICROBLAZE_64:
case (int) R_MICROBLAZE_32:
{
- /* r_symndx will be zero only for relocs against symbols
+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
from removed linkonce sections, or sections discarded by
a linker script. */
- if (r_symndx == 0 || (input_section->flags & SEC_ALLOC) == 0)
+ if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
{
relocation += addend;
if (r_type == R_MICROBLAZE_32)
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
- bfd_boolean skip, relocate = FALSE;
+ bfd_boolean skip;
/* When generating a shared object, these relocations
are copied into the output file to be resolved at run
if (outrel.r_offset == (bfd_vma) -1)
skip = TRUE;
else if (outrel.r_offset == (bfd_vma) -2)
- skip = TRUE, relocate = TRUE;
+ skip = TRUE;
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
static asection *
microblaze_elf_gc_mark_hook (asection *sec,
- struct bfd_link_info * info ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info,
Elf_Internal_Rela * rel,
struct elf_link_hash_entry * h,
Elf_Internal_Sym * sym)
{
if (h != NULL)
- {
- switch (ELF32_R_TYPE (rel->r_info))
- {
- case R_MICROBLAZE_GNU_VTINHERIT:
- case R_MICROBLAZE_GNU_VTENTRY:
- break;
-
- default:
- switch (h->root.type)
- {
- case bfd_link_hash_defined:
- case bfd_link_hash_defweak:
- return h->root.u.def.section;
-
- case bfd_link_hash_common:
- return h->root.u.c.p->section;
-
- default:
- break;
- }
- }
- }
- else
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
- return NULL;
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_MICROBLAZE_GNU_VTINHERIT:
+ case R_MICROBLAZE_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}
/* Update the got entry reference counts for the section being removed. */
if (! _bfd_elf_create_got_section (dynobj, info))
return FALSE;
htab = elf32_mb_hash_table (info);
- htab->sgot = bfd_get_section_by_name (dynobj, ".got");
- htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+ if (htab == NULL)
+ return FALSE;
+
+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
if (!htab->sgot || !htab->sgotplt)
return FALSE;
- htab->srelgot = bfd_make_section (dynobj, ".rela.got");
+ if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
+ htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
if (htab->srelgot == NULL
|| ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
| SEC_LOAD
const Elf_Internal_Rela * rel;
const Elf_Internal_Rela * rel_end;
struct elf32_mb_link_hash_table *htab;
- bfd_vma *local_got_offsets;
asection *sreloc = NULL;
if (info->relocatable)
return TRUE;
htab = elf32_mb_hash_table (info);
- local_got_offsets = elf_local_got_offsets (abfd);
+ if (htab == NULL)
+ return FALSE;
+
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
const char *name;
bfd *dynobj;
unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
- unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name;
+ unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
if (name == NULL)
htab->elf.dynobj = abfd;
dynobj = htab->elf.dynobj;
- sreloc = bfd_get_section_by_name (dynobj, name);
+ sreloc = bfd_get_linker_section (dynobj, name);
if (sreloc == NULL)
{
flagword flags;
- sreloc = bfd_make_section (dynobj, name);
flags = (SEC_HAS_CONTENTS | SEC_READONLY
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
if ((sec->flags & SEC_ALLOC) != 0)
flags |= SEC_ALLOC | SEC_LOAD;
+ sreloc = bfd_make_section_anyway_with_flags (dynobj,
+ name,
+ flags);
if (sreloc == NULL
- || ! bfd_set_section_flags (dynobj, sreloc, flags)
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
return FALSE;
}
struct elf32_mb_link_hash_table *htab;
htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
if (!htab->sgot && !create_got_section (dynobj, info))
return FALSE;
if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
- htab->splt = bfd_get_section_by_name (dynobj, ".plt");
- htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
- htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
+ htab->splt = bfd_get_linker_section (dynobj, ".plt");
+ htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
if (!info->shared)
- htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
if (!htab->splt || !htab->srelplt || !htab->sdynbss
|| (!info->shared && !htab->srelbss))
bfd *dynobj;
htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later,
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
- if (h->root.type == bfd_link_hash_warning)
- /* When warning symbols are created, they **replace** the "real"
- entry in the hash table, thus we never get to see the real
- symbol in a hash traversal. So look at it now. */
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
info = (struct bfd_link_info *) dat;
htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
if (htab->elf.dynamic_sections_created
&& h->plt.refcount > 0)
bfd *ibfd;
htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
dynobj = htab->elf.dynobj;
BFD_ASSERT (dynobj != NULL);
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym)
{
- bfd *dynobj;
struct elf32_mb_link_hash_table *htab;
htab = elf32_mb_hash_table (info);
- dynobj = htab->elf.dynobj;
+ if (htab == NULL)
+ return FALSE;
if (h->plt.offset != (bfd_vma) -1)
{
BFD_ASSERT (h->dynindx != -1);
- s = bfd_get_section_by_name (h->root.u.def.section->owner,
- ".rela.bss");
+ s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
BFD_ASSERT (s != NULL);
rela.r_offset = (h->root.u.def.value
}
/* Mark some specially defined symbols as absolute. */
- if (strcmp (h->root.root.string, "_DYNAMIC") == 0
- || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
- || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
+ if (h == htab->elf.hdynamic
+ || h == htab->elf.hgot
+ || h == htab->elf.hplt)
sym->st_shndx = SHN_ABS;
return TRUE;
struct elf32_mb_link_hash_table *htab;
htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
dynobj = htab->elf.dynobj;
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (htab->elf.dynamic_sections_created)
{
asection *splt;
Elf32_External_Dyn *dyncon, *dynconend;
- splt = bfd_get_section_by_name (dynobj, ".plt");
+ splt = bfd_get_linker_section (dynobj, ".plt");
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
/* Set the first entry in the global offset table to the address of
the dynamic section. */
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
if (sgot && sgot->size > 0)
{
if (sdyn == NULL)
{
/* Common symbols less than or equal to -G nn bytes are automatically
put into .sbss. */
- *secp = bfd_make_section_anyway (abfd, ".sbss");
+ *secp = bfd_make_section_old_way (abfd, ".sbss");
if (*secp == NULL
|| ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
return FALSE;
#define TARGET_BIG_NAME "elf32-microblaze"
#define ELF_ARCH bfd_arch_microblaze
+#define ELF_TARGET_ID MICROBLAZE_ELF_DATA
#define ELF_MACHINE_CODE EM_MICROBLAZE
#define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
#define ELF_MAXPAGESIZE 0x4 /* 4k, if we ever have 'em. */