diff options
author | dim <dim@FreeBSD.org> | 2010-11-01 19:35:33 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-11-01 19:35:33 +0000 |
commit | 3f5c947f4453c6016a2a6a9636367ee3f48fc6fc (patch) | |
tree | 461aafc934d462eb9b9221308f8e25238c0ada62 /contrib/binutils/bfd/elf64-s390.c | |
parent | e6be3e7867eb43d220575baee2ce5662fb03e46c (diff) | |
parent | d0f678fa0ff3f08a4eca29daf4d1ac39797b6326 (diff) | |
download | FreeBSD-src-3f5c947f4453c6016a2a6a9636367ee3f48fc6fc.zip FreeBSD-src-3f5c947f4453c6016a2a6a9636367ee3f48fc6fc.tar.gz |
Merge ^/vendor/binutils/dist@214571 into contrib/binutils, which brings
us up to version 2.17.50.20070703, at the last GPLv2 commit.
Amongst others, this added upstream support for some FreeBSD-specific
things that we previously had to manually hack in, such as the OSABI
label support, and so on.
There are also quite a number of new files, some for cpu's (e.g. SPU)
that we may or may not be interested in, but those can be cleaned up
later on, if needed.
Diffstat (limited to 'contrib/binutils/bfd/elf64-s390.c')
-rw-r--r-- | contrib/binutils/bfd/elf64-s390.c | 166 |
1 files changed, 77 insertions, 89 deletions
diff --git a/contrib/binutils/bfd/elf64-s390.c b/contrib/binutils/bfd/elf64-s390.c index 1fe0c6c..47fbff6 100644 --- a/contrib/binutils/bfd/elf64-s390.c +++ b/contrib/binutils/bfd/elf64-s390.c @@ -1,5 +1,5 @@ /* IBM S/390-specific support for 64-bit ELF - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Contributed Martin Schwidefsky (schwidefsky@de.ibm.com). @@ -20,8 +20,8 @@ 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" @@ -46,12 +46,6 @@ static void elf_s390_copy_indirect_symbol static bfd_boolean elf_s390_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); -static asection *elf_s390_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static bfd_boolean elf_s390_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); struct elf_s390_link_hash_entry; static void elf_s390_adjust_gotplt PARAMS ((struct elf_s390_link_hash_entry *)); @@ -73,8 +67,6 @@ static enum elf_reloc_type_class elf_s390_reloc_type_class PARAMS ((const Elf_Internal_Rela *)); static bfd_boolean elf_s390_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean elf_s390_mkobject - PARAMS ((bfd *)); static bfd_boolean elf_s390_object_p PARAMS ((bfd *)); static int elf_s390_tls_transition @@ -364,6 +356,27 @@ elf_s390_reloc_type_lookup (abfd, code) return 0; } +static reloc_howto_type * +elf_s390_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); + i++) + if (elf_howto_table[i].name != NULL + && strcasecmp (elf_howto_table[i].name, r_name) == 0) + return &elf_howto_table[i]; + + if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0) + return &elf64_s390_vtinherit_howto; + if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0) + return &elf64_s390_vtentry_howto; + + return NULL; +} + /* We need to use ELF64_R_TYPE so we have our own copy of this function, and elf64-s390.c has its own copy. */ @@ -631,14 +644,16 @@ struct elf_s390_obj_tdata (elf_s390_tdata (abfd)->local_got_tls_type) static bfd_boolean -elf_s390_mkobject (abfd) - bfd *abfd; +elf_s390_mkobject (bfd *abfd) { - bfd_size_type amt = sizeof (struct elf_s390_obj_tdata); - abfd->tdata.any = bfd_zalloc (abfd, amt); if (abfd->tdata.any == NULL) - return FALSE; - return TRUE; + { + bfd_size_type amt = sizeof (struct elf_s390_obj_tdata); + abfd->tdata.any = bfd_zalloc (abfd, amt); + if (abfd->tdata.any == NULL) + return FALSE; + } + return bfd_elf_mkobject (abfd); } static bfd_boolean @@ -1238,7 +1253,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs) if (name == NULL) return FALSE; - if (strncmp (name, ".rela", 5) != 0 + if (! CONST_STRNEQ (name, ".rela") || strcmp (bfd_get_section_name (abfd, sec), name + 5) != 0) { @@ -1345,50 +1360,30 @@ elf_s390_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf_s390_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +elf_s390_gc_mark_hook (asection *sec, + struct bfd_link_info *info, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { if (h != NULL) - { - switch (ELF64_R_TYPE (rel->r_info)) - { - case R_390_GNU_VTINHERIT: - case R_390_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 (ELF64_R_TYPE (rel->r_info)) + { + case R_390_GNU_VTINHERIT: + case R_390_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. */ static bfd_boolean -elf_s390_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +elf_s390_gc_sweep_hook (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1562,7 +1557,6 @@ elf_s390_adjust_dynamic_symbol (info, h) { struct elf_s390_link_hash_table *htab; asection *s; - unsigned int power_of_two; /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later @@ -1683,29 +1677,9 @@ elf_s390_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 = htab->sdynbss; - s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) - { - if (! bfd_set_section_alignment (htab->elf.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); } /* Allocate space in .plt, .got and associated reloc sections for @@ -2098,7 +2072,7 @@ elf_s390_size_dynamic_sections (output_bfd, info) /* Strip this section if we don't need it; see the comment below. */ } - else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) + else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela")) { if (s->size != 0 && s != htab->srelplt) relocs = TRUE; @@ -2240,6 +2214,7 @@ invalid_tls_insn (input_bfd, input_section, rel) input_section, (long) rel->r_offset, howto->name); + bfd_set_error (bfd_error_bad_value); } /* Relocate a 390 ELF section. */ @@ -2263,9 +2238,6 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; - if (info->relocatable) - return TRUE; - htab = elf_s390_hash_table (info); symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; sym_hashes = elf_sym_hashes (input_bfd); @@ -2300,7 +2272,6 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, howto = elf_howto_table + r_type; r_symndx = ELF64_R_SYM (rel->r_info); - /* This is a final link. */ h = NULL; sym = NULL; sec = NULL; @@ -2321,6 +2292,20 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, unresolved_reloc, warned); } + 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_390_GOTPLT12: @@ -2544,11 +2529,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, case R_390_PC32: case R_390_PC32DBL: case R_390_PC64: - /* r_symndx will be 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 ((input_section->flags & SEC_ALLOC) == 0) break; if ((info->shared @@ -2636,14 +2617,19 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, osec = sec->output_section; sindx = elf_section_data (osec)->dynindx; - BFD_ASSERT (sindx > 0); + + if (sindx == 0) + { + osec = htab->elf.text_index_section; + sindx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (sindx != 0); /* We are turning this relocation into one against a section symbol, so subtract out the output section's address but not the offset of the input section in the output section. */ - outrel.r_addend -= osec->vma; } outrel.r_info = ELF64_R_INFO (sindx, r_type); @@ -2908,7 +2894,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, continue; case R_390_TLS_LDO64: - if (info->shared || (input_section->flags & SEC_CODE) == 0) + if (info->shared) relocation -= dtpoff_base (info); else /* When converting LDO to LE, we must negate. */ @@ -3462,6 +3448,7 @@ const struct elf_size_info s390_elf64_size_info = #define bfd_elf64_bfd_is_local_label_name elf_s390_is_local_label_name #define bfd_elf64_bfd_link_hash_table_create elf_s390_link_hash_table_create #define bfd_elf64_bfd_reloc_type_lookup elf_s390_reloc_type_lookup +#define bfd_elf64_bfd_reloc_name_lookup elf_s390_reloc_name_lookup #define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol #define elf_backend_check_relocs elf_s390_check_relocs @@ -3474,6 +3461,7 @@ const struct elf_size_info s390_elf64_size_info = #define elf_backend_reloc_type_class elf_s390_reloc_type_class #define elf_backend_relocate_section elf_s390_relocate_section #define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_reloc_type_class elf_s390_reloc_type_class #define elf_backend_plt_sym_val elf_s390_plt_sym_val |