== 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. */
/* 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;
/* STT_GNU_IFUNC must keep R_386_GOT32 relocation. */
if (ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC
+ && irel->r_offset >= 2
&& bfd_get_8 (input_bfd,
contents + irel->r_offset - 2) == 0x8b)
{
&& h->type != STT_GNU_IFUNC
&& h != htab->elf.hdynamic
&& SYMBOL_REFERENCES_LOCAL (link_info, h)
+ && irel->r_offset >= 2
&& bfd_get_8 (input_bfd,
contents + irel->r_offset - 2) == 0x8b)
{
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. */
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;
_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
}