diff options
Diffstat (limited to 'binutils-2.25/bfd/elf32-i386.c')
-rw-r--r-- | binutils-2.25/bfd/elf32-i386.c | 134 |
1 files changed, 88 insertions, 46 deletions
diff --git a/binutils-2.25/bfd/elf32-i386.c b/binutils-2.25/bfd/elf32-i386.c index 560e05cc..ad8b5575 100644 --- a/binutils-2.25/bfd/elf32-i386.c +++ b/binutils-2.25/bfd/elf32-i386.c @@ -1,7 +1,5 @@ /* Intel 80386/80486-specific support for 32-bit ELF - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 - Free Software Foundation, Inc. + Copyright (C) 1993-2014 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -828,7 +826,7 @@ struct elf_i386_link_hash_table == I386_ELF_DATA ? ((struct elf_i386_link_hash_table *) ((p)->hash)) : NULL) #define elf_i386_compute_jump_table_size(htab) \ - ((htab)->next_tls_desc_index * 4) + ((htab)->elf.srelplt->reloc_count * 4) /* Create an entry in an i386 ELF linker hash table. */ @@ -929,6 +927,21 @@ elf_i386_get_local_sym_hash (struct elf_i386_link_hash_table *htab, return &ret->elf; } +/* Destroy an i386 ELF linker hash table. */ + +static void +elf_i386_link_hash_table_free (bfd *obfd) +{ + struct elf_i386_link_hash_table *htab + = (struct elf_i386_link_hash_table *) obfd->link.hash; + + if (htab->loc_hash_table) + htab_delete (htab->loc_hash_table); + if (htab->loc_hash_memory) + objalloc_free ((struct objalloc *) htab->loc_hash_memory); + _bfd_elf_link_hash_table_free (obfd); +} + /* Create an i386 ELF linker hash table. */ static struct bfd_link_hash_table * @@ -957,28 +970,14 @@ elf_i386_link_hash_table_create (bfd *abfd) ret->loc_hash_memory = objalloc_create (); if (!ret->loc_hash_table || !ret->loc_hash_memory) { - free (ret); + elf_i386_link_hash_table_free (abfd); return NULL; } + ret->elf.root.hash_table_free = elf_i386_link_hash_table_free; return &ret->elf.root; } -/* Destroy an i386 ELF linker hash table. */ - -static void -elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash) -{ - struct elf_i386_link_hash_table *htab - = (struct elf_i386_link_hash_table *) hash; - - if (htab->loc_hash_table) - htab_delete (htab->loc_hash_table); - if (htab->loc_hash_memory) - objalloc_free ((struct objalloc *) htab->loc_hash_memory); - _bfd_elf_link_hash_table_free (hash); -} - /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and .rel.bss sections in DYNOBJ, and set up shortcuts to them in our hash table. */ @@ -2219,7 +2218,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* If this is the first .plt entry, make room for the special first entry. */ if (s->size == 0) - s->size += plt_entry_size; + s->size = plt_entry_size; h->plt.offset = s->size; @@ -2534,7 +2533,7 @@ elf_i386_convert_mov_to_lea (bfd *abfd, asection *sec, /* Nothing to do if there are no codes, no relocations or no output. */ if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC) || sec->reloc_count == 0 - || discarded_section (sec)) + || bfd_is_abs_section (sec->output_section)) return TRUE; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; @@ -2688,7 +2687,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) /* Set up .got offsets for local syms, and space for local dynamic relocs. */ - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) { bfd_signed_vma *local_got; bfd_signed_vma *end_local_got; @@ -3311,11 +3310,12 @@ elf_i386_relocate_section (bfd *output_bfd, else { bfd_boolean warned ATTRIBUTE_UNUSED; + bfd_boolean ignored ATTRIBUTE_UNUSED; RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, r_symndx, symtab_hdr, sym_hashes, h, sec, relocation, - unresolved_reloc, warned); + unresolved_reloc, warned, ignored); st_size = h->size; } @@ -4976,14 +4976,46 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, return TRUE; } -/* Return address for Ith PLT stub in section PLT, for relocation REL - or (bfd_vma) -1 if it should not be included. */ +/* Return address in section PLT for the Ith GOTPLT relocation, for + relocation REL or (bfd_vma) -1 if it should not be included. */ static bfd_vma -elf_i386_plt_sym_val (bfd_vma i, const asection *plt, - const arelent *rel ATTRIBUTE_UNUSED) +elf_i386_plt_sym_val (bfd_vma i, const asection *plt, const arelent *rel) { - return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner); + bfd *abfd; + const struct elf_i386_backend_data *bed; + bfd_vma plt_offset; + + /* Only match R_386_JUMP_SLOT and R_386_IRELATIVE. */ + if (rel->howto->type != R_386_JUMP_SLOT + && rel->howto->type != R_386_IRELATIVE) + return (bfd_vma) -1; + + abfd = plt->owner; + bed = get_elf_i386_backend_data (abfd); + plt_offset = bed->plt->plt_entry_size; + + if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_GNU) + return plt->vma + (i + 1) * plt_offset; + + while (plt_offset < plt->size) + { + bfd_vma reloc_offset; + bfd_byte reloc_offset_raw[4]; + + if (!bfd_get_section_contents (abfd, (asection *) plt, + reloc_offset_raw, + plt_offset + bed->plt->plt_reloc_offset, + sizeof (reloc_offset_raw))) + return (bfd_vma) -1; + + reloc_offset = H_GET_32 (abfd, reloc_offset_raw); + if (reloc_offset == i * sizeof (Elf32_External_Rel)) + return plt->vma + plt_offset; + plt_offset += bed->plt->plt_entry_size; + } + + abort (); } /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ @@ -5004,22 +5036,23 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h) static bfd_boolean elf_i386_add_symbol_hook (bfd * abfd, - struct bfd_link_info * info ATTRIBUTE_UNUSED, + struct bfd_link_info * info, Elf_Internal_Sym * sym, const char ** namep ATTRIBUTE_UNUSED, flagword * flagsp ATTRIBUTE_UNUSED, asection ** secp ATTRIBUTE_UNUSED, bfd_vma * valp ATTRIBUTE_UNUSED) { - if ((abfd->flags & DYNAMIC) == 0 - && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC - || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)) + if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC + || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE) + && (abfd->flags & DYNAMIC) == 0 + && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour) elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE; return TRUE; } -#define TARGET_LITTLE_SYM bfd_elf32_i386_vec +#define TARGET_LITTLE_SYM i386_elf32_vec #define TARGET_LITTLE_NAME "elf32-i386" #define ELF_ARCH bfd_arch_i386 #define ELF_TARGET_ID I386_ELF_DATA @@ -5042,7 +5075,6 @@ elf_i386_add_symbol_hook (bfd * abfd, #define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name #define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_free elf_i386_link_hash_table_free #define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup #define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup @@ -5067,15 +5099,13 @@ elf_i386_add_symbol_hook (bfd * abfd, #define elf_backend_plt_sym_val elf_i386_plt_sym_val #define elf_backend_hash_symbol elf_i386_hash_symbol #define elf_backend_add_symbol_hook elf_i386_add_symbol_hook -#undef elf_backend_post_process_headers -#define elf_backend_post_process_headers _bfd_elf_set_osabi #include "elf32-target.h" /* FreeBSD support. */ #undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_freebsd_vec +#define TARGET_LITTLE_SYM i386_elf32_fbsd_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-i386-freebsd" #undef ELF_OSABI @@ -5088,11 +5118,14 @@ elf_i386_add_symbol_hook (bfd * abfd, static void elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) { - _bfd_elf_set_osabi (abfd, info); + _bfd_elf_post_process_headers (abfd, info); #ifdef OLD_FREEBSD_ABI_LABEL - /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ - memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); + { + /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ + Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); + memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); + } #endif } @@ -5108,7 +5141,7 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) /* Solaris 2. */ #undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_sol2_vec +#define TARGET_LITTLE_SYM i386_elf32_sol2_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-i386-sol2" @@ -5136,7 +5169,7 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) /* Native Client support. */ #undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_nacl_vec +#define TARGET_LITTLE_SYM i386_elf32_nacl_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-i386-nacl" #undef elf32_bed @@ -5150,7 +5183,6 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) #undef elf_backend_want_plt_sym #define elf_backend_want_plt_sym 0 #undef elf_backend_post_process_headers -#define elf_backend_post_process_headers _bfd_elf_set_osabi #undef elf_backend_static_tls_alignment /* NaCl uses substantially different PLT entries for the same effects. */ @@ -5295,9 +5327,19 @@ static const struct elf_i386_backend_data elf_i386_nacl_arch_bed = 0, /* is_vxworks */ }; +static bfd_boolean +elf32_i386_nacl_elf_object_p (bfd *abfd) +{ + /* Set the right machine number for a NaCl i386 ELF32 file. */ + bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386_nacl); + return TRUE; +} + #undef elf_backend_arch_data #define elf_backend_arch_data &elf_i386_nacl_arch_bed +#undef elf_backend_object_p +#define elf_backend_object_p elf32_i386_nacl_elf_object_p #undef elf_backend_modify_segment_map #define elf_backend_modify_segment_map nacl_modify_segment_map #undef elf_backend_modify_program_headers @@ -5308,6 +5350,7 @@ static const struct elf_i386_backend_data elf_i386_nacl_arch_bed = #include "elf32-target.h" /* Restore defaults. */ +#undef elf_backend_object_p #undef elf_backend_modify_segment_map #undef elf_backend_modify_program_headers #undef elf_backend_final_write_processing @@ -5315,7 +5358,7 @@ static const struct elf_i386_backend_data elf_i386_nacl_arch_bed = /* VxWorks support. */ #undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_vxworks_vec +#define TARGET_LITTLE_SYM i386_elf32_vxworks_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-i386-vxworks" #undef ELF_OSABI @@ -5333,7 +5376,6 @@ static const struct elf_i386_backend_data elf_i386_vxworks_arch_bed = #define elf_backend_arch_data &elf_i386_vxworks_arch_bed #undef elf_backend_relocs_compatible -#undef elf_backend_post_process_headers #undef elf_backend_add_symbol_hook #define elf_backend_add_symbol_hook \ elf_vxworks_add_symbol_hook |