/* Intel 80386/80486-specific support for 32-bit ELF
- Copyright (C) 1993-2014 Free Software Foundation, Inc.
+ Copyright (C) 1993-2015 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
static reloc_howto_type elf_howto_table[]=
{
- HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ HOWTO(R_386_NONE, 0, 3, 0, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_NONE",
TRUE, 0x00000000, 0x00000000, FALSE),
HOWTO(R_386_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
s = htab->sdynbss;
- return _bfd_elf_adjust_dynamic_copy (h, s);
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
info->flags |= DF_TEXTREL;
- if (info->warn_shared_textrel && info->shared)
- info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"),
+ if ((info->warn_shared_textrel && info->shared)
+ || info->error_textrel)
+ info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'\n"),
p->sec->owner, h->root.root.string,
p->sec);
&& (info->flags & DF_TEXTREL) == 0)
{
info->flags |= DF_TEXTREL;
- if (info->warn_shared_textrel && info->shared)
- info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"),
+ if ((info->warn_shared_textrel && info->shared)
+ || info->error_textrel)
+ info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'\n"),
p->sec->owner, p->sec);
}
}
tlsbase = (struct elf_link_hash_entry *)bh;
tlsbase->def_regular = 1;
tlsbase->other = STV_HIDDEN;
+ tlsbase->root.linker_def = 1;
(*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
}
}
return TRUE;
}
-/* Return address in section PLT for the Ith GOTPLT relocation, for
- relocation REL or (bfd_vma) -1 if it should not be included. */
+/* Return an array of PLT entry symbol values. */
-static bfd_vma
-elf_i386_plt_sym_val (bfd_vma i, const asection *plt, const arelent *rel)
+static bfd_vma *
+elf_i386_get_plt_sym_val (bfd *abfd, asymbol **dynsyms, asection *plt,
+ asection *relplt)
{
- bfd *abfd;
- const struct elf_i386_backend_data *bed;
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ arelent *p;
+ long count, i;
+ bfd_vma *plt_sym_val;
bfd_vma plt_offset;
+ bfd_byte *plt_contents;
+ const struct elf_i386_backend_data *bed
+ = get_elf_i386_backend_data (abfd);
+ Elf_Internal_Shdr *hdr;
+
+ /* Get the .plt section contents. */
+ plt_contents = (bfd_byte *) bfd_malloc (plt->size);
+ if (plt_contents == NULL)
+ return NULL;
+ if (!bfd_get_section_contents (abfd, (asection *) plt,
+ plt_contents, 0, plt->size))
+ {
+bad_return:
+ free (plt_contents);
+ return NULL;
+ }
- /* 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;
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ goto bad_return;
- abfd = plt->owner;
- bed = get_elf_i386_backend_data (abfd);
- plt_offset = bed->plt->plt_entry_size;
+ hdr = &elf_section_data (relplt)->this_hdr;
+ count = relplt->size / hdr->sh_entsize;
+
+ plt_sym_val = (bfd_vma *) bfd_malloc (sizeof (bfd_vma) * count);
+ if (plt_sym_val == NULL)
+ goto bad_return;
- if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_GNU)
- return plt->vma + (i + 1) * plt_offset;
+ for (i = 0; i < count; i++)
+ plt_sym_val[i] = -1;
- while (plt_offset < plt->size)
+ plt_offset = bed->plt->plt_entry_size;
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p++)
{
- 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;
+ long reloc_index;
+
+ /* Skip unknown relocation. PR 17512: file: bc9d6cf5. */
+ if (p->howto == NULL)
+ continue;
+
+ if (p->howto->type != R_386_JUMP_SLOT
+ && p->howto->type != R_386_IRELATIVE)
+ continue;
+
+ reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset
+ + bed->plt->plt_reloc_offset));
+ reloc_index /= sizeof (Elf32_External_Rel);
+ if (reloc_index >= count)
+ abort ();
+ plt_sym_val[reloc_index] = plt->vma + plt_offset;
plt_offset += bed->plt->plt_entry_size;
}
- abort ();
+ free (plt_contents);
+
+ return plt_sym_val;
+}
+
+/* Similar to _bfd_elf_get_synthetic_symtab. */
+
+static long
+elf_i386_get_synthetic_symtab (bfd *abfd,
+ long symcount,
+ asymbol **syms,
+ long dynsymcount,
+ asymbol **dynsyms,
+ asymbol **ret)
+{
+ asection *plt = bfd_get_section_by_name (abfd, ".plt");
+ return _bfd_elf_ifunc_get_synthetic_symtab (abfd, symcount, syms,
+ dynsymcount, dynsyms, ret,
+ plt,
+ elf_i386_get_plt_sym_val);
}
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
#define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create
#define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup
+#define bfd_elf32_get_synthetic_symtab elf_i386_get_synthetic_symtab
#define elf_backend_adjust_dynamic_symbol elf_i386_adjust_dynamic_symbol
#define elf_backend_relocs_compatible _bfd_elf_relocs_compatible
#define elf_backend_always_size_sections elf_i386_always_size_sections
#define elf_backend_omit_section_dynsym \
((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
-#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