/* Matsushita 10300 specific support for 32-bit ELF
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
-
+
HOWTO (R_MN10300_SYM_DIFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
asection * s;
struct elf_link_hash_entry * h;
const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab;
int ptralign;
/* This function may be called more than once. */
- if (bfd_get_section_by_name (abfd, ".got") != NULL)
+ htab = elf_hash_table (info);
+ if (htab->sgot != NULL)
return TRUE;
switch (bed->s->arch_size)
if (bed->plt_readonly)
pltflags |= SEC_READONLY;
- s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
+ htab->splt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE;
{
h = _bfd_elf_define_linkage_sym (abfd, info, s,
"_PROCEDURE_LINKAGE_TABLE_");
- elf_hash_table (info)->hplt = h;
+ htab->hplt = h;
if (h == NULL)
return FALSE;
}
- s = bfd_make_section_with_flags (abfd, ".got", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ htab->sgot = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
if (bed->want_got_plt)
{
- s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ htab->sgotplt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
because we don't want to define the symbol if we are not creating
a global offset table. */
h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
- elf_hash_table (info)->hgot = h;
+ htab->hgot = h;
if (h == NULL)
return FALSE;
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
}
r_type = ELF32_R_TYPE (rel->r_info);
if (info->shared)
info->flags |= DF_STATIC_TLS;
/* Fall through */
-
+
case R_MN10300_TLS_GD:
case R_MN10300_GOT32:
case R_MN10300_GOT24:
if (sgot == NULL)
{
- sgot = bfd_get_section_by_name (dynobj, ".got");
+ sgot = htab->root.sgot;
BFD_ASSERT (sgot != NULL);
}
if (srelgot == NULL
&& (h != NULL || info->shared))
{
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
if (srelgot == NULL)
{
- srelgot = bfd_make_section_with_flags (dynobj,
- ".rela.got",
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
if (srelgot == NULL
|| ! bfd_set_section_alignment (dynobj, srelgot, 2))
goto fail;
return bfd_reloc_dangerous;
/* Use global offset table as symbol value. */
- value = bfd_get_section_by_name (dynobj,
- ".got")->output_section->vma;
+ value = htab->root.sgot->output_section->vma;
value -= (input_section->output_section->vma
+ input_section->output_offset);
value -= offset;
return bfd_reloc_dangerous;
/* Use global offset table as symbol value. */
- value = bfd_get_section_by_name (dynobj,
- ".got")->output_section->vma;
+ value = htab->root.sgot->output_section->vma;
value -= (input_section->output_section->vma
+ input_section->output_offset);
value -= offset;
if (dynobj == NULL)
return bfd_reloc_dangerous;
- value -= bfd_get_section_by_name (dynobj,
- ".got")->output_section->vma;
+ value -= htab->root.sgot->output_section->vma;
value += addend;
bfd_put_32 (input_bfd, value, hit_data);
if (dynobj == NULL)
return bfd_reloc_dangerous;
- value -= bfd_get_section_by_name (dynobj,
- ".got")->output_section->vma;
+ value -= htab->root.sgot->output_section->vma;
value += addend;
if ((long) value > 0x7fffff || (long) value < -0x800000)
if (dynobj == NULL)
return bfd_reloc_dangerous;
- value -= bfd_get_section_by_name (dynobj,
- ".got")->output_section->vma;
+ value -= htab->root.sgot->output_section->vma;
value += addend;
if ((long) value > 0x7fff || (long) value < -0x8000)
if (dynobj == NULL)
return bfd_reloc_dangerous;
- splt = bfd_get_section_by_name (dynobj, ".plt");
-
+ splt = htab->root.splt;
value = (splt->output_section->vma
+ splt->output_offset
+ h->plt.offset) - value;
if (dynobj == NULL)
return bfd_reloc_dangerous;
- splt = bfd_get_section_by_name (dynobj, ".plt");
-
+ splt = htab->root.splt;
value = (splt->output_section->vma
+ splt->output_offset
+ h->plt.offset) - value;
if (dynobj == NULL)
return bfd_reloc_dangerous;
- sgot = bfd_get_section_by_name (dynobj, ".got");
-
+ sgot = htab->root.sgot;
BFD_ASSERT (sgot != NULL);
value = htab->tls_ldm_got.offset + sgot->output_offset;
bfd_put_32 (input_bfd, value, hit_data);
if (!htab->tls_ldm_got.rel_emitted)
{
- asection * srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ asection * srelgot = bfd_get_linker_section (dynobj, ".rela.got");
Elf_Internal_Rela rel;
BFD_ASSERT (srelgot != NULL);
if (dynobj == NULL)
return bfd_reloc_dangerous;
- sgot = bfd_get_section_by_name (dynobj, ".got");
-
+ sgot = htab->root.sgot;
if (r_type == R_MN10300_TLS_GD)
value = dtpoff (info, value);
asection * srelgot;
Elf_Internal_Rela outrel;
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
outrel.r_offset = (sgot->output_section->vma
bfd_reloc_status_type r;
int tls_r_type;
bfd_boolean unresolved_reloc = FALSE;
- bfd_boolean warned;
+ bfd_boolean warned, ignored;
struct elf_link_hash_entry * hh;
relocation = 0;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
hh, sec, relocation,
- unresolved_reloc, warned);
+ unresolved_reloc, warned, ignored);
}
h = elf_mn10300_hash_entry (hh);
h->root.root.root.string);
}
- if (sec != NULL && elf_discarded_section (sec))
+ if (sec != NULL && discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
serve to keep the section artifically inflated. */
if (ELF32_R_TYPE ((irelend - 1)->r_info) == (int) R_MN10300_ALIGN)
--irelend;
-
+
/* The deletion must stop at the next ALIGN reloc for an aligment
power larger than, or not a multiple of, the number of bytes we
are deleting. */
isym->st_name);
if ((sym_sec->flags & SEC_MERGE)
- && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
+ && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
{
symval = isym->st_value;
{
asection * splt;
- splt = bfd_get_section_by_name (elf_hash_table (link_info)
- ->dynobj, ".plt");
-
+ splt = hash_table->root.splt;
value = ((splt->output_section->vma
+ splt->output_offset
+ h->root.plt.offset)
{
asection * sgot;
- sgot = bfd_get_section_by_name (elf_hash_table (link_info)
- ->dynobj, ".got");
-
+ sgot = hash_table->root.sgot;
if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOT32)
{
value = sgot->output_offset;
struct elf32_mn10300_link_hash_table *ret;
bfd_size_type amt = sizeof (* ret);
- ret = bfd_malloc (amt);
+ ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
return NULL;
}
- ret->flags = 0;
- ret->tls_ldm_got.refcount = 0;
ret->tls_ldm_got.offset = -1;
- ret->tls_ldm_got.got_allocated = 0;
- ret->tls_ldm_got.rel_emitted = 0;
amt = sizeof (struct elf_link_hash_table);
- ret->static_hash_table = bfd_malloc (amt);
+ ret->static_hash_table = bfd_zmalloc (amt);
if (ret->static_hash_table == NULL)
{
free (ret);
struct elf32_mn10300_link_hash_table *ret
= (struct elf32_mn10300_link_hash_table *) hash;
- _bfd_generic_link_hash_table_free
+ _bfd_elf_link_hash_table_free
((struct bfd_link_hash_table *) ret->static_hash_table);
- _bfd_generic_link_hash_table_free
+ _bfd_elf_link_hash_table_free
((struct bfd_link_hash_table *) ret);
}
flagword flags;
asection * s;
const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
int ptralign = 0;
switch (bed->s->arch_size)
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
- s = bfd_make_section_with_flags (abfd,
- (bed->default_use_rela_p
- ? ".rela.plt" : ".rel.plt"),
- flags | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt"),
+ flags | SEC_READONLY);
+ htab->root.srelplt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
if (! _bfd_mn10300_elf_create_got_section (abfd, info))
return FALSE;
- {
- const char * secname;
- char * relname;
- flagword secflags;
- asection * sec;
-
- for (sec = abfd->sections; sec; sec = sec->next)
- {
- secflags = bfd_get_section_flags (abfd, sec);
- if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
- || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
- continue;
-
- secname = bfd_get_section_name (abfd, sec);
- relname = bfd_malloc (strlen (secname) + 6);
- strcpy (relname, ".rela");
- strcat (relname, secname);
-
- s = bfd_make_section_with_flags (abfd, relname,
- flags | SEC_READONLY);
- if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, ptralign))
- return FALSE;
- }
- }
-
if (bed->want_dynbss)
{
/* The .dynbss section is a place to put symbols which are defined
image and use a R_*_COPY reloc to tell the dynamic linker to
initialize them at run time. The linker script puts the .dynbss
section into the .bss section of the final image. */
- s = bfd_make_section_with_flags (abfd, ".dynbss",
- SEC_ALLOC | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
if (s == NULL)
return FALSE;
copy relocs. */
if (! info->shared)
{
- s = bfd_make_section_with_flags (abfd,
- (bed->default_use_rela_p
- ? ".rela.bss" : ".rel.bss"),
- flags | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
_bfd_mn10300_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
struct elf_link_hash_entry * h)
{
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
bfd * dynobj;
asection * s;
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
/* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL
return FALSE;
}
- s = bfd_get_section_by_name (dynobj, ".plt");
+ s = htab->root.splt;
BFD_ASSERT (s != NULL);
/* If this is the first .plt entry, make room for the special
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
- s = bfd_get_section_by_name (dynobj, ".got.plt");
+ s = htab->root.sgotplt;
BFD_ASSERT (s != NULL);
s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
- s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
BFD_ASSERT (s != NULL);
s->size += sizeof (Elf32_External_Rela);
if (!h->non_got_ref)
return TRUE;
- if (h->size == 0)
- {
- (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
- h->root.root.string);
- return TRUE;
- }
-
/* We must allocate the symbol in our .dynbss section, which will
become part of the .bss section of the executable. There will be
an entry for this symbol in the .dynsym section. The dynamic
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- s = bfd_get_section_by_name (dynobj, ".dynbss");
+ s = bfd_get_linker_section (dynobj, ".dynbss");
BFD_ASSERT (s != NULL);
/* We must generate a R_MN10300_COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the
runtime process image. We need to remember the offset into the
.rela.bss section we are going to use. */
- if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
{
asection * srel;
- srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
BFD_ASSERT (srel != NULL);
srel->size += sizeof (Elf32_External_Rela);
h->needs_copy = 1;
bfd_boolean relocs;
bfd_boolean reltext;
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
BFD_ASSERT (dynobj != NULL);
if (elf_hash_table (info)->dynamic_sections_created)
/* Set the contents of the .interp section to the interpreter. */
if (info->executable)
{
- s = bfd_get_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
not actually use these entries. Reset the size of .rela.got,
which will cause it to get stripped from the output file
below. */
- s = bfd_get_section_by_name (dynobj, ".rela.got");
+ s = htab->root.sgot;
if (s != NULL)
s->size = 0;
}
if (htab->tls_ldm_got.refcount > 0)
{
- s = bfd_get_section_by_name (dynobj, ".rela.got");
+ s = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (s != NULL);
s->size += sizeof (Elf32_External_Rela);
}
struct elf_link_hash_entry * h,
Elf_Internal_Sym * sym)
{
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
bfd * dynobj;
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
if (h->plt.offset != (bfd_vma) -1)
{
BFD_ASSERT (h->dynindx != -1);
- splt = bfd_get_section_by_name (dynobj, ".plt");
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
- srel = bfd_get_section_by_name (dynobj, ".rela.plt");
+ splt = htab->root.splt;
+ sgot = htab->root.sgotplt;
+ srel = bfd_get_linker_section (dynobj, ".rela.plt");
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
/* Get the index in the procedure linkage table which
Elf_Internal_Rela rel;
/* This symbol has an entry in the global offset table. Set it up. */
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srel = bfd_get_section_by_name (dynobj, ".rela.got");
+ sgot = htab->root.sgot;
+ srel = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (sgot != NULL && srel != NULL);
rel.r_offset = (sgot->output_section->vma
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- s = bfd_get_section_by_name (h->root.u.def.section->owner,
- ".rela.bss");
+ s = bfd_get_linker_section (dynobj, ".rela.bss");
BFD_ASSERT (s != NULL);
rel.r_offset = (h->root.u.def.value
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
- if (streq (h->root.root.string, "_DYNAMIC")
+ if (h == elf_hash_table (info)->hdynamic
|| h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
bfd * dynobj;
asection * sgot;
asection * sdyn;
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
- dynobj = elf_hash_table (info)->dynobj;
-
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ dynobj = htab->root.dynobj;
+ sgot = htab->root.sgotplt;
BFD_ASSERT (sgot != NULL);
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
{
}
/* Fill in the first entry in the procedure linkage table. */
- splt = bfd_get_section_by_name (dynobj, ".plt");
+ splt = htab->root.splt;
if (splt && splt->size > 0)
{
if (info->shared)
properly. */
static enum elf_reloc_type_class
-_bfd_mn10300_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+_bfd_mn10300_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{