diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2010-10-30 23:02:32 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2010-10-30 23:02:32 +0000 |
commit | b3cded65e92ba4d9b5e5a33fb95c4d551bda9c1b (patch) | |
tree | 69d40fbef2c0c4ee32fe97b7a28b510f2e3c2dbc /bfd/elf32-vax.c | |
parent | 7a815afd9b5121ee0f65dc1e1de1c0de6de97679 (diff) |
Notes
Diffstat (limited to 'bfd/elf32-vax.c')
-rw-r--r-- | bfd/elf32-vax.c | 132 |
1 files changed, 62 insertions, 70 deletions
diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index bf481e459e75d..aac81c11e5d0e 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1,6 +1,6 @@ /* VAX series support for 32-bit ELF Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Contributed by Matt Thomas <matt@3am-software.com>. This file is part of BFD, the Binary File Descriptor library. @@ -19,8 +19,8 @@ along with this program; if not, write to the Free Software 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" @@ -34,13 +34,6 @@ static struct bfd_hash_entry *elf_vax_link_hash_newfunc (struct bfd_hash_entry * 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 *); @@ -329,7 +322,22 @@ reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) 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 */ @@ -738,7 +746,7 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, if (name == NULL) return FALSE; - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 + BFD_ASSERT (CONST_STRNEQ (name, ".rela") && strcmp (bfd_get_section_name (abfd, sec), name + 5) == 0); @@ -829,38 +837,20 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, 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. */ @@ -935,7 +925,6 @@ elf_vax_adjust_dynamic_symbol (info, h) { bfd *dynobj; asection *s; - unsigned int power_of_two; dynobj = elf_hash_table (info)->dynobj; @@ -1089,28 +1078,7 @@ elf_vax_adjust_dynamic_symbol (info, h) 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. */ @@ -1194,7 +1162,7 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) /* 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) { @@ -1226,7 +1194,7 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) 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. */ @@ -1402,9 +1370,6 @@ elf_vax_relocate_section (bfd *output_bfd, 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); @@ -1436,7 +1401,6 @@ elf_vax_relocate_section (bfd *output_bfd, } howto = howto_table + r_type; - /* This is a final link. */ r_symndx = ELF32_R_SYM (rel->r_info); h = NULL; sym = NULL; @@ -1492,6 +1456,20 @@ elf_vax_relocate_section (bfd *output_bfd, 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: @@ -1625,8 +1603,9 @@ elf_vax_relocate_section (bfd *output_bfd, && ((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; @@ -1646,7 +1625,7 @@ elf_vax_relocate_section (bfd *output_bfd, if (name == NULL) return FALSE; - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 + BFD_ASSERT (CONST_STRNEQ (name, ".rela") && strcmp (bfd_get_section_name (input_bfd, input_section), name + 5) == 0); @@ -1705,9 +1684,21 @@ elf_vax_relocate_section (bfd *output_bfd, { 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); @@ -2087,6 +2078,7 @@ elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) 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 |