static bfd_boolean
elf_i386_mkobject (bfd *abfd)
{
- bfd_size_type amt = sizeof (struct elf_i386_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_i386_obj_tdata);
+ abfd->tdata.any = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.any == NULL)
+ return FALSE;
+ }
+ return bfd_elf_mkobject (abfd);
}
/* i386 ELF linker hash table. */
/* Value used to fill the last word of the first plt entry. */
bfd_byte plt0_pad_byte;
+ /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. */
+ bfd_vma next_tls_desc_index;
+
union {
bfd_signed_vma refcount;
bfd_vma offset;
((struct elf_i386_link_hash_table *) ((p)->hash))
#define elf_i386_compute_jump_table_size(htab) \
- ((htab)->srelplt->reloc_count * 4)
+ ((htab)->next_tls_desc_index * 4)
/* Create an entry in an i386 ELF linker hash table. */
if (ret == NULL)
return NULL;
- if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc))
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+ sizeof (struct elf_i386_link_hash_entry)))
{
free (ret);
return NULL;
ret->sdynbss = NULL;
ret->srelbss = NULL;
ret->tls_ldm_got.refcount = 0;
+ ret->next_tls_desc_index = 0;
ret->sgotplt_jump_table_size = 0;
ret->sym_sec.abfd = NULL;
ret->is_vxworks = 0;
elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
{
struct elf_i386_link_hash_table *htab;
- asection * s;
- int flags;
- const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
htab = elf_i386_hash_table (info);
if (!htab->sgot && !create_got_section (dynobj, info))
|| (!info->shared && !htab->srelbss))
abort ();
- if (htab->is_vxworks && !info->shared)
- {
- s = bfd_make_section (dynobj, ".rel.plt.unloaded");
- flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY
- | SEC_LINKER_CREATED);
- if (s == NULL
- || ! bfd_set_section_flags (dynobj, s, flags)
- || ! bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
- return FALSE;
- htab->srelplt2 = s;
- }
+ if (htab->is_vxworks
+ && !elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
+ return FALSE;
return TRUE;
}
/* We also need to make an entry in the .rel.plt section. */
htab->srelplt->size += sizeof (Elf32_External_Rel);
- htab->srelplt->reloc_count++;
+ htab->next_tls_desc_index++;
if (htab->is_vxworks && !info->shared)
{
else
htab->tls_ldm_got.offset = -1;
- if (htab->is_vxworks)
- {
- /* Mark the GOT and PLT symbols as having relocations; they might
- not, but we won't know for sure until we build the GOT in
- finish_dynamic_symbol. */
- if (htab->elf.hgot)
- htab->elf.hgot->indx = -2;
- if (htab->elf.hplt)
- {
- htab->elf.hplt->indx = -2;
- if (htab->splt->flags & SEC_CODE)
- htab->elf.hplt->type = STT_FUNC;
- }
- }
-
/* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
for them, it suffices to multiply the reloc count by the jump
slot size. */
if (htab->srelplt)
- htab->sgotplt_jump_table_size = htab->srelplt->reloc_count * 4;
+ htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4;
/* We now have determined the sizes of the various dynamic sections.
Allocate memory for them. */
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
- if (s != htab->srelplt)
- s->reloc_count = 0;
+ s->reloc_count = 0;
}
else
{
val = bfd_get_8 (input_bfd, contents + roff + 1);
BFD_ASSERT (val == 0x10);
- /* Now modify the instruction as appropriate. */
- bfd_put_8 (output_bfd, 0x90, contents + roff);
+ /* Now modify the instruction as appropriate. Use
+ xchg %ax,%ax instead of 2 nops. */
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
continue;
}
+ htab->sgotplt_jump_table_size);
sreloc = htab->srelplt;
loc = sreloc->contents;
- loc += sreloc->reloc_count++
- * sizeof (Elf32_External_Rel);
+ loc += (htab->next_tls_desc_index++
+ * sizeof (Elf32_External_Rel));
BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
<= sreloc->contents + sreloc->size);
bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
subl $foo@gottpoff(%reg), %eax
into:
addl $foo@gotntpoff(%reg), %eax. */
- if (r_type == R_386_TLS_GOTIE)
- {
- contents[roff + 6] = 0x03;
- if (tls_type == GOT_TLS_IE_BOTH)
- off += 4;
- }
+ if (tls_type == GOT_TLS_IE_POS)
+ contents[roff + 6] = 0x03;
bfd_put_32 (output_bfd,
htab->sgot->output_section->vma
+ htab->sgot->output_offset + off
/* Now modify the instruction as appropriate. */
if (tls_type != GOT_TLS_IE_NEG)
{
- /* nop; nop */
- bfd_put_8 (output_bfd, 0x90, contents + roff);
+ /* xchg %ax,%ax */
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
}
else
return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
}
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+
+static bfd_boolean
+elf_i386_hash_symbol (struct elf_link_hash_entry *h)
+{
+ if (h->plt.offset != (bfd_vma) -1
+ && !h->def_regular
+ && !h->pointer_equality_needed)
+ return FALSE;
+
+ return _bfd_elf_hash_symbol (h);
+}
#define TARGET_LITTLE_SYM bfd_elf32_i386_vec
#define TARGET_LITTLE_NAME "elf32-i386"
#define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections
#define elf_backend_always_size_sections elf_i386_always_size_sections
#define elf_backend_plt_sym_val elf_i386_plt_sym_val
+#define elf_backend_hash_symbol elf_i386_hash_symbol
#include "elf32-target.h"
}
-/* Tweak magic VxWorks symbols as they are written to the output file. */
-static bfd_boolean
-elf_i386_vxworks_link_output_symbol_hook (struct bfd_link_info *info
- ATTRIBUTE_UNUSED,
- const char *name,
- Elf_Internal_Sym *sym,
- asection *input_sec ATTRIBUTE_UNUSED,
- struct elf_link_hash_entry *h
- ATTRIBUTE_UNUSED)
-{
- /* Ignore the first dummy symbol. */
- if (!name)
- return TRUE;
-
- return elf_vxworks_link_output_symbol_hook (name, sym);
-}
-
#undef elf_backend_post_process_headers
#undef bfd_elf32_bfd_link_hash_table_create
#define bfd_elf32_bfd_link_hash_table_create \
elf_vxworks_add_symbol_hook
#undef elf_backend_link_output_symbol_hook
#define elf_backend_link_output_symbol_hook \
- elf_i386_vxworks_link_output_symbol_hook
+ elf_vxworks_link_output_symbol_hook
#undef elf_backend_emit_relocs
#define elf_backend_emit_relocs elf_vxworks_emit_relocs
#undef elf_backend_final_write_processing