/* VAX series support for 32-bit ELF
Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Matt Thomas <matt@3am-software.com>.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
static struct bfd_link_hash_table *elf_vax_link_hash_table_create (bfd *);
static bfd_boolean elf_vax_check_relocs (bfd *, struct bfd_link_info *,
asection *, const Elf_Internal_Rela *);
-static asection *elf_vax_gc_mark_hook (asection *, struct bfd_link_info *,
- Elf_Internal_Rela *,
- struct elf_link_hash_entry *,
- Elf_Internal_Sym *);
-static bfd_boolean elf_vax_gc_sweep_hook (bfd *, struct bfd_link_info *,
- asection *,
- const Elf_Internal_Rela *);
static bfd_boolean elf_vax_adjust_dynamic_symbol (struct bfd_link_info *,
struct elf_link_hash_entry *);
static bfd_boolean elf_vax_size_dynamic_sections (bfd *, struct bfd_link_info *);
return 0;
}
+static reloc_howto_type *
+reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
#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_vax
/* end code generated by elf.el */
\f
if (ret == NULL)
return NULL;
- if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
- elf_vax_link_hash_newfunc))
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf_vax_link_hash_newfunc,
+ sizeof (struct elf_vax_link_hash_entry)))
{
free (ret);
return NULL;
section in dynobj and make room for this reloc. */
if (sreloc == NULL)
{
- const char *name;
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
- name = (bfd_elf_string_from_elf_section
- (abfd,
- elf_elfheader (abfd)->e_shstrndx,
- elf_section_data (sec)->rel_hdr.sh_name));
- if (name == NULL)
+ if (sreloc == NULL)
return FALSE;
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (abfd, sec),
- name + 5) == 0);
-
- sreloc = bfd_get_section_by_name (dynobj, name);
- if (sreloc == NULL)
- {
- sreloc = bfd_make_section_with_flags (dynobj,
- name,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
- if (sreloc == NULL
- || !bfd_set_section_alignment (dynobj, sreloc, 2))
- return FALSE;
- }
if (sec->flags & SEC_READONLY)
info->flags |= DF_TEXTREL;
}
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_VAX_GNU_VTENTRY:
- if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
static asection *
elf_vax_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_VAX_GNU_VTINHERIT:
- case R_VAX_GNU_VTENTRY:
- break;
-
- default:
- switch (h->root.type)
- {
- default:
- break;
-
- 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;
- }
- }
- }
- else
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
- return NULL;
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_VAX_GNU_VTINHERIT:
+ case R_VAX_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. */
const Elf_Internal_Rela *rel, *relend;
bfd *dynobj;
+ if (info->relocatable)
+ return TRUE;
+
dynobj = elf_hash_table (info)->dynobj;
if (dynobj == NULL)
return TRUE;
{
bfd *dynobj;
asection *s;
- unsigned int power_of_two;
dynobj = elf_hash_table (info)->dynobj;
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (!bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Set the sizes of the dynamic sections. */
/* Remember whether there is a PLT. */
plt = s->size != 0;
}
- else if (strncmp (name, ".rela", 5) == 0)
+ else if (CONST_STRNEQ (name, ".rela"))
{
if (s->size != 0)
{
s->reloc_count = 0;
}
}
- else if (strncmp (name, ".got", 4) != 0
+ else if (! CONST_STRNEQ (name, ".got")
&& strcmp (name, ".dynbss") != 0)
{
/* It's not one of our sections, so don't allocate space. */
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
- if (info->relocatable)
- return TRUE;
-
dynobj = elf_hash_table (info)->dynobj;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
}
howto = howto_table + r_type;
- /* This is a final link. */
r_symndx = ELF32_R_SYM (rel->r_info);
h = NULL;
sym = NULL;
relocation = 0;
}
+ 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;
+ }
+
+ if (info->relocatable)
+ continue;
+
switch (r_type)
{
case R_VAX_GOT32:
&& ((r_type != R_VAX_PC8
&& r_type != R_VAX_PC16
&& r_type != R_VAX_PC32)
- || (!info->symbolic
- || !h->def_regular)))
+ || ((input_section->flags & SEC_CODE)
+ && (!info->symbolic
+ || (!h->def_regular && h->type != STT_SECTION)))))
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
time. */
if (sreloc == NULL)
{
- const char *name;
-
- name = (bfd_elf_string_from_elf_section
- (input_bfd,
- elf_elfheader (input_bfd)->e_shstrndx,
- elf_section_data (input_section)->rel_hdr.sh_name));
- if (name == NULL)
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
return FALSE;
-
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (input_bfd,
- input_section),
- name + 5) == 0);
-
- sreloc = bfd_get_section_by_name (dynobj, name);
- BFD_ASSERT (sreloc != NULL);
}
skip = FALSE;
{
asection *osec;
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
osec = sec->output_section;
indx = elf_section_data (osec)->dynindx;
- BFD_ASSERT (indx > 0);
+ if (indx == 0)
+ {
+ struct elf_link_hash_table *htab;
+ htab = elf_hash_table (info);
+ osec = htab->text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
}
outrel.r_info = ELF32_R_INFO (indx, r_type);
elf_vax_adjust_dynamic_symbol
#define elf_backend_size_dynamic_sections \
elf_vax_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
#define elf_backend_relocate_section elf_vax_relocate_section
#define elf_backend_finish_dynamic_symbol \
elf_vax_finish_dynamic_symbol