OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-i386.c] - Diff between revs 148 and 161

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 148 Rev 161
Line 27... Line 27...
#include "elf-bfd.h"
#include "elf-bfd.h"
#include "elf-vxworks.h"
#include "elf-vxworks.h"
#include "bfd_stdint.h"
#include "bfd_stdint.h"
#include "objalloc.h"
#include "objalloc.h"
#include "hashtab.h"
#include "hashtab.h"
 
#include "dwarf2.h"
 
 
/* 386 uses REL relocations instead of RELA.  */
/* 386 uses REL relocations instead of RELA.  */
#define USE_REL 1
#define USE_REL 1
 
 
#include "elf/i386.h"
#include "elf/i386.h"
Line 572... Line 573...
  0, 0, 0, 0,       /* replaced with offset into relocation table.  */
  0, 0, 0, 0,       /* replaced with offset into relocation table.  */
  0xe9,         /* jmp relative */
  0xe9,         /* jmp relative */
  0, 0, 0, 0        /* replaced with offset to start of .plt.  */
  0, 0, 0, 0        /* replaced with offset to start of .plt.  */
};
};
 
 
 
/* .eh_frame covering the .plt section.  */
 
 
 
static const bfd_byte elf_i386_eh_frame_plt[] =
 
{
 
#define PLT_CIE_LENGTH          20
 
#define PLT_FDE_LENGTH          36
 
#define PLT_FDE_START_OFFSET    4 + PLT_CIE_LENGTH + 8
 
#define PLT_FDE_LEN_OFFSET      4 + PLT_CIE_LENGTH + 12
 
  PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
 
  0, 0, 0, 0,                       /* CIE ID */
 
  1,                            /* CIE version */
 
  'z', 'R', 0,                   /* Augmentation string */
 
  1,                            /* Code alignment factor */
 
  0x7c,                         /* Data alignment factor */
 
  8,                            /* Return address column */
 
  1,                            /* Augmentation size */
 
  DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
 
  DW_CFA_def_cfa, 4, 4,         /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
 
  DW_CFA_offset + 8, 1,         /* DW_CFA_offset: r8 (eip) at cfa-4 */
 
  DW_CFA_nop, DW_CFA_nop,
 
 
 
  PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
 
  PLT_CIE_LENGTH + 8, 0, 0, 0,     /* CIE pointer */
 
  0, 0, 0, 0,                       /* R_386_PC32 .plt goes here */
 
  0, 0, 0, 0,                       /* .plt size goes here */
 
  0,                             /* Augmentation size */
 
  DW_CFA_def_cfa_offset, 8,     /* DW_CFA_def_cfa_offset: 8 */
 
  DW_CFA_advance_loc + 6,       /* DW_CFA_advance_loc: 6 to __PLT__+6 */
 
  DW_CFA_def_cfa_offset, 12,    /* DW_CFA_def_cfa_offset: 12 */
 
  DW_CFA_advance_loc + 10,      /* DW_CFA_advance_loc: 10 to __PLT__+16 */
 
  DW_CFA_def_cfa_expression,    /* DW_CFA_def_cfa_expression */
 
  11,                           /* Block length */
 
  DW_OP_breg4, 4,               /* DW_OP_breg4 (esp): 4 */
 
  DW_OP_breg8, 0,                /* DW_OP_breg8 (eip): 0 */
 
  DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
 
  DW_OP_lit2, DW_OP_shl, DW_OP_plus,
 
  DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
 
};
 
 
 
struct elf_i386_plt_layout
 
{
 
  /* The first entry in an absolute procedure linkage table looks like this.  */
 
  const bfd_byte *plt0_entry;
 
  unsigned int plt0_entry_size;
 
 
 
  /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2].  */
 
  unsigned int plt0_got1_offset;
 
  unsigned int plt0_got2_offset;
 
 
 
  /* Later entries in an absolute procedure linkage table look like this.  */
 
  const bfd_byte *plt_entry;
 
  unsigned int plt_entry_size;
 
 
 
  /* Offsets into plt_entry that are to be replaced with...  */
 
  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
 
  unsigned int plt_reloc_offset;  /* ... offset into relocation table. */
 
  unsigned int plt_plt_offset;    /* ... offset to start of .plt. */
 
 
 
  /* Offset into plt_entry where the initial value of the GOT entry points.  */
 
  unsigned int plt_lazy_offset;
 
 
 
  /* The first entry in a PIC procedure linkage table looks like this.  */
 
  const bfd_byte *pic_plt0_entry;
 
 
 
  /* Subsequent entries in a PIC procedure linkage table look like this.  */
 
  const bfd_byte *pic_plt_entry;
 
 
 
  /* .eh_frame covering the .plt section.  */
 
  const bfd_byte *eh_frame_plt;
 
  unsigned int eh_frame_plt_size;
 
};
 
 
 
#define GET_PLT_ENTRY_SIZE(abfd) \
 
  get_elf_i386_backend_data (abfd)->plt->plt_entry_size
 
 
 
/* These are the standard parameters.  */
 
static const struct elf_i386_plt_layout elf_i386_plt =
 
  {
 
    elf_i386_plt0_entry,                /* plt0_entry */
 
    sizeof (elf_i386_plt0_entry),       /* plt0_entry_size */
 
    2,                                  /* plt0_got1_offset */
 
    8,                                  /* plt0_got2_offset */
 
    elf_i386_plt_entry,                 /* plt_entry */
 
    PLT_ENTRY_SIZE,                     /* plt_entry_size */
 
    2,                                  /* plt_got_offset */
 
    7,                                  /* plt_reloc_offset */
 
    12,                                 /* plt_plt_offset */
 
    6,                                  /* plt_lazy_offset */
 
    elf_i386_pic_plt0_entry,            /* pic_plt0_entry */
 
    elf_i386_pic_plt_entry,             /* pic_plt_entry */
 
    elf_i386_eh_frame_plt,              /* eh_frame_plt */
 
    sizeof (elf_i386_eh_frame_plt),     /* eh_frame_plt_size */
 
  };
 

 
 
/* On VxWorks, the .rel.plt.unloaded section has absolute relocations
/* On VxWorks, the .rel.plt.unloaded section has absolute relocations
   for the PLTResolve stub and then for each PLT entry.  */
   for the PLTResolve stub and then for each PLT entry.  */
#define PLTRESOLVE_RELOCS_SHLIB 0
#define PLTRESOLVE_RELOCS_SHLIB 0
#define PLTRESOLVE_RELOCS 2
#define PLTRESOLVE_RELOCS 2
#define PLT_NON_JUMP_SLOT_RELOCS 2
#define PLT_NON_JUMP_SLOT_RELOCS 2
 
 
 
/* Architecture-specific backend data for i386.  */
 
 
 
struct elf_i386_backend_data
 
{
 
  /* Parameters describing PLT generation.  */
 
  const struct elf_i386_plt_layout *plt;
 
 
 
  /* Value used to fill the unused bytes of the first PLT entry.  */
 
  bfd_byte plt0_pad_byte;
 
 
 
  /* True if the target system is VxWorks.  */
 
  int is_vxworks;
 
};
 
 
 
#define get_elf_i386_backend_data(abfd) \
 
  ((const struct elf_i386_backend_data *) \
 
   get_elf_backend_data (abfd)->arch_data)
 
 
 
/* These are the standard parameters.  */
 
static const struct elf_i386_backend_data elf_i386_arch_bed =
 
  {
 
    &elf_i386_plt,                      /* plt */
 
    0,                                  /* plt0_pad_byte */
 
    0,                                  /* is_vxworks */
 
  };
 
 
 
#define elf_backend_arch_data   &elf_i386_arch_bed
 
 
/* i386 ELF linker hash entry.  */
/* i386 ELF linker hash entry.  */
 
 
struct elf_i386_link_hash_entry
struct elf_i386_link_hash_entry
{
{
  struct elf_link_hash_entry elf;
  struct elf_link_hash_entry elf;
Line 653... Line 777...
  struct elf_link_hash_table elf;
  struct elf_link_hash_table elf;
 
 
  /* Short-cuts to get to dynamic linker sections.  */
  /* Short-cuts to get to dynamic linker sections.  */
  asection *sdynbss;
  asection *sdynbss;
  asection *srelbss;
  asection *srelbss;
 
  asection *plt_eh_frame;
 
 
  union
  union
  {
  {
    bfd_signed_vma refcount;
    bfd_signed_vma refcount;
    bfd_vma offset;
    bfd_vma offset;
Line 677... Line 802...
  void * loc_hash_memory;
  void * loc_hash_memory;
 
 
  /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
  /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
  asection *srelplt2;
  asection *srelplt2;
 
 
  /* True if the target system is VxWorks.  */
 
  int is_vxworks;
 
 
 
  /* The index of the next unused R_386_TLS_DESC slot in .rel.plt.  */
  /* The index of the next unused R_386_TLS_DESC slot in .rel.plt.  */
  bfd_vma next_tls_desc_index;
  bfd_vma next_tls_desc_index;
 
 
  /* Value used to fill the last word of the first plt entry.  */
 
  bfd_byte plt0_pad_byte;
 
};
};
 
 
/* Get the i386 ELF linker hash table from a link_info structure.  */
/* Get the i386 ELF linker hash table from a link_info structure.  */
 
 
#define elf_i386_hash_table(p) \
#define elf_i386_hash_table(p) \
Line 818... Line 937...
      return NULL;
      return NULL;
    }
    }
 
 
  ret->sdynbss = NULL;
  ret->sdynbss = NULL;
  ret->srelbss = NULL;
  ret->srelbss = NULL;
 
  ret->plt_eh_frame = NULL;
  ret->tls_ldm_got.refcount = 0;
  ret->tls_ldm_got.refcount = 0;
  ret->next_tls_desc_index = 0;
  ret->next_tls_desc_index = 0;
  ret->sgotplt_jump_table_size = 0;
  ret->sgotplt_jump_table_size = 0;
  ret->sym_cache.abfd = NULL;
  ret->sym_cache.abfd = NULL;
  ret->is_vxworks = 0;
 
  ret->srelplt2 = NULL;
  ret->srelplt2 = NULL;
  ret->plt0_pad_byte = 0;
 
  ret->tls_module_base = NULL;
  ret->tls_module_base = NULL;
 
 
  ret->loc_hash_table = htab_try_create (1024,
  ret->loc_hash_table = htab_try_create (1024,
                                         elf_i386_local_htab_hash,
                                         elf_i386_local_htab_hash,
                                         elf_i386_local_htab_eq,
                                         elf_i386_local_htab_eq,
Line 880... Line 998...
 
 
  if (!htab->sdynbss
  if (!htab->sdynbss
      || (!info->shared && !htab->srelbss))
      || (!info->shared && !htab->srelbss))
    abort ();
    abort ();
 
 
  if (htab->is_vxworks
  if (get_elf_i386_backend_data (dynobj)->is_vxworks
      && !elf_vxworks_create_dynamic_sections (dynobj, info,
      && !elf_vxworks_create_dynamic_sections (dynobj, info,
                                               &htab->srelplt2))
                                               &htab->srelplt2))
    return FALSE;
    return FALSE;
 
 
 
  if (!info->no_ld_generated_unwind_info
 
      && bfd_get_section_by_name (dynobj, ".eh_frame") == NULL
 
      && htab->elf.splt != NULL)
 
    {
 
      flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
 
      htab->plt_eh_frame
 
        = bfd_make_section_with_flags (dynobj, ".eh_frame",
 
                                       flags | SEC_READONLY);
 
      if (htab->plt_eh_frame == NULL
 
          || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2))
 
        return FALSE;
 
 
 
      htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt);
 
      htab->plt_eh_frame->contents
 
        = bfd_alloc (dynobj, htab->plt_eh_frame->size);
 
      memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt,
 
              sizeof (elf_i386_eh_frame_plt));
 
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Copy the extra info we tack onto an elf_link_hash_entry.  */
/* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 
Line 2016... Line 2153...
 
 
  /* If there aren't any dynamic relocs in read-only sections, then
  /* If there aren't any dynamic relocs in read-only sections, then
     we can keep the dynamic relocs and avoid the copy reloc.  This
     we can keep the dynamic relocs and avoid the copy reloc.  This
     doesn't work on VxWorks, where we can not have dynamic relocations
     doesn't work on VxWorks, where we can not have dynamic relocations
     (other than copy and jump slot relocations) in an executable.  */
     (other than copy and jump slot relocations) in an executable.  */
  if (ELIMINATE_COPY_RELOCS && !htab->is_vxworks)
  if (ELIMINATE_COPY_RELOCS
 
      && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
    {
    {
      struct elf_i386_link_hash_entry * eh;
      struct elf_i386_link_hash_entry * eh;
      struct elf_dyn_relocs *p;
      struct elf_dyn_relocs *p;
 
 
      eh = (struct elf_i386_link_hash_entry *) h;
      eh = (struct elf_i386_link_hash_entry *) h;
Line 2077... Line 2215...
{
{
  struct bfd_link_info *info;
  struct bfd_link_info *info;
  struct elf_i386_link_hash_table *htab;
  struct elf_i386_link_hash_table *htab;
  struct elf_i386_link_hash_entry *eh;
  struct elf_i386_link_hash_entry *eh;
  struct elf_dyn_relocs *p;
  struct elf_dyn_relocs *p;
 
  unsigned plt_entry_size;
 
 
  if (h->root.type == bfd_link_hash_indirect)
  if (h->root.type == bfd_link_hash_indirect)
    return TRUE;
    return TRUE;
 
 
  eh = (struct elf_i386_link_hash_entry *) h;
  eh = (struct elf_i386_link_hash_entry *) h;
Line 2088... Line 2227...
  info = (struct bfd_link_info *) inf;
  info = (struct bfd_link_info *) inf;
  htab = elf_i386_hash_table (info);
  htab = elf_i386_hash_table (info);
  if (htab == NULL)
  if (htab == NULL)
    return FALSE;
    return FALSE;
 
 
 
  plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
 
 
  /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
  /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
     here if it is defined and referenced in a non-shared object.  */
     here if it is defined and referenced in a non-shared object.  */
  if (h->type == STT_GNU_IFUNC
  if (h->type == STT_GNU_IFUNC
      && h->def_regular)
      && h->def_regular)
    return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
    return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
                                               &eh->dyn_relocs,
                                               plt_entry_size, 4);
                                               PLT_ENTRY_SIZE, 4);
 
  else if (htab->elf.dynamic_sections_created
  else if (htab->elf.dynamic_sections_created
           && h->plt.refcount > 0)
           && h->plt.refcount > 0)
    {
    {
      /* Make sure this symbol is output as a dynamic symbol.
      /* Make sure this symbol is output as a dynamic symbol.
         Undefined weak syms won't yet be marked as dynamic.  */
         Undefined weak syms won't yet be marked as dynamic.  */
Line 2115... Line 2255...
          asection *s = htab->elf.splt;
          asection *s = htab->elf.splt;
 
 
          /* If this is the first .plt entry, make room for the special
          /* If this is the first .plt entry, make room for the special
             first entry.  */
             first entry.  */
          if (s->size == 0)
          if (s->size == 0)
            s->size += PLT_ENTRY_SIZE;
            s->size += plt_entry_size;
 
 
          h->plt.offset = s->size;
          h->plt.offset = s->size;
 
 
          /* If this symbol is not defined in a regular file, and we are
          /* If this symbol is not defined in a regular file, and we are
             not generating a shared library, then set the symbol to this
             not generating a shared library, then set the symbol to this
Line 2132... Line 2272...
              h->root.u.def.section = s;
              h->root.u.def.section = s;
              h->root.u.def.value = h->plt.offset;
              h->root.u.def.value = h->plt.offset;
            }
            }
 
 
          /* Make room for this entry.  */
          /* Make room for this entry.  */
          s->size += PLT_ENTRY_SIZE;
          s->size += plt_entry_size;
 
 
          /* We also need to make an entry in the .got.plt section, which
          /* We also need to make an entry in the .got.plt section, which
             will be placed in the .got section by the linker script.  */
             will be placed in the .got section by the linker script.  */
          htab->elf.sgotplt->size += 4;
          htab->elf.sgotplt->size += 4;
 
 
          /* We also need to make an entry in the .rel.plt section.  */
          /* We also need to make an entry in the .rel.plt section.  */
          htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
          htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
          htab->next_tls_desc_index++;
          htab->next_tls_desc_index++;
 
 
          if (htab->is_vxworks && !info->shared)
          if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks
 
              && !info->shared)
            {
            {
              /* VxWorks has a second set of relocations for each PLT entry
              /* VxWorks has a second set of relocations for each PLT entry
                 in executables.  They go in a separate relocation section,
                 in executables.  They go in a separate relocation section,
                 which is processed by the kernel loader.  */
                 which is processed by the kernel loader.  */
 
 
              /* There are two relocations for the initial PLT entry: an
              /* There are two relocations for the initial PLT entry: an
                 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
                 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
                 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
                 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
 
 
              if (h->plt.offset == PLT_ENTRY_SIZE)
              if (h->plt.offset == plt_entry_size)
                htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
                htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
 
 
              /* There are two extra relocations for each subsequent PLT entry:
              /* There are two extra relocations for each subsequent PLT entry:
                 an R_386_32 relocation for the GOT entry, and an R_386_32
                 an R_386_32 relocation for the GOT entry, and an R_386_32
                 relocation for the PLT entry.  */
                 relocation for the PLT entry.  */
Line 2272... Line 2413...
              else
              else
                pp = &p->next;
                pp = &p->next;
            }
            }
        }
        }
 
 
      if (htab->is_vxworks)
      if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
        {
        {
          struct elf_dyn_relocs **pp;
          struct elf_dyn_relocs **pp;
          for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
          for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
            {
            {
              if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
              if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
Line 2406... Line 2547...
}
}
 
 
/* Set the sizes of the dynamic sections.  */
/* Set the sizes of the dynamic sections.  */
 
 
static bfd_boolean
static bfd_boolean
elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
                                struct bfd_link_info *info)
 
{
{
  struct elf_i386_link_hash_table *htab;
  struct elf_i386_link_hash_table *htab;
  bfd *dynobj;
  bfd *dynobj;
  asection *s;
  asection *s;
  bfd_boolean relocs;
  bfd_boolean relocs;
Line 2467... Line 2607...
                  /* Input section has been discarded, either because
                  /* Input section has been discarded, either because
                     it is a copy of a linkonce section or due to
                     it is a copy of a linkonce section or due to
                     linker script /DISCARD/, so we'll be discarding
                     linker script /DISCARD/, so we'll be discarding
                     the relocs too.  */
                     the relocs too.  */
                }
                }
              else if (htab->is_vxworks
              else if (get_elf_i386_backend_data (output_bfd)->is_vxworks
                       && strcmp (p->sec->output_section->name,
                       && strcmp (p->sec->output_section->name,
                                  ".tls_vars") == 0)
                                  ".tls_vars") == 0)
                {
                {
                  /* Relocations in vxworks .tls_vars sections are
                  /* Relocations in vxworks .tls_vars sections are
                     handled specially by the loader.  */
                     handled specially by the loader.  */
Line 2665... Line 2805...
      s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
      s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
      if (s->contents == NULL)
      if (s->contents == NULL)
        return FALSE;
        return FALSE;
    }
    }
 
 
 
  if (htab->plt_eh_frame != NULL
 
      && htab->elf.splt != NULL
 
      && htab->elf.splt->size != 0
 
      && (htab->elf.splt->flags & SEC_EXCLUDE) == 0)
 
    bfd_put_32 (dynobj, htab->elf.splt->size,
 
                htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
 
 
  if (htab->elf.dynamic_sections_created)
  if (htab->elf.dynamic_sections_created)
    {
    {
      /* Add some entries to the .dynamic section.  We fill in the
      /* Add some entries to the .dynamic section.  We fill in the
         values later, in elf_i386_finish_dynamic_sections, but we
         values later, in elf_i386_finish_dynamic_sections, but we
         must add the entries now so that we get the correct size for
         must add the entries now so that we get the correct size for
Line 2709... Line 2856...
            {
            {
              if (!add_dynamic_entry (DT_TEXTREL, 0))
              if (!add_dynamic_entry (DT_TEXTREL, 0))
                return FALSE;
                return FALSE;
            }
            }
        }
        }
      if (htab->is_vxworks
      if (get_elf_i386_backend_data (output_bfd)->is_vxworks
          && !elf_vxworks_add_dynamic_entries (output_bfd, info))
          && !elf_vxworks_add_dynamic_entries (output_bfd, info))
        return FALSE;
        return FALSE;
    }
    }
#undef add_dynamic_entry
#undef add_dynamic_entry
 
 
Line 2872... Line 3019...
  bfd_vma *local_got_offsets;
  bfd_vma *local_got_offsets;
  bfd_vma *local_tlsdesc_gotents;
  bfd_vma *local_tlsdesc_gotents;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  Elf_Internal_Rela *relend;
  bfd_boolean is_vxworks_tls;
  bfd_boolean is_vxworks_tls;
 
  unsigned plt_entry_size;
 
 
  BFD_ASSERT (is_i386_elf (input_bfd));
  BFD_ASSERT (is_i386_elf (input_bfd));
 
 
  htab = elf_i386_hash_table (info);
  htab = elf_i386_hash_table (info);
  if (htab == NULL)
  if (htab == NULL)
Line 2884... Line 3032...
  sym_hashes = elf_sym_hashes (input_bfd);
  sym_hashes = elf_sym_hashes (input_bfd);
  local_got_offsets = elf_local_got_offsets (input_bfd);
  local_got_offsets = elf_local_got_offsets (input_bfd);
  local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd);
  local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd);
  /* We have to handle relocations in vxworks .tls_vars sections
  /* We have to handle relocations in vxworks .tls_vars sections
     specially, because the dynamic loader is 'weird'.  */
     specially, because the dynamic loader is 'weird'.  */
  is_vxworks_tls = (htab->is_vxworks && info->shared
  is_vxworks_tls = (get_elf_i386_backend_data (output_bfd)->is_vxworks
 
                    && info->shared
                    && !strcmp (input_section->output_section->name,
                    && !strcmp (input_section->output_section->name,
                                ".tls_vars"));
                                ".tls_vars"));
 
 
  elf_i386_set_tls_module_base (info);
  elf_i386_set_tls_module_base (info);
 
 
 
  plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
 
 
  rel = relocs;
  rel = relocs;
  relend = relocs + input_section->reloc_count;
  relend = relocs + input_section->reloc_count;
  for (; rel < relend; rel++)
  for (; rel < relend; rel++)
    {
    {
      unsigned int r_type;
      unsigned int r_type;
Line 3156... Line 3307...
                     even just remember the offset, as finish_dynamic_symbol
                     even just remember the offset, as finish_dynamic_symbol
                     would use that as offset into .got.  */
                     would use that as offset into .got.  */
 
 
                  if (htab->elf.splt != NULL)
                  if (htab->elf.splt != NULL)
                    {
                    {
                      plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
                      plt_index = h->plt.offset / plt_entry_size - 1;
                      off = (plt_index + 3) * 4;
                      off = (plt_index + 3) * 4;
                      base_got = htab->elf.sgotplt;
                      base_got = htab->elf.sgotplt;
                    }
                    }
                  else
                  else
                    {
                    {
                      plt_index = h->plt.offset / PLT_ENTRY_SIZE;
                      plt_index = h->plt.offset / plt_entry_size;
                      off = plt_index * 4;
                      off = plt_index * 4;
                      base_got = htab->elf.igotplt;
                      base_got = htab->elf.igotplt;
                    }
                    }
 
 
                  if (h->dynindx == -1
                  if (h->dynindx == -1
Line 4158... Line 4309...
                                struct bfd_link_info *info,
                                struct bfd_link_info *info,
                                struct elf_link_hash_entry *h,
                                struct elf_link_hash_entry *h,
                                Elf_Internal_Sym *sym)
                                Elf_Internal_Sym *sym)
{
{
  struct elf_i386_link_hash_table *htab;
  struct elf_i386_link_hash_table *htab;
 
  unsigned plt_entry_size;
 
  const struct elf_i386_backend_data *abed;
 
 
  htab = elf_i386_hash_table (info);
  htab = elf_i386_hash_table (info);
  if (htab == NULL)
  if (htab == NULL)
    return FALSE;
    return FALSE;
 
 
 
  abed = get_elf_i386_backend_data (output_bfd);
 
  plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
 
 
  if (h->plt.offset != (bfd_vma) -1)
  if (h->plt.offset != (bfd_vma) -1)
    {
    {
      bfd_vma plt_index;
      bfd_vma plt_index;
      bfd_vma got_offset;
      bfd_vma got_offset;
      Elf_Internal_Rela rel;
      Elf_Internal_Rela rel;
Line 4211... Line 4367...
 
 
         For static executables, we don't reserve anything.  */
         For static executables, we don't reserve anything.  */
 
 
      if (plt == htab->elf.splt)
      if (plt == htab->elf.splt)
        {
        {
          plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
          plt_index = h->plt.offset / plt_entry_size - 1;
          got_offset = (plt_index + 3) * 4;
          got_offset = (plt_index + 3) * 4;
        }
        }
      else
      else
        {
        {
          plt_index = h->plt.offset / PLT_ENTRY_SIZE;
          plt_index = h->plt.offset / plt_entry_size;
          got_offset = plt_index * 4;
          got_offset = plt_index * 4;
        }
        }
 
 
      /* Fill in the entry in the procedure linkage table.  */
      /* Fill in the entry in the procedure linkage table.  */
      if (! info->shared)
      if (! info->shared)
        {
        {
          memcpy (plt->contents + h->plt.offset, elf_i386_plt_entry,
          memcpy (plt->contents + h->plt.offset, abed->plt->plt_entry,
                  PLT_ENTRY_SIZE);
                  abed->plt->plt_entry_size);
          bfd_put_32 (output_bfd,
          bfd_put_32 (output_bfd,
                      (gotplt->output_section->vma
                      (gotplt->output_section->vma
                       + gotplt->output_offset
                       + gotplt->output_offset
                       + got_offset),
                       + got_offset),
                      plt->contents + h->plt.offset + 2);
                      plt->contents + h->plt.offset
 
                      + abed->plt->plt_got_offset);
 
 
          if (htab->is_vxworks)
          if (abed->is_vxworks)
            {
            {
              int s, k, reloc_index;
              int s, k, reloc_index;
 
 
              /* Create the R_386_32 relocation referencing the GOT
              /* Create the R_386_32 relocation referencing the GOT
                 for this PLT entry.  */
                 for this PLT entry.  */
 
 
              /* S: Current slot number (zero-based).  */
              /* S: Current slot number (zero-based).  */
              s = (h->plt.offset - PLT_ENTRY_SIZE) / PLT_ENTRY_SIZE;
              s = ((h->plt.offset - abed->plt->plt_entry_size)
 
                   / abed->plt->plt_entry_size);
              /* K: Number of relocations for PLTResolve. */
              /* K: Number of relocations for PLTResolve. */
              if (info->shared)
              if (info->shared)
                k = PLTRESOLVE_RELOCS_SHLIB;
                k = PLTRESOLVE_RELOCS_SHLIB;
              else
              else
                k = PLTRESOLVE_RELOCS;
                k = PLTRESOLVE_RELOCS;
Line 4269... Line 4427...
              loc + sizeof (Elf32_External_Rel));
              loc + sizeof (Elf32_External_Rel));
            }
            }
        }
        }
      else
      else
        {
        {
          memcpy (plt->contents + h->plt.offset, elf_i386_pic_plt_entry,
          memcpy (plt->contents + h->plt.offset, abed->plt->pic_plt_entry,
                  PLT_ENTRY_SIZE);
                  abed->plt->plt_entry_size);
          bfd_put_32 (output_bfd, got_offset,
          bfd_put_32 (output_bfd, got_offset,
                      plt->contents + h->plt.offset + 2);
                      plt->contents + h->plt.offset
 
                      + abed->plt->plt_got_offset);
        }
        }
 
 
      /* Don't fill PLT entry for static executables.  */
      /* Don't fill PLT entry for static executables.  */
      if (plt == htab->elf.splt)
      if (plt == htab->elf.splt)
        {
        {
          bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
          bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
                      plt->contents + h->plt.offset + 7);
                      plt->contents + h->plt.offset
          bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
                      + abed->plt->plt_reloc_offset);
                      plt->contents + h->plt.offset + 12);
          bfd_put_32 (output_bfd, - (h->plt.offset
 
                                     + abed->plt->plt_plt_offset + 4),
 
                      plt->contents + h->plt.offset
 
                      + abed->plt->plt_plt_offset);
        }
        }
 
 
      /* Fill in the entry in the global offset table.  */
      /* Fill in the entry in the global offset table.  */
      bfd_put_32 (output_bfd,
      bfd_put_32 (output_bfd,
                  (plt->output_section->vma
                  (plt->output_section->vma
                   + plt->output_offset
                   + plt->output_offset
                   + h->plt.offset
                   + h->plt.offset
                   + 6),
                   + abed->plt->plt_lazy_offset),
                  gotplt->contents + got_offset);
                  gotplt->contents + got_offset);
 
 
      /* Fill in the entry in the .rel.plt section.  */
      /* Fill in the entry in the .rel.plt section.  */
      rel.r_offset = (gotplt->output_section->vma
      rel.r_offset = (gotplt->output_section->vma
                      + gotplt->output_offset
                      + gotplt->output_offset
Line 4430... Line 4592...
 
 
     On VxWorks, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it
     On VxWorks, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it
     is relative to the ".got" section.  */
     is relative to the ".got" section.  */
  if (sym != NULL
  if (sym != NULL
      && (strcmp (h->root.root.string, "_DYNAMIC") == 0
      && (strcmp (h->root.root.string, "_DYNAMIC") == 0
          || (!htab->is_vxworks && h == htab->elf.hgot)))
          || (!abed->is_vxworks
 
              && h == htab->elf.hgot)))
    sym->st_shndx = SHN_ABS;
    sym->st_shndx = SHN_ABS;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
Line 4479... Line 4642...
                                  struct bfd_link_info *info)
                                  struct bfd_link_info *info)
{
{
  struct elf_i386_link_hash_table *htab;
  struct elf_i386_link_hash_table *htab;
  bfd *dynobj;
  bfd *dynobj;
  asection *sdyn;
  asection *sdyn;
 
  const struct elf_i386_backend_data *abed;
 
 
  htab = elf_i386_hash_table (info);
  htab = elf_i386_hash_table (info);
  if (htab == NULL)
  if (htab == NULL)
    return FALSE;
    return FALSE;
 
 
  dynobj = htab->elf.dynobj;
  dynobj = htab->elf.dynobj;
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
 
  abed = get_elf_i386_backend_data (output_bfd);
 
 
  if (htab->elf.dynamic_sections_created)
  if (htab->elf.dynamic_sections_created)
    {
    {
      Elf32_External_Dyn *dyncon, *dynconend;
      Elf32_External_Dyn *dyncon, *dynconend;
 
 
Line 4506... Line 4671...
          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
 
 
          switch (dyn.d_tag)
          switch (dyn.d_tag)
            {
            {
            default:
            default:
              if (htab->is_vxworks
              if (abed->is_vxworks
                  && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
                  && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
                break;
                break;
              continue;
              continue;
 
 
            case DT_PLTGOT:
            case DT_PLTGOT:
Line 4560... Line 4725...
      /* Fill in the first entry in the procedure linkage table.  */
      /* Fill in the first entry in the procedure linkage table.  */
      if (htab->elf.splt && htab->elf.splt->size > 0)
      if (htab->elf.splt && htab->elf.splt->size > 0)
        {
        {
          if (info->shared)
          if (info->shared)
            {
            {
              memcpy (htab->elf.splt->contents, elf_i386_pic_plt0_entry,
              memcpy (htab->elf.splt->contents, abed->plt->pic_plt0_entry,
                      sizeof (elf_i386_pic_plt0_entry));
                      abed->plt->plt0_entry_size);
              memset (htab->elf.splt->contents + sizeof (elf_i386_pic_plt0_entry),
              memset (htab->elf.splt->contents + abed->plt->plt0_entry_size,
                      htab->plt0_pad_byte,
                      abed->plt0_pad_byte,
                      PLT_ENTRY_SIZE - sizeof (elf_i386_pic_plt0_entry));
                      abed->plt->plt_entry_size - abed->plt->plt0_entry_size);
            }
            }
          else
          else
            {
            {
              memcpy (htab->elf.splt->contents, elf_i386_plt0_entry,
              memcpy (htab->elf.splt->contents, abed->plt->plt0_entry,
                      sizeof(elf_i386_plt0_entry));
                      abed->plt->plt0_entry_size);
              memset (htab->elf.splt->contents + sizeof (elf_i386_plt0_entry),
              memset (htab->elf.splt->contents + abed->plt->plt0_entry_size,
                      htab->plt0_pad_byte,
                      abed->plt0_pad_byte,
                      PLT_ENTRY_SIZE - sizeof (elf_i386_plt0_entry));
                      abed->plt->plt_entry_size - abed->plt->plt0_entry_size);
              bfd_put_32 (output_bfd,
              bfd_put_32 (output_bfd,
                          (htab->elf.sgotplt->output_section->vma
                          (htab->elf.sgotplt->output_section->vma
                           + htab->elf.sgotplt->output_offset
                           + htab->elf.sgotplt->output_offset
                           + 4),
                           + 4),
                          htab->elf.splt->contents + 2);
                          htab->elf.splt->contents
 
                          + abed->plt->plt0_got1_offset);
              bfd_put_32 (output_bfd,
              bfd_put_32 (output_bfd,
                          (htab->elf.sgotplt->output_section->vma
                          (htab->elf.sgotplt->output_section->vma
                           + htab->elf.sgotplt->output_offset
                           + htab->elf.sgotplt->output_offset
                           + 8),
                           + 8),
                          htab->elf.splt->contents + 8);
                          htab->elf.splt->contents
 
                          + abed->plt->plt0_got2_offset);
 
 
              if (htab->is_vxworks)
              if (abed->is_vxworks)
                {
                {
                  Elf_Internal_Rela rel;
                  Elf_Internal_Rela rel;
 
 
                  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
                  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
                     On IA32 we use REL relocations so the addend goes in
                     On IA32 we use REL relocations so the addend goes in
                     the PLT directly.  */
                     the PLT directly.  */
                  rel.r_offset = (htab->elf.splt->output_section->vma
                  rel.r_offset = (htab->elf.splt->output_section->vma
                                  + htab->elf.splt->output_offset
                                  + htab->elf.splt->output_offset
                                  + 2);
                                  + abed->plt->plt0_got1_offset);
                  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
                  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
                  bfd_elf32_swap_reloc_out (output_bfd, &rel,
                  bfd_elf32_swap_reloc_out (output_bfd, &rel,
                                            htab->srelplt2->contents);
                                            htab->srelplt2->contents);
                  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
                  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
                  rel.r_offset = (htab->elf.splt->output_section->vma
                  rel.r_offset = (htab->elf.splt->output_section->vma
                                  + htab->elf.splt->output_offset
                                  + htab->elf.splt->output_offset
                                  + 8);
                                  + abed->plt->plt0_got2_offset);
                  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
                  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
                  bfd_elf32_swap_reloc_out (output_bfd, &rel,
                  bfd_elf32_swap_reloc_out (output_bfd, &rel,
                                            htab->srelplt2->contents +
                                            htab->srelplt2->contents +
                                            sizeof (Elf32_External_Rel));
                                            sizeof (Elf32_External_Rel));
                }
                }
Line 4614... Line 4781...
             really seem like the right value.  */
             really seem like the right value.  */
          elf_section_data (htab->elf.splt->output_section)
          elf_section_data (htab->elf.splt->output_section)
            ->this_hdr.sh_entsize = 4;
            ->this_hdr.sh_entsize = 4;
 
 
          /* Correct the .rel.plt.unloaded relocations.  */
          /* Correct the .rel.plt.unloaded relocations.  */
          if (htab->is_vxworks && !info->shared)
          if (abed->is_vxworks && !info->shared)
            {
            {
              int num_plts = (htab->elf.splt->size / PLT_ENTRY_SIZE) - 1;
              int num_plts = (htab->elf.splt->size
 
                              / abed->plt->plt_entry_size) - 1;
              unsigned char *p;
              unsigned char *p;
 
 
              p = htab->srelplt2->contents;
              p = htab->srelplt2->contents;
              if (info->shared)
              if (info->shared)
                p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
                p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
Line 4665... Line 4833...
        }
        }
 
 
      elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4;
      elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4;
    }
    }
 
 
 
  /* Adjust .eh_frame for .plt section.  */
 
  if (htab->plt_eh_frame != NULL)
 
    {
 
      if (htab->elf.splt != NULL
 
          && htab->elf.splt->size != 0
 
          && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
 
          && htab->elf.splt->output_section != NULL
 
          && htab->plt_eh_frame->output_section != NULL)
 
        {
 
          bfd_vma plt_start = htab->elf.splt->output_section->vma;
 
          bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
 
                                   + htab->plt_eh_frame->output_offset
 
                                   + PLT_FDE_START_OFFSET;
 
          bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
 
                             htab->plt_eh_frame->contents
 
                             + PLT_FDE_START_OFFSET);
 
        }
 
      if (htab->plt_eh_frame->sec_info_type
 
          == ELF_INFO_TYPE_EH_FRAME)
 
        {
 
          if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
 
                                                 htab->plt_eh_frame,
 
                                                 htab->plt_eh_frame->contents))
 
            return FALSE;
 
        }
 
    }
 
 
  if (htab->elf.sgot && htab->elf.sgot->size > 0)
  if (htab->elf.sgot && htab->elf.sgot->size > 0)
    elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
    elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
 
 
  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
  htab_traverse (htab->loc_hash_table,
  htab_traverse (htab->loc_hash_table,
Line 4683... Line 4878...
 
 
static bfd_vma
static bfd_vma
elf_i386_plt_sym_val (bfd_vma i, const asection *plt,
elf_i386_plt_sym_val (bfd_vma i, const asection *plt,
                      const arelent *rel ATTRIBUTE_UNUSED)
                      const arelent *rel ATTRIBUTE_UNUSED)
{
{
  return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
  return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner);
}
}
 
 
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
 
 
static bfd_boolean
static bfd_boolean
Line 4732... Line 4927...
#define elf_backend_can_refcount        1
#define elf_backend_can_refcount        1
#define elf_backend_want_got_plt        1
#define elf_backend_want_got_plt        1
#define elf_backend_plt_readonly        1
#define elf_backend_plt_readonly        1
#define elf_backend_want_plt_sym        0
#define elf_backend_want_plt_sym        0
#define elf_backend_got_header_size     12
#define elf_backend_got_header_size     12
 
#define elf_backend_plt_alignment       4
 
 
/* Support RELA for objdump of prelink objects.  */
/* Support RELA for objdump of prelink objects.  */
#define elf_info_to_howto                     elf_i386_info_to_howto_rel
#define elf_info_to_howto                     elf_i386_info_to_howto_rel
#define elf_info_to_howto_rel                 elf_i386_info_to_howto_rel
#define elf_info_to_howto_rel                 elf_i386_info_to_howto_rel
 
 
Line 4832... Line 5028...
#undef elf_backend_want_plt_sym
#undef elf_backend_want_plt_sym
#define elf_backend_want_plt_sym        1
#define elf_backend_want_plt_sym        1
 
 
#include "elf32-target.h"
#include "elf32-target.h"
 
 
/* VxWorks support.  */
/* Native Client support.  */
 
 
#undef  TARGET_LITTLE_SYM
#undef  TARGET_LITTLE_SYM
#define TARGET_LITTLE_SYM               bfd_elf32_i386_vxworks_vec
#define TARGET_LITTLE_SYM               bfd_elf32_i386_nacl_vec
#undef  TARGET_LITTLE_NAME
#undef  TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME              "elf32-i386-vxworks"
#define TARGET_LITTLE_NAME              "elf32-i386-nacl"
 
#undef  elf32_bed
 
#define elf32_bed                       elf32_i386_nacl_bed
 
 
 
#undef  ELF_MAXPAGESIZE
 
#define ELF_MAXPAGESIZE                 0x10000
 
 
 
/* Restore defaults.  */
#undef  ELF_OSABI
#undef  ELF_OSABI
 
#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
 
 
/* Like elf_i386_link_hash_table_create but with tweaks for VxWorks.  */
/* NaCl uses substantially different PLT entries for the same effects.  */
 
 
static struct bfd_link_hash_table *
#undef  elf_backend_plt_alignment
elf_i386_vxworks_link_hash_table_create (bfd *abfd)
#define elf_backend_plt_alignment       5
 
#define NACL_PLT_ENTRY_SIZE             64
 
#define NACLMASK                        0xe0 /* 32-byte alignment mask.  */
 
 
 
static const bfd_byte elf_i386_nacl_plt0_entry[] =
{
{
  struct bfd_link_hash_table *ret;
    0xff, 0x35,                   /* pushl contents of address */
  struct elf_i386_link_hash_table *htab;
    0, 0, 0, 0,                       /* replaced with address of .got + 4.  */
 
    0x8b, 0x0d,                   /* movl contents of address, %ecx */
 
    0, 0, 0, 0,                       /* replaced with address of .got + 8.  */
 
    0x83, 0xe1, NACLMASK,         /* andl $NACLMASK, %ecx */
 
    0xff, 0xe1                    /* jmp *%ecx */
 
  };
 
 
  ret = elf_i386_link_hash_table_create (abfd);
static const bfd_byte elf_i386_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
  if (ret)
 
    {
    {
      htab = (struct elf_i386_link_hash_table *) ret;
    0x8b, 0x0d,                         /* movl contents of address, %ecx */
      htab->is_vxworks = 1;
    0, 0, 0, 0,                             /* replaced with GOT slot address.  */
      htab->plt0_pad_byte = 0x90;
    0x83, 0xe1, NACLMASK,               /* andl $NACLMASK, %ecx */
    }
    0xff, 0xe1,                         /* jmp *%ecx */
 
 
 
    /* Pad to the next 32-byte boundary with nop instructions.  */
 
    0x90,
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
 
  return ret;
    /* Lazy GOT entries point here (32-byte aligned).  */
}
    0x68,                              /* pushl immediate */
 
    0, 0, 0, 0,                            /* replaced with reloc offset.  */
 
    0xe9,                              /* jmp relative */
 
    0, 0, 0, 0,                            /* replaced with offset to .plt.  */
 
 
 
    /* Pad to the next 32-byte boundary with nop instructions.  */
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
    0x90, 0x90
 
  };
 
 
 
static const bfd_byte
 
elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] =
 
  {
 
    0xff, 0x73, 0x04,           /* pushl 4(%ebx) */
 
    0x8b, 0x4b, 0x08,           /* mov 0x8(%ebx), %ecx */
 
    0x83, 0xe1, 0xe0,           /* and $NACLMASK, %ecx */
 
    0xff, 0xe1,                 /* jmp *%ecx */
 
    0x90                        /* nop */
 
  };
 
 
 
static const bfd_byte elf_i386_nacl_pic_plt_entry[NACL_PLT_ENTRY_SIZE] =
 
  {
 
    0x8b, 0x8b,          /* movl offset(%ebx), %ecx */
 
    0, 0, 0, 0,          /* replaced with offset of this symbol in .got.  */
 
    0x83, 0xe1, 0xe0,    /* andl $NACLMASK, %ecx */
 
    0xff, 0xe1,          /* jmp *%ecx */
 
 
 
    /* Pad to the next 32-byte boundary with nop instructions.  */
 
    0x90,
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
 
 
    /* Lazy GOT entries point here (32-byte aligned).  */
 
    0x68,                /* pushl immediate */
 
    0, 0, 0, 0,          /* replaced with offset into relocation table.  */
 
    0xe9,                /* jmp relative */
 
    0, 0, 0, 0,          /* replaced with offset to start of .plt.  */
 
 
 
    /* Pad to the next 32-byte boundary with nop instructions.  */
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
 
    0x90, 0x90
 
  };
 
 
 
static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
 
  {
 
#if (PLT_CIE_LENGTH != 20                               \
 
     || PLT_FDE_LENGTH != 36                            \
 
     || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8  \
 
     || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
 
# error "Need elf_i386_backend_data parameters for eh_frame_plt offsets!"
 
#endif
 
    PLT_CIE_LENGTH, 0, 0, 0,               /* CIE length */
 
    0, 0, 0, 0,                         /* CIE ID */
 
    1,                                  /* CIE version */
 
    'z', 'R', 0,                        /* Augmentation string */
 
    1,                                  /* Code alignment factor */
 
    0x7c,                               /* Data alignment factor: -4 */
 
    8,                                  /* Return address column */
 
    1,                                  /* Augmentation size */
 
    DW_EH_PE_pcrel | DW_EH_PE_sdata4,   /* FDE encoding */
 
    DW_CFA_def_cfa, 4, 4,               /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
 
    DW_CFA_offset + 8, 1,               /* DW_CFA_offset: r8 (eip) at cfa-4 */
 
    DW_CFA_nop, DW_CFA_nop,
 
 
 
    PLT_FDE_LENGTH, 0, 0, 0,     /* FDE length */
 
    PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
 
    0, 0, 0, 0,                  /* R_386_PC32 .plt goes here */
 
    0, 0, 0, 0,                  /* .plt size goes here */
 
    0,                           /* Augmentation size */
 
    DW_CFA_def_cfa_offset, 8,    /* DW_CFA_def_cfa_offset: 8 */
 
    DW_CFA_advance_loc + 6,      /* DW_CFA_advance_loc: 6 to __PLT__+6 */
 
    DW_CFA_def_cfa_offset, 12,   /* DW_CFA_def_cfa_offset: 12 */
 
    DW_CFA_advance_loc + 58,     /* DW_CFA_advance_loc: 58 to __PLT__+64 */
 
    DW_CFA_def_cfa_expression,   /* DW_CFA_def_cfa_expression */
 
    13,                          /* Block length */
 
    DW_OP_breg4, 4,              /* DW_OP_breg4 (esp): 4 */
 
    DW_OP_breg8, 0,              /* DW_OP_breg8 (eip): 0 */
 
    DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
 
    DW_OP_lit2, DW_OP_shl, DW_OP_plus,
 
    DW_CFA_nop, DW_CFA_nop
 
  };
 
 
 
static const struct elf_i386_plt_layout elf_i386_nacl_plt =
 
  {
 
    elf_i386_nacl_plt0_entry,           /* plt0_entry */
 
    sizeof (elf_i386_nacl_plt0_entry),  /* plt0_entry_size */
 
    2,                                  /* plt0_got1_offset */
 
    8,                                  /* plt0_got2_offset */
 
    elf_i386_nacl_plt_entry,            /* plt_entry */
 
    NACL_PLT_ENTRY_SIZE,                /* plt_entry_size */
 
    2,                                  /* plt_got_offset */
 
    33,                                 /* plt_reloc_offset */
 
    38,                                 /* plt_plt_offset */
 
    32,                                 /* plt_lazy_offset */
 
    elf_i386_nacl_pic_plt0_entry,       /* pic_plt0_entry */
 
    elf_i386_nacl_pic_plt_entry,        /* pic_plt_entry */
 
    elf_i386_nacl_eh_frame_plt,         /* eh_frame_plt */
 
    sizeof (elf_i386_nacl_eh_frame_plt),/* eh_frame_plt_size */
 
  };
 
 
 
static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
 
  {
 
    &elf_i386_nacl_plt,                      /* plt */
 
    0x90,                               /* plt0_pad_byte: nop insn */
 
    0,                                  /* is_vxworks */
 
  };
 
 
 
#undef  elf_backend_arch_data
 
#define elf_backend_arch_data   &elf_i386_nacl_arch_bed
 
 
 
#include "elf32-target.h"
 
 
 
/* VxWorks support.  */
 
 
 
#undef  TARGET_LITTLE_SYM
 
#define TARGET_LITTLE_SYM               bfd_elf32_i386_vxworks_vec
 
#undef  TARGET_LITTLE_NAME
 
#define TARGET_LITTLE_NAME              "elf32-i386-vxworks"
 
#undef  ELF_OSABI
 
#undef  elf_backend_plt_alignment
 
#define elf_backend_plt_alignment       4
 
 
 
static const struct elf_i386_backend_data elf_i386_vxworks_arch_bed =
 
  {
 
    &elf_i386_plt,                      /* plt */
 
    0x90,                               /* plt0_pad_byte */
 
    1,                                  /* is_vxworks */
 
  };
 
 
 
#undef  elf_backend_arch_data
 
#define elf_backend_arch_data   &elf_i386_vxworks_arch_bed
 
 
#undef elf_backend_relocs_compatible
#undef elf_backend_relocs_compatible
#undef elf_backend_post_process_headers
#undef elf_backend_post_process_headers
#undef bfd_elf32_bfd_link_hash_table_create
 
#define bfd_elf32_bfd_link_hash_table_create \
 
  elf_i386_vxworks_link_hash_table_create
 
#undef elf_backend_add_symbol_hook
#undef elf_backend_add_symbol_hook
#define elf_backend_add_symbol_hook \
#define elf_backend_add_symbol_hook \
  elf_vxworks_add_symbol_hook
  elf_vxworks_add_symbol_hook
#undef elf_backend_link_output_symbol_hook
#undef elf_backend_link_output_symbol_hook
#define elf_backend_link_output_symbol_hook \
#define elf_backend_link_output_symbol_hook \

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.