// i386.cc -- i386 target support for gold.

// Copyright (C) 2006-2016 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of gold.

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.

#include "gold.h"

#include <cstring>

#include "elfcpp.h"
#include "dwarf.h"
#include "parameters.h"
#include "reloc.h"
#include "i386.h"
#include "object.h"
#include "symtab.h"
#include "layout.h"
#include "output.h"
#include "copy-relocs.h"
#include "target.h"
#include "target-reloc.h"
#include "target-select.h"
#include "tls.h"
#include "freebsd.h"
#include "nacl.h"
#include "gc.h"

namespace
{

using namespace gold;

// A class to handle the .got.plt section.

class Output_data_got_plt_i386 : public Output_section_data_build
{
 public:
  Output_data_got_plt_i386(Layout* layout)
    : Output_section_data_build(4),
      layout_(layout)
  { }

 protected:
  // Write out the PLT data.
  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, "** GOT PLT"); }

 private:
  // A pointer to the Layout class, so that we can find the .dynamic
  // section when we write out the GOT PLT section.
  Layout* layout_;
};

// A class to handle the PLT data.
// This is an abstract base class that handles most of the linker details
// but does not know the actual contents of PLT entries.  The derived
// classes below fill in those details.

class Output_data_plt_i386 : public Output_section_data
{
 public:
  typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;

  Output_data_plt_i386(Layout*, uint64_t addralign,
		       Output_data_got_plt_i386*, Output_data_space*);

  // Add an entry to the PLT.
  void
  add_entry(Symbol_table*, Layout*, Symbol* gsym);

  // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
  unsigned int
  add_local_ifunc_entry(Symbol_table*, Layout*,
			Sized_relobj_file<32, false>* relobj,
			unsigned int local_sym_index);

  // Return the .rel.plt section data.
  Reloc_section*
  rel_plt() const
  { return this->rel_; }

  // Return where the TLS_DESC relocations should go.
  Reloc_section*
  rel_tls_desc(Layout*);

  // Return where the IRELATIVE relocations should go.
  Reloc_section*
  rel_irelative(Symbol_table*, Layout*);

  // Return whether we created a section for IRELATIVE relocations.
  bool
  has_irelative_section() const
  { return this->irelative_rel_ != NULL; }

  // Return the number of PLT entries.
  unsigned int
  entry_count() const
  { return this->count_ + this->irelative_count_; }

  // Return the offset of the first non-reserved PLT entry.
  unsigned int
  first_plt_entry_offset()
  { return this->get_plt_entry_size(); }

  // Return the size of a PLT entry.
  unsigned int
  get_plt_entry_size() const
  { return this->do_get_plt_entry_size(); }

  // Return the PLT address to use for a global symbol.
  uint64_t
  address_for_global(const Symbol*);

  // Return the PLT address to use for a local symbol.
  uint64_t
  address_for_local(const Relobj*, unsigned int symndx);

  // Add .eh_frame information for the PLT.
  void
  add_eh_frame(Layout* layout)
  { this->do_add_eh_frame(layout); }

 protected:
  // Fill the first PLT entry, given the pointer to the PLT section data
  // and the runtime address of the GOT.
  void
  fill_first_plt_entry(unsigned char* pov,
		       elfcpp::Elf_types<32>::Elf_Addr got_address)
  { this->do_fill_first_plt_entry(pov, got_address); }

  // Fill a normal PLT entry, given the pointer to the entry's data in the
  // section, the runtime address of the GOT, the offset into the GOT of
  // the corresponding slot, the offset into the relocation section of the
  // corresponding reloc, and the offset of this entry within the whole
  // PLT.  Return the offset from this PLT entry's runtime address that
  // should be used to compute the initial value of the GOT slot.
  unsigned int
  fill_plt_entry(unsigned char* pov,
		 elfcpp::Elf_types<32>::Elf_Addr got_address,
		 unsigned int got_offset,
		 unsigned int plt_offset,
		 unsigned int plt_rel_offset)
  {
    return this->do_fill_plt_entry(pov, got_address, got_offset,
				   plt_offset, plt_rel_offset);
  }

  virtual unsigned int
  do_get_plt_entry_size() const = 0;

  virtual void
  do_fill_first_plt_entry(unsigned char* pov,
			  elfcpp::Elf_types<32>::Elf_Addr got_address) = 0;

  virtual unsigned int
  do_fill_plt_entry(unsigned char* pov,
		    elfcpp::Elf_types<32>::Elf_Addr got_address,
		    unsigned int got_offset,
		    unsigned int plt_offset,
		    unsigned int plt_rel_offset) = 0;

  virtual void
  do_add_eh_frame(Layout*) = 0;

  void
  do_adjust_output_section(Output_section* os);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** PLT")); }

  // The .eh_frame unwind information for the PLT.
  // The CIE is common across variants of the PLT format.
  static const int plt_eh_frame_cie_size = 16;
  static const unsigned char plt_eh_frame_cie[plt_eh_frame_cie_size];

 private:
  // Set the final size.
  void
  set_final_data_size()
  {
    this->set_data_size((this->count_ + this->irelative_count_ + 1)
			* this->get_plt_entry_size());
  }

  // Write out the PLT data.
  void
  do_write(Output_file*);

  // We keep a list of global STT_GNU_IFUNC symbols, each with its
  // offset in the GOT.
  struct Global_ifunc
  {
    Symbol* sym;
    unsigned int got_offset;
  };

  // We keep a list of local STT_GNU_IFUNC symbols, each with its
  // offset in the GOT.
  struct Local_ifunc
  {
    Sized_relobj_file<32, false>* object;
    unsigned int local_sym_index;
    unsigned int got_offset;
  };

  // The reloc section.
  Reloc_section* rel_;
  // The TLS_DESC relocations, if necessary.  These must follow the
  // regular PLT relocs.
  Reloc_section* tls_desc_rel_;
  // The IRELATIVE relocations, if necessary.  These must follow the
  // regular relocatoins and the TLS_DESC relocations.
  Reloc_section* irelative_rel_;
  // The .got.plt section.
  Output_data_got_plt_i386* got_plt_;
  // The part of the .got.plt section used for IRELATIVE relocs.
  Output_data_space* got_irelative_;
  // The number of PLT entries.
  unsigned int count_;
  // Number of PLT entries with R_386_IRELATIVE relocs.  These follow
  // the regular PLT entries.
  unsigned int irelative_count_;
  // Global STT_GNU_IFUNC symbols.
  std::vector<Global_ifunc> global_ifuncs_;
  // Local STT_GNU_IFUNC symbols.
  std::vector<Local_ifunc> local_ifuncs_;
};

// This is an abstract class for the standard PLT layout.
// The derived classes below handle the actual PLT contents
// for the executable (non-PIC) and shared-library (PIC) cases.
// The unwind information is uniform across those two, so it's here.

class Output_data_plt_i386_standard : public Output_data_plt_i386
{
 public:
  Output_data_plt_i386_standard(Layout* layout,
				Output_data_got_plt_i386* got_plt,
				Output_data_space* got_irelative)
    : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
  { }

 protected:
  virtual unsigned int
  do_get_plt_entry_size() const
  { return plt_entry_size; }

  virtual void
  do_add_eh_frame(Layout* layout)
  {
    layout->add_eh_frame_for_plt(this, plt_eh_frame_cie, plt_eh_frame_cie_size,
				 plt_eh_frame_fde, plt_eh_frame_fde_size);
  }

  // The size of an entry in the PLT.
  static const int plt_entry_size = 16;

  // The .eh_frame unwind information for the PLT.
  static const int plt_eh_frame_fde_size = 32;
  static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size];
};

// Actually fill the PLT contents for an executable (non-PIC).

class Output_data_plt_i386_exec : public Output_data_plt_i386_standard
{
public:
  Output_data_plt_i386_exec(Layout* layout,
			    Output_data_got_plt_i386* got_plt,
			    Output_data_space* got_irelative)
    : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
  { }

 protected:
  virtual void
  do_fill_first_plt_entry(unsigned char* pov,
			  elfcpp::Elf_types<32>::Elf_Addr got_address);

  virtual unsigned int
  do_fill_plt_entry(unsigned char* pov,
		    elfcpp::Elf_types<32>::Elf_Addr got_address,
		    unsigned int got_offset,
		    unsigned int plt_offset,
		    unsigned int plt_rel_offset);

 private:
  // The first entry in the PLT for an executable.
  static const unsigned char first_plt_entry[plt_entry_size];

  // Other entries in the PLT for an executable.
  static const unsigned char plt_entry[plt_entry_size];
};

// Actually fill the PLT contents for a shared library (PIC).

class Output_data_plt_i386_dyn : public Output_data_plt_i386_standard
{
 public:
  Output_data_plt_i386_dyn(Layout* layout,
			   Output_data_got_plt_i386* got_plt,
			   Output_data_space* got_irelative)
    : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
  { }

 protected:
  virtual void
  do_fill_first_plt_entry(unsigned char* pov, elfcpp::Elf_types<32>::Elf_Addr);

  virtual unsigned int
  do_fill_plt_entry(unsigned char* pov,
		    elfcpp::Elf_types<32>::Elf_Addr,
		    unsigned int got_offset,
		    unsigned int plt_offset,
		    unsigned int plt_rel_offset);

 private:
  // The first entry in the PLT for a shared object.
  static const unsigned char first_plt_entry[plt_entry_size];

  // Other entries in the PLT for a shared object.
  static const unsigned char plt_entry[plt_entry_size];
};

// The i386 target class.
// TLS info comes from
//   http://people.redhat.com/drepper/tls.pdf
//   http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt

class Target_i386 : public Sized_target<32, false>
{
 public:
  typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;

  Target_i386(const Target::Target_info* info = &i386_info)
    : Sized_target<32, false>(info),
      got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
      got_tlsdesc_(NULL), global_offset_table_(NULL), rel_dyn_(NULL),
      rel_irelative_(NULL), copy_relocs_(elfcpp::R_386_COPY),
      got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
  { }

  // Process the relocations to determine unreferenced sections for
  // garbage collection.
  void
  gc_process_relocs(Symbol_table* symtab,
		    Layout* layout,
		    Sized_relobj_file<32, false>* object,
		    unsigned int data_shndx,
		    unsigned int sh_type,
		    const unsigned char* prelocs,
		    size_t reloc_count,
		    Output_section* output_section,
		    bool needs_special_offset_handling,
		    size_t local_symbol_count,
		    const unsigned char* plocal_symbols);

  // Scan the relocations to look for symbol adjustments.
  void
  scan_relocs(Symbol_table* symtab,
	      Layout* layout,
	      Sized_relobj_file<32, false>* object,
	      unsigned int data_shndx,
	      unsigned int sh_type,
	      const unsigned char* prelocs,
	      size_t reloc_count,
	      Output_section* output_section,
	      bool needs_special_offset_handling,
	      size_t local_symbol_count,
	      const unsigned char* plocal_symbols);

  // Finalize the sections.
  void
  do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);

  // Return the value to use for a dynamic which requires special
  // treatment.
  uint64_t
  do_dynsym_value(const Symbol*) const;

  // Relocate a section.
  void
  relocate_section(const Relocate_info<32, false>*,
		   unsigned int sh_type,
		   const unsigned char* prelocs,
		   size_t reloc_count,
		   Output_section* output_section,
		   bool needs_special_offset_handling,
		   unsigned char* view,
		   elfcpp::Elf_types<32>::Elf_Addr view_address,
		   section_size_type view_size,
		   const Reloc_symbol_changes*);

  // Scan the relocs during a relocatable link.
  void
  scan_relocatable_relocs(Symbol_table* symtab,
			  Layout* layout,
			  Sized_relobj_file<32, false>* object,
			  unsigned int data_shndx,
			  unsigned int sh_type,
			  const unsigned char* prelocs,
			  size_t reloc_count,
			  Output_section* output_section,
			  bool needs_special_offset_handling,
			  size_t local_symbol_count,
			  const unsigned char* plocal_symbols,
			  Relocatable_relocs*);

  // Scan the relocs for --emit-relocs.
  void
  emit_relocs_scan(Symbol_table* symtab,
		   Layout* layout,
		   Sized_relobj_file<32, false>* object,
		   unsigned int data_shndx,
		   unsigned int sh_type,
		   const unsigned char* prelocs,
		   size_t reloc_count,
		   Output_section* output_section,
		   bool needs_special_offset_handling,
		   size_t local_symbol_count,
		   const unsigned char* plocal_syms,
		   Relocatable_relocs* rr);

  // Emit relocations for a section.
  void
  relocate_relocs(const Relocate_info<32, false>*,
		  unsigned int sh_type,
		  const unsigned char* prelocs,
		  size_t reloc_count,
		  Output_section* output_section,
		  elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
		  unsigned char* view,
		  elfcpp::Elf_types<32>::Elf_Addr view_address,
		  section_size_type view_size,
		  unsigned char* reloc_view,
		  section_size_type reloc_view_size);

  // Return a string used to fill a code section with nops.
  std::string
  do_code_fill(section_size_type length) const;

  // Return whether SYM is defined by the ABI.
  bool
  do_is_defined_by_abi(const Symbol* sym) const
  { return strcmp(sym->name(), "___tls_get_addr") == 0; }

  // Return whether a symbol name implies a local label.  The UnixWare
  // 2.1 cc generates temporary symbols that start with .X, so we
  // recognize them here.  FIXME: do other SVR4 compilers also use .X?.
  // If so, we should move the .X recognition into
  // Target::do_is_local_label_name.
  bool
  do_is_local_label_name(const char* name) const
  {
    if (name[0] == '.' && name[1] == 'X')
      return true;
    return Target::do_is_local_label_name(name);
  }

  // Return the PLT address to use for a global symbol.
  uint64_t
  do_plt_address_for_global(const Symbol* gsym) const
  { return this->plt_section()->address_for_global(gsym); }

  uint64_t
  do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
  { return this->plt_section()->address_for_local(relobj, symndx); }

  // We can tell whether we take the address of a function.
  inline bool
  do_can_check_for_function_pointers() const
  { return true; }

  // Return the base for a DW_EH_PE_datarel encoding.
  uint64_t
  do_ehframe_datarel_base() const;

  // Return whether SYM is call to a non-split function.
  bool
  do_is_call_to_non_split(const Symbol* sym, const unsigned char*,
			  const unsigned char*, section_size_type) const;

  // Adjust -fsplit-stack code which calls non-split-stack code.
  void
  do_calls_non_split(Relobj* object, unsigned int shndx,
		     section_offset_type fnoffset, section_size_type fnsize,
		     const unsigned char* prelocs, size_t reloc_count,
		     unsigned char* view, section_size_type view_size,
		     std::string* from, std::string* to) const;

  // Return the size of the GOT section.
  section_size_type
  got_size() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_->data_size();
  }

  // Return the number of entries in the GOT.
  unsigned int
  got_entry_count() const
  {
    if (this->got_ == NULL)
      return 0;
    return this->got_size() / 4;
  }

  // Return the number of entries in the PLT.
  unsigned int
  plt_entry_count() const;

  // Return the offset of the first non-reserved PLT entry.
  unsigned int
  first_plt_entry_offset() const;

  // Return the size of each PLT entry.
  unsigned int
  plt_entry_size() const;

 protected:
  // Instantiate the plt_ member.
  // This chooses the right PLT flavor for an executable or a shared object.
  Output_data_plt_i386*
  make_data_plt(Layout* layout,
		Output_data_got_plt_i386* got_plt,
		Output_data_space* got_irelative,
		bool dyn)
  { return this->do_make_data_plt(layout, got_plt, got_irelative, dyn); }

  virtual Output_data_plt_i386*
  do_make_data_plt(Layout* layout,
		   Output_data_got_plt_i386* got_plt,
		   Output_data_space* got_irelative,
		   bool dyn)
  {
    if (dyn)
      return new Output_data_plt_i386_dyn(layout, got_plt, got_irelative);
    else
      return new Output_data_plt_i386_exec(layout, got_plt, got_irelative);
  }

 private:
  // The class which scans relocations.
  struct Scan
  {
    static inline int

    get_reference_flags(unsigned int r_type);

    inline void
    local(Symbol_table* symtab, Layout* layout, Target_i386* target,
	  Sized_relobj_file<32, false>* object,
	  unsigned int data_shndx,
	  Output_section* output_section,
	  const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
	  const elfcpp::Sym<32, false>& lsym,
	  bool is_discarded);

    inline void
    global(Symbol_table* symtab, Layout* layout, Target_i386* target,
	   Sized_relobj_file<32, false>* object,
	   unsigned int data_shndx,
	   Output_section* output_section,
	   const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
	   Symbol* gsym);

    inline bool
    local_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
					Target_i386* target,
					Sized_relobj_file<32, false>* object,
					unsigned int data_shndx,
					Output_section* output_section,
					const elfcpp::Rel<32, false>& reloc,
					unsigned int r_type,
					const elfcpp::Sym<32, false>& lsym);

    inline bool
    global_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
					 Target_i386* target,
					 Sized_relobj_file<32, false>* object,
					 unsigned int data_shndx,
					 Output_section* output_section,
					 const elfcpp::Rel<32, false>& reloc,
					 unsigned int r_type,
					 Symbol* gsym);

    inline bool
    possible_function_pointer_reloc(unsigned int r_type);

    bool
    reloc_needs_plt_for_ifunc(Sized_relobj_file<32, false>*,
			      unsigned int r_type);

    static void
    unsupported_reloc_local(Sized_relobj_file<32, false>*, unsigned int r_type);

    static void
    unsupported_reloc_global(Sized_relobj_file<32, false>*, unsigned int r_type,
			     Symbol*);
  };

  // The class which implements relocation.
  class Relocate
  {
   public:
    Relocate()
      : skip_call_tls_get_addr_(false),
	local_dynamic_type_(LOCAL_DYNAMIC_NONE)
    { }

    ~Relocate()
    {
      if (this->skip_call_tls_get_addr_)
	{
	  // FIXME: This needs to specify the location somehow.
	  gold_error(_("missing expected TLS relocation"));
	}
    }

    // Return whether the static relocation needs to be applied.
    inline bool
    should_apply_static_reloc(const Sized_symbol<32>* gsym,
			      unsigned int r_type,
			      bool is_32bit,
			      Output_section* output_section);

    // Do a relocation.  Return false if the caller should not issue
    // any warnings about this relocation.
    inline bool
    relocate(const Relocate_info<32, false>*, unsigned int,
	     Target_i386*, Output_section*, size_t, const unsigned char*,
	     const Sized_symbol<32>*, const Symbol_value<32>*,
	     unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
	     section_size_type);

   private:
    // Do a TLS relocation.
    inline void
    relocate_tls(const Relocate_info<32, false>*, Target_i386* target,
		 size_t relnum, const elfcpp::Rel<32, false>&,
		 unsigned int r_type, const Sized_symbol<32>*,
		 const Symbol_value<32>*,
		 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
		 section_size_type);

    // Do a TLS General-Dynamic to Initial-Exec transition.
    inline void
    tls_gd_to_ie(const Relocate_info<32, false>*, size_t relnum,
		 const elfcpp::Rel<32, false>&, unsigned int r_type,
		 elfcpp::Elf_types<32>::Elf_Addr value,
		 unsigned char* view,
		 section_size_type view_size);

    // Do a TLS General-Dynamic to Local-Exec transition.
    inline void
    tls_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
		 Output_segment* tls_segment,
		 const elfcpp::Rel<32, false>&, unsigned int r_type,
		 elfcpp::Elf_types<32>::Elf_Addr value,
		 unsigned char* view,
		 section_size_type view_size);

    // Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Initial-Exec
    // transition.
    inline void
    tls_desc_gd_to_ie(const Relocate_info<32, false>*, size_t relnum,
		      const elfcpp::Rel<32, false>&, unsigned int r_type,
		      elfcpp::Elf_types<32>::Elf_Addr value,
		      unsigned char* view,
		      section_size_type view_size);

    // Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Local-Exec
    // transition.
    inline void
    tls_desc_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
		      Output_segment* tls_segment,
		      const elfcpp::Rel<32, false>&, unsigned int r_type,
		      elfcpp::Elf_types<32>::Elf_Addr value,
		      unsigned char* view,
		      section_size_type view_size);

    // Do a TLS Local-Dynamic to Local-Exec transition.
    inline void
    tls_ld_to_le(const Relocate_info<32, false>*, size_t relnum,
		 Output_segment* tls_segment,
		 const elfcpp::Rel<32, false>&, unsigned int r_type,
		 elfcpp::Elf_types<32>::Elf_Addr value,
		 unsigned char* view,
		 section_size_type view_size);

    // Do a TLS Initial-Exec to Local-Exec transition.
    static inline void
    tls_ie_to_le(const Relocate_info<32, false>*, size_t relnum,
		 Output_segment* tls_segment,
		 const elfcpp::Rel<32, false>&, unsigned int r_type,
		 elfcpp::Elf_types<32>::Elf_Addr value,
		 unsigned char* view,
		 section_size_type view_size);

    // We need to keep track of which type of local dynamic relocation
    // we have seen, so that we can optimize R_386_TLS_LDO_32 correctly.
    enum Local_dynamic_type
    {
      LOCAL_DYNAMIC_NONE,
      LOCAL_DYNAMIC_SUN,
      LOCAL_DYNAMIC_GNU
    };

    // This is set if we should skip the next reloc, which should be a
    // PLT32 reloc against ___tls_get_addr.
    bool skip_call_tls_get_addr_;
    // The type of local dynamic relocation we have seen in the section
    // being relocated, if any.
    Local_dynamic_type local_dynamic_type_;
  };

  // A class for inquiring about properties of a relocation,
  // used while scanning relocs during a relocatable link and
  // garbage collection.
  class Classify_reloc :
      public gold::Default_classify_reloc<elfcpp::SHT_REL, 32, false>
  {
   public:
    typedef Reloc_types<elfcpp::SHT_REL, 32, false>::Reloc Reltype;

    // Return the explicit addend of the relocation (return 0 for SHT_REL).
    static elfcpp::Elf_types<32>::Elf_Swxword
    get_r_addend(const Reltype*)
    { return 0; }

    // Return the size of the addend of the relocation (only used for SHT_REL).
    static unsigned int
    get_size_for_reloc(unsigned int, Relobj*);
  };

  // Adjust TLS relocation type based on the options and whether this
  // is a local symbol.
  static tls::Tls_optimization
  optimize_tls_reloc(bool is_final, int r_type);

  // Check if relocation against this symbol is a candidate for
  // conversion from
  // mov foo@GOT(%reg), %reg
  // to
  // lea foo@GOTOFF(%reg), %reg.
  static bool
  can_convert_mov_to_lea(const Symbol* gsym)
  {
    gold_assert(gsym != NULL);
    return (gsym->type() != elfcpp::STT_GNU_IFUNC
	    && !gsym->is_undefined ()
	    && !gsym->is_from_dynobj()
	    && !gsym->is_preemptible()
	    && (!parameters->options().shared()
		|| (gsym->visibility() != elfcpp::STV_DEFAULT
		    && gsym->visibility() != elfcpp::STV_PROTECTED)
		|| parameters->options().Bsymbolic())
	    && strcmp(gsym->name(), "_DYNAMIC") != 0);
  }

  // Get the GOT section, creating it if necessary.
  Output_data_got<32, false>*
  got_section(Symbol_table*, Layout*);

  // Get the GOT PLT section.
  Output_data_got_plt_i386*
  got_plt_section() const
  {
    gold_assert(this->got_plt_ != NULL);
    return this->got_plt_;
  }

  // Get the GOT section for TLSDESC entries.
  Output_data_got<32, false>*
  got_tlsdesc_section() const
  {
    gold_assert(this->got_tlsdesc_ != NULL);
    return this->got_tlsdesc_;
  }

  // Create the PLT section.
  void
  make_plt_section(Symbol_table* symtab, Layout* layout);

  // Create a PLT entry for a global symbol.
  void
  make_plt_entry(Symbol_table*, Layout*, Symbol*);

  // Create a PLT entry for a local STT_GNU_IFUNC symbol.
  void
  make_local_ifunc_plt_entry(Symbol_table*, Layout*,
			     Sized_relobj_file<32, false>* relobj,
			     unsigned int local_sym_index);

  // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
  void
  define_tls_base_symbol(Symbol_table*, Layout*);

  // Create a GOT entry for the TLS module index.
  unsigned int
  got_mod_index_entry(Symbol_table* symtab, Layout* layout,
		      Sized_relobj_file<32, false>* object);

  // Get the PLT section.
  Output_data_plt_i386*
  plt_section() const
  {
    gold_assert(this->plt_ != NULL);
    return this->plt_;
  }

  // Get the dynamic reloc section, creating it if necessary.
  Reloc_section*
  rel_dyn_section(Layout*);

  // Get the section to use for TLS_DESC relocations.
  Reloc_section*
  rel_tls_desc_section(Layout*) const;

  // Get the section to use for IRELATIVE relocations.
  Reloc_section*
  rel_irelative_section(Layout*);

  // Add a potential copy relocation.
  void
  copy_reloc(Symbol_table* symtab, Layout* layout,
	     Sized_relobj_file<32, false>* object,
	     unsigned int shndx, Output_section* output_section,
	     Symbol* sym, const elfcpp::Rel<32, false>& reloc)
  {
    unsigned int r_type = elfcpp::elf_r_type<32>(reloc.get_r_info());
    this->copy_relocs_.copy_reloc(symtab, layout,
				  symtab->get_sized_symbol<32>(sym),
				  object, shndx, output_section,
				  r_type, reloc.get_r_offset(), 0,
				  this->rel_dyn_section(layout));
  }

  // Information about this specific target which we pass to the
  // general Target structure.
  static const Target::Target_info i386_info;

  // The types of GOT entries needed for this platform.
  // These values are exposed to the ABI in an incremental link.
  // Do not renumber existing values without changing the version
  // number of the .gnu_incremental_inputs section.
  enum Got_type
  {
    GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
    GOT_TYPE_TLS_NOFFSET = 1,   // GOT entry for negative TLS offset
    GOT_TYPE_TLS_OFFSET = 2,    // GOT entry for positive TLS offset
    GOT_TYPE_TLS_PAIR = 3,      // GOT entry for TLS module/offset pair
    GOT_TYPE_TLS_DESC = 4       // GOT entry for TLS_DESC pair
  };

  // The GOT section.
  Output_data_got<32, false>* got_;
  // The PLT section.
  Output_data_plt_i386* plt_;
  // The GOT PLT section.
  Output_data_got_plt_i386* got_plt_;
  // The GOT section for IRELATIVE relocations.
  Output_data_space* got_irelative_;
  // The GOT section for TLSDESC relocations.
  Output_data_got<32, false>* got_tlsdesc_;
  // The _GLOBAL_OFFSET_TABLE_ symbol.
  Symbol* global_offset_table_;
  // The dynamic reloc section.
  Reloc_section* rel_dyn_;
  // The section to use for IRELATIVE relocs.
  Reloc_section* rel_irelative_;
  // Relocs saved to avoid a COPY reloc.
  Copy_relocs<elfcpp::SHT_REL, 32, false> copy_relocs_;
  // Offset of the GOT entry for the TLS module index.
  unsigned int got_mod_index_offset_;
  // True if the _TLS_MODULE_BASE_ symbol has been defined.
  bool tls_base_symbol_defined_;
};

const Target::Target_info Target_i386::i386_info =
{
  32,			// size
  false,		// is_big_endian
  elfcpp::EM_386,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  true,			// has_code_fill
  true,			// is_default_stack_executable
  true,			// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/usr/lib/libc.so.1",	// dynamic_linker
  0x08048000,		// default_text_segment_address
  0x1000,		// abi_pagesize (overridable by -z max-page-size)
  0x1000,		// common_pagesize (overridable by -z common-page-size)
  false,                // isolate_execinstr
  0,                    // rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
};

// Get the GOT section, creating it if necessary.

Output_data_got<32, false>*
Target_i386::got_section(Symbol_table* symtab, Layout* layout)
{
  if (this->got_ == NULL)
    {
      gold_assert(symtab != NULL && layout != NULL);

      this->got_ = new Output_data_got<32, false>();

      // When using -z now, we can treat .got.plt as a relro section.
      // Without -z now, it is modified after program startup by lazy
      // PLT relocations.
      bool is_got_plt_relro = parameters->options().now();
      Output_section_order got_order = (is_got_plt_relro
					? ORDER_RELRO
					: ORDER_RELRO_LAST);
      Output_section_order got_plt_order = (is_got_plt_relro
					    ? ORDER_RELRO
					    : ORDER_NON_RELRO_FIRST);

      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_WRITE),
				      this->got_, got_order, true);

      this->got_plt_ = new Output_data_got_plt_i386(layout);
      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_WRITE),
				      this->got_plt_, got_plt_order,
				      is_got_plt_relro);

      // The first three entries are reserved.
      this->got_plt_->set_current_data_size(3 * 4);

      if (!is_got_plt_relro)
	{
	  // Those bytes can go into the relro segment.
	  layout->increase_relro(3 * 4);
	}

      // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
      this->global_offset_table_ =
	symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
				      Symbol_table::PREDEFINED,
				      this->got_plt_,
				      0, 0, elfcpp::STT_OBJECT,
				      elfcpp::STB_LOCAL,
				      elfcpp::STV_HIDDEN, 0,
				      false, false);

      // If there are any IRELATIVE relocations, they get GOT entries
      // in .got.plt after the jump slot relocations.
      this->got_irelative_ = new Output_data_space(4, "** GOT IRELATIVE PLT");
      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_WRITE),
				      this->got_irelative_,
				      got_plt_order, is_got_plt_relro);

      // If there are any TLSDESC relocations, they get GOT entries in
      // .got.plt after the jump slot entries.
      this->got_tlsdesc_ = new Output_data_got<32, false>();
      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_WRITE),
				      this->got_tlsdesc_,
				      got_plt_order, is_got_plt_relro);
    }

  return this->got_;
}

// Get the dynamic reloc section, creating it if necessary.

Target_i386::Reloc_section*
Target_i386::rel_dyn_section(Layout* layout)
{
  if (this->rel_dyn_ == NULL)
    {
      gold_assert(layout != NULL);
      this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
      layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
				      elfcpp::SHF_ALLOC, this->rel_dyn_,
				      ORDER_DYNAMIC_RELOCS, false);
    }
  return this->rel_dyn_;
}

// Get the section to use for IRELATIVE relocs, creating it if
// necessary.  These go in .rel.dyn, but only after all other dynamic
// relocations.  They need to follow the other dynamic relocations so
// that they can refer to global variables initialized by those
// relocs.

Target_i386::Reloc_section*
Target_i386::rel_irelative_section(Layout* layout)
{
  if (this->rel_irelative_ == NULL)
    {
      // Make sure we have already create the dynamic reloc section.
      this->rel_dyn_section(layout);
      this->rel_irelative_ = new Reloc_section(false);
      layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
				      elfcpp::SHF_ALLOC, this->rel_irelative_,
				      ORDER_DYNAMIC_RELOCS, false);
      gold_assert(this->rel_dyn_->output_section()
		  == this->rel_irelative_->output_section());
    }
  return this->rel_irelative_;
}

// Write the first three reserved words of the .got.plt section.
// The remainder of the section is written while writing the PLT
// in Output_data_plt_i386::do_write.

void
Output_data_got_plt_i386::do_write(Output_file* of)
{
  // The first entry in the GOT is the address of the .dynamic section
  // aka the PT_DYNAMIC segment.  The next two entries are reserved.
  // We saved space for them when we created the section in
  // Target_i386::got_section.
  const off_t got_file_offset = this->offset();
  gold_assert(this->data_size() >= 12);
  unsigned char* const got_view = of->get_output_view(got_file_offset, 12);
  Output_section* dynamic = this->layout_->dynamic_section();
  uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
  elfcpp::Swap<32, false>::writeval(got_view, dynamic_addr);
  memset(got_view + 4, 0, 8);
  of->write_output_view(got_file_offset, 12, got_view);
}

// Create the PLT section.  The ordinary .got section is an argument,
// since we need to refer to the start.  We also create our own .got
// section just for PLT entries.

Output_data_plt_i386::Output_data_plt_i386(Layout* layout,
					   uint64_t addralign,
					   Output_data_got_plt_i386* got_plt,
					   Output_data_space* got_irelative)
  : Output_section_data(addralign),
    tls_desc_rel_(NULL), irelative_rel_(NULL), got_plt_(got_plt),
    got_irelative_(got_irelative), count_(0), irelative_count_(0),
    global_ifuncs_(), local_ifuncs_()
{
  this->rel_ = new Reloc_section(false);
  layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
				  elfcpp::SHF_ALLOC, this->rel_,
				  ORDER_DYNAMIC_PLT_RELOCS, false);
}

void
Output_data_plt_i386::do_adjust_output_section(Output_section* os)
{
  // UnixWare sets the entsize of .plt to 4, and so does the old GNU
  // linker, and so do we.
  os->set_entsize(4);
}

// Add an entry to the PLT.

void
Output_data_plt_i386::add_entry(Symbol_table* symtab, Layout* layout,
				Symbol* gsym)
{
  gold_assert(!gsym->has_plt_offset());

  // Every PLT entry needs a reloc.
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    {
      gsym->set_plt_offset(this->irelative_count_ * this->get_plt_entry_size());
      ++this->irelative_count_;
      section_offset_type got_offset =
	this->got_irelative_->current_data_size();
      this->got_irelative_->set_current_data_size(got_offset + 4);
      Reloc_section* rel = this->rel_irelative(symtab, layout);
      rel->add_symbolless_global_addend(gsym, elfcpp::R_386_IRELATIVE,
					this->got_irelative_, got_offset);
      struct Global_ifunc gi;
      gi.sym = gsym;
      gi.got_offset = got_offset;
      this->global_ifuncs_.push_back(gi);
    }
  else
    {
      // When setting the PLT offset we skip the initial reserved PLT
      // entry.
      gsym->set_plt_offset((this->count_ + 1) * this->get_plt_entry_size());

      ++this->count_;

      section_offset_type got_offset = this->got_plt_->current_data_size();

      // Every PLT entry needs a GOT entry which points back to the
      // PLT entry (this will be changed by the dynamic linker,
      // normally lazily when the function is called).
      this->got_plt_->set_current_data_size(got_offset + 4);

      gsym->set_needs_dynsym_entry();
      this->rel_->add_global(gsym, elfcpp::R_386_JUMP_SLOT, this->got_plt_,
			     got_offset);
    }

  // Note that we don't need to save the symbol.  The contents of the
  // PLT are independent of which symbols are used.  The symbols only
  // appear in the relocations.
}

// Add an entry to the PLT for a local STT_GNU_IFUNC symbol.  Return
// the PLT offset.

unsigned int
Output_data_plt_i386::add_local_ifunc_entry(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<32, false>* relobj,
    unsigned int local_sym_index)
{
  unsigned int plt_offset = this->irelative_count_ * this->get_plt_entry_size();
  ++this->irelative_count_;

  section_offset_type got_offset = this->got_irelative_->current_data_size();

  // Every PLT entry needs a GOT entry which points back to the PLT
  // entry.
  this->got_irelative_->set_current_data_size(got_offset + 4);

  // Every PLT entry needs a reloc.
  Reloc_section* rel = this->rel_irelative(symtab, layout);
  rel->add_symbolless_local_addend(relobj, local_sym_index,
				   elfcpp::R_386_IRELATIVE,
				   this->got_irelative_, got_offset);

  struct Local_ifunc li;
  li.object = relobj;
  li.local_sym_index = local_sym_index;
  li.got_offset = got_offset;
  this->local_ifuncs_.push_back(li);

  return plt_offset;
}

// Return where the TLS_DESC relocations should go, creating it if
// necessary. These follow the JUMP_SLOT relocations.

Output_data_plt_i386::Reloc_section*
Output_data_plt_i386::rel_tls_desc(Layout* layout)
{
  if (this->tls_desc_rel_ == NULL)
    {
      this->tls_desc_rel_ = new Reloc_section(false);
      layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
				      elfcpp::SHF_ALLOC, this->tls_desc_rel_,
				      ORDER_DYNAMIC_PLT_RELOCS, false);
      gold_assert(this->tls_desc_rel_->output_section()
		  == this->rel_->output_section());
    }
  return this->tls_desc_rel_;
}

// Return where the IRELATIVE relocations should go in the PLT.  These
// follow the JUMP_SLOT and TLS_DESC relocations.

Output_data_plt_i386::Reloc_section*
Output_data_plt_i386::rel_irelative(Symbol_table* symtab, Layout* layout)
{
  if (this->irelative_rel_ == NULL)
    {
      // Make sure we have a place for the TLS_DESC relocations, in
      // case we see any later on.
      this->rel_tls_desc(layout);
      this->irelative_rel_ = new Reloc_section(false);
      layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
				      elfcpp::SHF_ALLOC, this->irelative_rel_,
				      ORDER_DYNAMIC_PLT_RELOCS, false);
      gold_assert(this->irelative_rel_->output_section()
		  == this->rel_->output_section());

      if (parameters->doing_static_link())
	{
	  // A statically linked executable will only have a .rel.plt
	  // section to hold R_386_IRELATIVE relocs for STT_GNU_IFUNC
	  // symbols.  The library will use these symbols to locate
	  // the IRELATIVE relocs at program startup time.
	  symtab->define_in_output_data("__rel_iplt_start", NULL,
					Symbol_table::PREDEFINED,
					this->irelative_rel_, 0, 0,
					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
					elfcpp::STV_HIDDEN, 0, false, true);
	  symtab->define_in_output_data("__rel_iplt_end", NULL,
					Symbol_table::PREDEFINED,
					this->irelative_rel_, 0, 0,
					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
					elfcpp::STV_HIDDEN, 0, true, true);
	}
    }
  return this->irelative_rel_;
}

// Return the PLT address to use for a global symbol.

uint64_t
Output_data_plt_i386::address_for_global(const Symbol* gsym)
{
  uint64_t offset = 0;
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    offset = (this->count_ + 1) * this->get_plt_entry_size();
  return this->address() + offset + gsym->plt_offset();
}

// Return the PLT address to use for a local symbol.  These are always
// IRELATIVE relocs.

uint64_t
Output_data_plt_i386::address_for_local(const Relobj* object,
					unsigned int r_sym)
{
  return (this->address()
	  + (this->count_ + 1) * this->get_plt_entry_size()
	  + object->local_plt_offset(r_sym));
}

// The first entry in the PLT for an executable.

const unsigned char Output_data_plt_i386_exec::first_plt_entry[plt_entry_size] =
{
  0xff, 0x35,	// pushl contents of memory address
  0, 0, 0, 0,	// replaced with address of .got + 4
  0xff, 0x25,	// jmp indirect
  0, 0, 0, 0,	// replaced with address of .got + 8
  0, 0, 0, 0	// unused
};

void
Output_data_plt_i386_exec::do_fill_first_plt_entry(
    unsigned char* pov,
    elfcpp::Elf_types<32>::Elf_Addr got_address)
{
  memcpy(pov, first_plt_entry, plt_entry_size);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_address + 4);
  elfcpp::Swap<32, false>::writeval(pov + 8, got_address + 8);
}

// The first entry in the PLT for a shared object.

const unsigned char Output_data_plt_i386_dyn::first_plt_entry[plt_entry_size] =
{
  0xff, 0xb3, 4, 0, 0, 0,	// pushl 4(%ebx)
  0xff, 0xa3, 8, 0, 0, 0,	// jmp *8(%ebx)
  0, 0, 0, 0			// unused
};

void
Output_data_plt_i386_dyn::do_fill_first_plt_entry(
    unsigned char* pov,
    elfcpp::Elf_types<32>::Elf_Addr)
{
  memcpy(pov, first_plt_entry, plt_entry_size);
}

// Subsequent entries in the PLT for an executable.

const unsigned char Output_data_plt_i386_exec::plt_entry[plt_entry_size] =
{
  0xff, 0x25,	// jmp indirect
  0, 0, 0, 0,	// replaced with address of symbol in .got
  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
};

unsigned int
Output_data_plt_i386_exec::do_fill_plt_entry(
    unsigned char* pov,
    elfcpp::Elf_types<32>::Elf_Addr got_address,
    unsigned int got_offset,
    unsigned int plt_offset,
    unsigned int plt_rel_offset)
{
  memcpy(pov, plt_entry, plt_entry_size);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 2,
					      got_address + got_offset);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 7, plt_rel_offset);
  elfcpp::Swap<32, false>::writeval(pov + 12, - (plt_offset + 12 + 4));
  return 6;
}

// Subsequent entries in the PLT for a shared object.

const unsigned char Output_data_plt_i386_dyn::plt_entry[plt_entry_size] =
{
  0xff, 0xa3,	// jmp *offset(%ebx)
  0, 0, 0, 0,	// replaced with offset of symbol in .got
  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
};

unsigned int
Output_data_plt_i386_dyn::do_fill_plt_entry(unsigned char* pov,
					    elfcpp::Elf_types<32>::Elf_Addr,
					    unsigned int got_offset,
					    unsigned int plt_offset,
					    unsigned int plt_rel_offset)
{
  memcpy(pov, plt_entry, plt_entry_size);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 7, plt_rel_offset);
  elfcpp::Swap<32, false>::writeval(pov + 12, - (plt_offset + 12 + 4));
  return 6;
}

// The .eh_frame unwind information for the PLT.

const unsigned char
Output_data_plt_i386::plt_eh_frame_cie[plt_eh_frame_cie_size] =
{
  1,				// CIE version.
  'z',				// Augmentation: augmentation size included.
  'R',				// Augmentation: FDE encoding included.
  '\0',				// End of augmentation string.
  1,				// Code alignment factor.
  0x7c,				// Data alignment factor.
  8,				// Return address column.
  1,				// Augmentation size.
  (elfcpp::DW_EH_PE_pcrel	// FDE encoding.
   | elfcpp::DW_EH_PE_sdata4),
  elfcpp::DW_CFA_def_cfa, 4, 4,	// DW_CFA_def_cfa: r4 (esp) ofs 4.
  elfcpp::DW_CFA_offset + 8, 1,	// DW_CFA_offset: r8 (eip) at cfa-4.
  elfcpp::DW_CFA_nop,		// Align to 16 bytes.
  elfcpp::DW_CFA_nop
};

const unsigned char
Output_data_plt_i386_standard::plt_eh_frame_fde[plt_eh_frame_fde_size] =
{
  0, 0, 0, 0,				// Replaced with offset to .plt.
  0, 0, 0, 0,				// Replaced with size of .plt.
  0,					// Augmentation size.
  elfcpp::DW_CFA_def_cfa_offset, 8,	// DW_CFA_def_cfa_offset: 8.
  elfcpp::DW_CFA_advance_loc + 6,	// Advance 6 to __PLT__ + 6.
  elfcpp::DW_CFA_def_cfa_offset, 12,	// DW_CFA_def_cfa_offset: 12.
  elfcpp::DW_CFA_advance_loc + 10,	// Advance 10 to __PLT__ + 16.
  elfcpp::DW_CFA_def_cfa_expression,	// DW_CFA_def_cfa_expression.
  11,					// Block length.
  elfcpp::DW_OP_breg4, 4,		// Push %esp + 4.
  elfcpp::DW_OP_breg8, 0,		// Push %eip.
  elfcpp::DW_OP_lit15,			// Push 0xf.
  elfcpp::DW_OP_and,			// & (%eip & 0xf).
  elfcpp::DW_OP_lit11,			// Push 0xb.
  elfcpp::DW_OP_ge,			// >= ((%eip & 0xf) >= 0xb)
  elfcpp::DW_OP_lit2,			// Push 2.
  elfcpp::DW_OP_shl,			// << (((%eip & 0xf) >= 0xb) << 2)
  elfcpp::DW_OP_plus,			// + ((((%eip&0xf)>=0xb)<<2)+%esp+4
  elfcpp::DW_CFA_nop,			// Align to 32 bytes.
  elfcpp::DW_CFA_nop,
  elfcpp::DW_CFA_nop,
  elfcpp::DW_CFA_nop
};

// Write out the PLT.  This uses the hand-coded instructions above,
// and adjusts them as needed.  This is all specified by the i386 ELF
// Processor Supplement.

void
Output_data_plt_i386::do_write(Output_file* of)
{
  const off_t offset = this->offset();
  const section_size_type oview_size =
    convert_to_section_size_type(this->data_size());
  unsigned char* const oview = of->get_output_view(offset, oview_size);

  const off_t got_file_offset = this->got_plt_->offset();
  gold_assert(parameters->incremental_update()
	      || (got_file_offset + this->got_plt_->data_size()
		  == this->got_irelative_->offset()));
  const section_size_type got_size =
    convert_to_section_size_type(this->got_plt_->data_size()
				 + this->got_irelative_->data_size());

  unsigned char* const got_view = of->get_output_view(got_file_offset,
						      got_size);

  unsigned char* pov = oview;

  elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address();
  elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address();

  this->fill_first_plt_entry(pov, got_address);
  pov += this->get_plt_entry_size();

  // The first three entries in the GOT are reserved, and are written
  // by Output_data_got_plt_i386::do_write.
  unsigned char* got_pov = got_view + 12;

  const int rel_size = elfcpp::Elf_sizes<32>::rel_size;

  unsigned int plt_offset = this->get_plt_entry_size();
  unsigned int plt_rel_offset = 0;
  unsigned int got_offset = 12;
  const unsigned int count = this->count_ + this->irelative_count_;
  for (unsigned int i = 0;
       i < count;
       ++i,
	 pov += this->get_plt_entry_size(),
	 got_pov += 4,
	 plt_offset += this->get_plt_entry_size(),
	 plt_rel_offset += rel_size,
	 got_offset += 4)
    {
      // Set and adjust the PLT entry itself.
      unsigned int lazy_offset = this->fill_plt_entry(pov,
						      got_address,
						      got_offset,
						      plt_offset,
						      plt_rel_offset);

      // Set the entry in the GOT.
      elfcpp::Swap<32, false>::writeval(got_pov,
					plt_address + plt_offset + lazy_offset);
    }

  // If any STT_GNU_IFUNC symbols have PLT entries, we need to change
  // the GOT to point to the actual symbol value, rather than point to
  // the PLT entry.  That will let the dynamic linker call the right
  // function when resolving IRELATIVE relocations.
  unsigned char* got_irelative_view = got_view + this->got_plt_->data_size();
  for (std::vector<Global_ifunc>::const_iterator p =
	 this->global_ifuncs_.begin();
       p != this->global_ifuncs_.end();
       ++p)
    {
      const Sized_symbol<32>* ssym =
	static_cast<const Sized_symbol<32>*>(p->sym);
      elfcpp::Swap<32, false>::writeval(got_irelative_view + p->got_offset,
					ssym->value());
    }

  for (std::vector<Local_ifunc>::const_iterator p =
	 this->local_ifuncs_.begin();
       p != this->local_ifuncs_.end();
       ++p)
    {
      const Symbol_value<32>* psymval =
	p->object->local_symbol(p->local_sym_index);
      elfcpp::Swap<32, false>::writeval(got_irelative_view + p->got_offset,
					psymval->value(p->object, 0));
    }

  gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
  gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);

  of->write_output_view(offset, oview_size, oview);
  of->write_output_view(got_file_offset, got_size, got_view);
}

// Create the PLT section.

void
Target_i386::make_plt_section(Symbol_table* symtab, Layout* layout)
{
  if (this->plt_ == NULL)
    {
      // Create the GOT sections first.
      this->got_section(symtab, layout);

      const bool dyn = parameters->options().output_is_position_independent();
      this->plt_ = this->make_data_plt(layout,
				       this->got_plt_,
				       this->got_irelative_,
				       dyn);

      // Add unwind information if requested.
      if (parameters->options().ld_generated_unwind_info())
	this->plt_->add_eh_frame(layout);

      layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_EXECINSTR),
				      this->plt_, ORDER_PLT, false);

      // Make the sh_info field of .rel.plt point to .plt.
      Output_section* rel_plt_os = this->plt_->rel_plt()->output_section();
      rel_plt_os->set_info_section(this->plt_->output_section());
    }
}

// Create a PLT entry for a global symbol.

void
Target_i386::make_plt_entry(Symbol_table* symtab, Layout* layout, Symbol* gsym)
{
  if (gsym->has_plt_offset())
    return;
  if (this->plt_ == NULL)
    this->make_plt_section(symtab, layout);
  this->plt_->add_entry(symtab, layout, gsym);
}

// Make a PLT entry for a local STT_GNU_IFUNC symbol.

void
Target_i386::make_local_ifunc_plt_entry(Symbol_table* symtab, Layout* layout,
					Sized_relobj_file<32, false>* relobj,
					unsigned int local_sym_index)
{
  if (relobj->local_has_plt_offset(local_sym_index))
    return;
  if (this->plt_ == NULL)
    this->make_plt_section(symtab, layout);
  unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout,
							      relobj,
							      local_sym_index);
  relobj->set_local_plt_offset(local_sym_index, plt_offset);
}

// Return the number of entries in the PLT.

unsigned int
Target_i386::plt_entry_count() const
{
  if (this->plt_ == NULL)
    return 0;
  return this->plt_->entry_count();
}

// Return the offset of the first non-reserved PLT entry.

unsigned int
Target_i386::first_plt_entry_offset() const
{
  if (this->plt_ == NULL)
    return 0;
  return this->plt_->first_plt_entry_offset();
}

// Return the size of each PLT entry.

unsigned int
Target_i386::plt_entry_size() const
{
  if (this->plt_ == NULL)
    return 0;
  return this->plt_->get_plt_entry_size();
}

// Get the section to use for TLS_DESC relocations.

Target_i386::Reloc_section*
Target_i386::rel_tls_desc_section(Layout* layout) const
{
  return this->plt_section()->rel_tls_desc(layout);
}

// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.

void
Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
{
  if (this->tls_base_symbol_defined_)
    return;

  Output_segment* tls_segment = layout->tls_segment();
  if (tls_segment != NULL)
    {
      bool is_exec = parameters->options().output_is_executable();
      symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
				       Symbol_table::PREDEFINED,
				       tls_segment, 0, 0,
				       elfcpp::STT_TLS,
				       elfcpp::STB_LOCAL,
				       elfcpp::STV_HIDDEN, 0,
				       (is_exec
					? Symbol::SEGMENT_END
					: Symbol::SEGMENT_START),
				       true);
    }
  this->tls_base_symbol_defined_ = true;
}

// Create a GOT entry for the TLS module index.

unsigned int
Target_i386::got_mod_index_entry(Symbol_table* symtab, Layout* layout,
				 Sized_relobj_file<32, false>* object)
{
  if (this->got_mod_index_offset_ == -1U)
    {
      gold_assert(symtab != NULL && layout != NULL && object != NULL);
      Reloc_section* rel_dyn = this->rel_dyn_section(layout);
      Output_data_got<32, false>* got = this->got_section(symtab, layout);
      unsigned int got_offset = got->add_constant(0);
      rel_dyn->add_local(object, 0, elfcpp::R_386_TLS_DTPMOD32, got,
			 got_offset);
      got->add_constant(0);
      this->got_mod_index_offset_ = got_offset;
    }
  return this->got_mod_index_offset_;
}

// Optimize the TLS relocation type based on what we know about the
// symbol.  IS_FINAL is true if the final address of this symbol is
// known at link time.

tls::Tls_optimization
Target_i386::optimize_tls_reloc(bool is_final, int r_type)
{
  // If we are generating a shared library, then we can't do anything
  // in the linker.
  if (parameters->options().shared())
    return tls::TLSOPT_NONE;

  switch (r_type)
    {
    case elfcpp::R_386_TLS_GD:
    case elfcpp::R_386_TLS_GOTDESC:
    case elfcpp::R_386_TLS_DESC_CALL:
      // These are General-Dynamic which permits fully general TLS
      // access.  Since we know that we are generating an executable,
      // we can convert this to Initial-Exec.  If we also know that
      // this is a local symbol, we can further switch to Local-Exec.
      if (is_final)
	return tls::TLSOPT_TO_LE;
      return tls::TLSOPT_TO_IE;

    case elfcpp::R_386_TLS_LDM:
      // This is Local-Dynamic, which refers to a local symbol in the
      // dynamic TLS block.  Since we know that we generating an
      // executable, we can switch to Local-Exec.
      return tls::TLSOPT_TO_LE;

    case elfcpp::R_386_TLS_LDO_32:
      // Another type of Local-Dynamic relocation.
      return tls::TLSOPT_TO_LE;

    case elfcpp::R_386_TLS_IE:
    case elfcpp::R_386_TLS_GOTIE:
    case elfcpp::R_386_TLS_IE_32:
      // These are Initial-Exec relocs which get the thread offset
      // from the GOT.  If we know that we are linking against the
      // local symbol, we can switch to Local-Exec, which links the
      // thread offset into the instruction.
      if (is_final)
	return tls::TLSOPT_TO_LE;
      return tls::TLSOPT_NONE;

    case elfcpp::R_386_TLS_LE:
    case elfcpp::R_386_TLS_LE_32:
      // When we already have Local-Exec, there is nothing further we
      // can do.
      return tls::TLSOPT_NONE;

    default:
      gold_unreachable();
    }
}

// Get the Reference_flags for a particular relocation.

int
Target_i386::Scan::get_reference_flags(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_386_NONE:
    case elfcpp::R_386_GNU_VTINHERIT:
    case elfcpp::R_386_GNU_VTENTRY:
    case elfcpp::R_386_GOTPC:
      // No symbol reference.
      return 0;

    case elfcpp::R_386_32:
    case elfcpp::R_386_16:
    case elfcpp::R_386_8:
      return Symbol::ABSOLUTE_REF;

    case elfcpp::R_386_PC32:
    case elfcpp::R_386_PC16:
    case elfcpp::R_386_PC8:
    case elfcpp::R_386_GOTOFF:
      return Symbol::RELATIVE_REF;

    case elfcpp::R_386_PLT32:
      return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;

    case elfcpp::R_386_GOT32:
    case elfcpp::R_386_GOT32X:
      // Absolute in GOT.
      return Symbol::ABSOLUTE_REF;

    case elfcpp::R_386_TLS_GD:            // Global-dynamic
    case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    case elfcpp::R_386_TLS_DESC_CALL:
    case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    case elfcpp::R_386_TLS_IE:            // Initial-exec
    case elfcpp::R_386_TLS_IE_32:
    case elfcpp::R_386_TLS_GOTIE:
    case elfcpp::R_386_TLS_LE:            // Local-exec
    case elfcpp::R_386_TLS_LE_32:
      return Symbol::TLS_REF;

    case elfcpp::R_386_COPY:
    case elfcpp::R_386_GLOB_DAT:
    case elfcpp::R_386_JUMP_SLOT:
    case elfcpp::R_386_RELATIVE:
    case elfcpp::R_386_IRELATIVE:
    case elfcpp::R_386_TLS_TPOFF:
    case elfcpp::R_386_TLS_DTPMOD32:
    case elfcpp::R_386_TLS_DTPOFF32:
    case elfcpp::R_386_TLS_TPOFF32:
    case elfcpp::R_386_TLS_DESC:
    case elfcpp::R_386_32PLT:
    case elfcpp::R_386_TLS_GD_32:
    case elfcpp::R_386_TLS_GD_PUSH:
    case elfcpp::R_386_TLS_GD_CALL:
    case elfcpp::R_386_TLS_GD_POP:
    case elfcpp::R_386_TLS_LDM_32:
    case elfcpp::R_386_TLS_LDM_PUSH:
    case elfcpp::R_386_TLS_LDM_CALL:
    case elfcpp::R_386_TLS_LDM_POP:
    case elfcpp::R_386_USED_BY_INTEL_200:
    default:
      // Not expected.  We will give an error later.
      return 0;
    }
}

// Report an unsupported relocation against a local symbol.

void
Target_i386::Scan::unsupported_reloc_local(Sized_relobj_file<32, false>* object,
					   unsigned int r_type)
{
  gold_error(_("%s: unsupported reloc %u against local symbol"),
	     object->name().c_str(), r_type);
}

// Return whether we need to make a PLT entry for a relocation of a
// given type against a STT_GNU_IFUNC symbol.

bool
Target_i386::Scan::reloc_needs_plt_for_ifunc(
    Sized_relobj_file<32, false>* object,
    unsigned int r_type)
{
  int flags = Scan::get_reference_flags(r_type);
  if (flags & Symbol::TLS_REF)
    gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
	       object->name().c_str(), r_type);
  return flags != 0;
}

// Scan a relocation for a local symbol.

inline void
Target_i386::Scan::local(Symbol_table* symtab,
			 Layout* layout,
			 Target_i386* target,
			 Sized_relobj_file<32, false>* object,
			 unsigned int data_shndx,
			 Output_section* output_section,
			 const elfcpp::Rel<32, false>& reloc,
			 unsigned int r_type,
			 const elfcpp::Sym<32, false>& lsym,
			 bool is_discarded)
{
  if (is_discarded)
    return;

  // A local STT_GNU_IFUNC symbol may require a PLT entry.
  if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC
      && this->reloc_needs_plt_for_ifunc(object, r_type))
    {
      unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
      target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
    }

  switch (r_type)
    {
    case elfcpp::R_386_NONE:
    case elfcpp::R_386_GNU_VTINHERIT:
    case elfcpp::R_386_GNU_VTENTRY:
      break;

    case elfcpp::R_386_32:
      // If building a shared library (or a position-independent
      // executable), we need to create a dynamic relocation for
      // this location. The relocation applied at link time will
      // apply the link-time value, so we flag the location with
      // an R_386_RELATIVE relocation so the dynamic loader can
      // relocate it easily.
      if (parameters->options().output_is_position_independent())
	{
	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
	  rel_dyn->add_local_relative(object, r_sym, elfcpp::R_386_RELATIVE,
				      output_section, data_shndx,
				      reloc.get_r_offset());
	}
      break;

    case elfcpp::R_386_16:
    case elfcpp::R_386_8:
      // If building a shared library (or a position-independent
      // executable), we need to create a dynamic relocation for
      // this location. Because the addend needs to remain in the
      // data section, we need to be careful not to apply this
      // relocation statically.
      if (parameters->options().output_is_position_independent())
	{
	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
	  if (lsym.get_st_type() != elfcpp::STT_SECTION)
	    rel_dyn->add_local(object, r_sym, r_type, output_section,
			       data_shndx, reloc.get_r_offset());
	  else
	    {
	      gold_assert(lsym.get_st_value() == 0);
	      unsigned int shndx = lsym.get_st_shndx();
	      bool is_ordinary;
	      shndx = object->adjust_sym_shndx(r_sym, shndx,
					       &is_ordinary);
	      if (!is_ordinary)
		object->error(_("section symbol %u has bad shndx %u"),
			      r_sym, shndx);
	      else
		rel_dyn->add_local_section(object, shndx,
					   r_type, output_section,
					   data_shndx, reloc.get_r_offset());
	    }
	}
      break;

    case elfcpp::R_386_PC32:
    case elfcpp::R_386_PC16:
    case elfcpp::R_386_PC8:
      break;

    case elfcpp::R_386_PLT32:
      // Since we know this is a local symbol, we can handle this as a
      // PC32 reloc.
      break;

    case elfcpp::R_386_GOTOFF:
    case elfcpp::R_386_GOTPC:
      // We need a GOT section.
      target->got_section(symtab, layout);
      break;

    case elfcpp::R_386_GOT32:
    case elfcpp::R_386_GOT32X:
      {
	// We need GOT section.
	Output_data_got<32, false>* got = target->got_section(symtab, layout);

	// If the relocation symbol isn't IFUNC,
	// and is local, then we will convert
	// mov foo@GOT(%reg), %reg
	// to
	// lea foo@GOTOFF(%reg), %reg
	// in Relocate::relocate.
	if (reloc.get_r_offset() >= 2
	    && lsym.get_st_type() != elfcpp::STT_GNU_IFUNC)
	  {
	    section_size_type stype;
	    const unsigned char* view = object->section_contents(data_shndx,
								 &stype, true);
	    if (view[reloc.get_r_offset() - 2] == 0x8b)
	      break;
	  }

	// Otherwise, the symbol requires a GOT entry.
	unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());

	// For a STT_GNU_IFUNC symbol we want the PLT offset.  That
	// lets function pointers compare correctly with shared
	// libraries.  Otherwise we would need an IRELATIVE reloc.
	bool is_new;
	if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC)
	  is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
	else
	  is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
	if (is_new)
	  {
	    // If we are generating a shared object, we need to add a
	    // dynamic RELATIVE relocation for this symbol's GOT entry.
	    if (parameters->options().output_is_position_independent())
	      {
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		unsigned int got_offset =
		  object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
		rel_dyn->add_local_relative(object, r_sym,
					    elfcpp::R_386_RELATIVE,
					    got, got_offset);
	      }
	  }
      }
      break;

      // These are relocations which should only be seen by the
      // dynamic linker, and should never be seen here.
    case elfcpp::R_386_COPY:
    case elfcpp::R_386_GLOB_DAT:
    case elfcpp::R_386_JUMP_SLOT:
    case elfcpp::R_386_RELATIVE:
    case elfcpp::R_386_IRELATIVE:
    case elfcpp::R_386_TLS_TPOFF:
    case elfcpp::R_386_TLS_DTPMOD32:
    case elfcpp::R_386_TLS_DTPOFF32:
    case elfcpp::R_386_TLS_TPOFF32:
    case elfcpp::R_386_TLS_DESC:
      gold_error(_("%s: unexpected reloc %u in object file"),
		 object->name().c_str(), r_type);
      break;

      // These are initial TLS relocs, which are expected when
      // linking.
    case elfcpp::R_386_TLS_GD:            // Global-dynamic
    case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    case elfcpp::R_386_TLS_DESC_CALL:
    case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    case elfcpp::R_386_TLS_IE:            // Initial-exec
    case elfcpp::R_386_TLS_IE_32:
    case elfcpp::R_386_TLS_GOTIE:
    case elfcpp::R_386_TLS_LE:            // Local-exec
    case elfcpp::R_386_TLS_LE_32:
      {
	bool output_is_shared = parameters->options().shared();
	const tls::Tls_optimization optimized_type
	    = Target_i386::optimize_tls_reloc(!output_is_shared, r_type);
	switch (r_type)
	  {
	  case elfcpp::R_386_TLS_GD:          // Global-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a pair of GOT entries for the module index and
		// dtv-relative offset.
		Output_data_got<32, false>* got
		    = target->got_section(symtab, layout);
		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
		unsigned int shndx = lsym.get_st_shndx();
		bool is_ordinary;
		shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
		if (!is_ordinary)
		  object->error(_("local symbol %u has bad shndx %u"),
			      r_sym, shndx);
		else
		  got->add_local_pair_with_rel(object, r_sym, shndx,
					       GOT_TYPE_TLS_PAIR,
					       target->rel_dyn_section(layout),
					       elfcpp::R_386_TLS_DTPMOD32);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_local(object, r_type);
	    break;

	  case elfcpp::R_386_TLS_GOTDESC:     // Global-dynamic (from ~oliva)
	    target->define_tls_base_symbol(symtab, layout);
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a double GOT entry with an R_386_TLS_DESC
		// reloc.  The R_386_TLS_DESC reloc is resolved
		// lazily, so the GOT entry needs to be in an area in
		// .got.plt, not .got.  Call got_section to make sure
		// the section has been created.
		target->got_section(symtab, layout);
		Output_data_got<32, false>* got = target->got_tlsdesc_section();
		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
		if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC))
		  {
		    unsigned int got_offset = got->add_constant(0);
		    // The local symbol value is stored in the second
		    // GOT entry.
		    got->add_local(object, r_sym, GOT_TYPE_TLS_DESC);
		    // That set the GOT offset of the local symbol to
		    // point to the second entry, but we want it to
		    // point to the first.
		    object->set_local_got_offset(r_sym, GOT_TYPE_TLS_DESC,
						 got_offset);
		    Reloc_section* rt = target->rel_tls_desc_section(layout);
		    rt->add_absolute(elfcpp::R_386_TLS_DESC, got, got_offset);
		  }
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_local(object, r_type);
	    break;

	  case elfcpp::R_386_TLS_DESC_CALL:
	    break;

	  case elfcpp::R_386_TLS_LDM:         // Local-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the module index.
		target->got_mod_index_entry(symtab, layout, object);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_local(object, r_type);
	    break;

	  case elfcpp::R_386_TLS_LDO_32:      // Alternate local-dynamic
	    break;

	  case elfcpp::R_386_TLS_IE:          // Initial-exec
	  case elfcpp::R_386_TLS_IE_32:
	  case elfcpp::R_386_TLS_GOTIE:
	    layout->set_has_static_tls();
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// For the R_386_TLS_IE relocation, we need to create a
		// dynamic relocation when building a shared library.
		if (r_type == elfcpp::R_386_TLS_IE
		    && parameters->options().shared())
		  {
		    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		    unsigned int r_sym
			= elfcpp::elf_r_sym<32>(reloc.get_r_info());
		    rel_dyn->add_local_relative(object, r_sym,
						elfcpp::R_386_RELATIVE,
						output_section, data_shndx,
						reloc.get_r_offset());
		  }
		// Create a GOT entry for the tp-relative offset.
		Output_data_got<32, false>* got
		    = target->got_section(symtab, layout);
		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
					   ? elfcpp::R_386_TLS_TPOFF32
					   : elfcpp::R_386_TLS_TPOFF);
		unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
					 ? GOT_TYPE_TLS_OFFSET
					 : GOT_TYPE_TLS_NOFFSET);
		got->add_local_with_rel(object, r_sym, got_type,
					target->rel_dyn_section(layout),
					dyn_r_type);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_local(object, r_type);
	    break;

	  case elfcpp::R_386_TLS_LE:          // Local-exec
	  case elfcpp::R_386_TLS_LE_32:
	    layout->set_has_static_tls();
	    if (output_is_shared)
	      {
		// We need to create a dynamic relocation.
		gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_LE_32
					   ? elfcpp::R_386_TLS_TPOFF32
					   : elfcpp::R_386_TLS_TPOFF);
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_local(object, r_sym, dyn_r_type, output_section,
				   data_shndx, reloc.get_r_offset());
	      }
	    break;

	  default:
	    gold_unreachable();
	  }
      }
      break;

    case elfcpp::R_386_32PLT:
    case elfcpp::R_386_TLS_GD_32:
    case elfcpp::R_386_TLS_GD_PUSH:
    case elfcpp::R_386_TLS_GD_CALL:
    case elfcpp::R_386_TLS_GD_POP:
    case elfcpp::R_386_TLS_LDM_32:
    case elfcpp::R_386_TLS_LDM_PUSH:
    case elfcpp::R_386_TLS_LDM_CALL:
    case elfcpp::R_386_TLS_LDM_POP:
    case elfcpp::R_386_USED_BY_INTEL_200:
    default:
      unsupported_reloc_local(object, r_type);
      break;
    }
}

// Report an unsupported relocation against a global symbol.

void
Target_i386::Scan::unsupported_reloc_global(
    Sized_relobj_file<32, false>* object,
    unsigned int r_type,
    Symbol* gsym)
{
  gold_error(_("%s: unsupported reloc %u against global symbol %s"),
	     object->name().c_str(), r_type, gsym->demangled_name().c_str());
}

inline bool
Target_i386::Scan::possible_function_pointer_reloc(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_386_32:
    case elfcpp::R_386_16:
    case elfcpp::R_386_8:
    case elfcpp::R_386_GOTOFF:
    case elfcpp::R_386_GOT32:
    case elfcpp::R_386_GOT32X:
      {
	return true;
      }
    default:
      return false;
    }
  return false;
}

inline bool
Target_i386::Scan::local_reloc_may_be_function_pointer(
  Symbol_table* ,
  Layout* ,
  Target_i386* ,
  Sized_relobj_file<32, false>* ,
  unsigned int ,
  Output_section* ,
  const elfcpp::Rel<32, false>& ,
  unsigned int r_type,
  const elfcpp::Sym<32, false>&)
{
  return possible_function_pointer_reloc(r_type);
}

inline bool
Target_i386::Scan::global_reloc_may_be_function_pointer(
  Symbol_table* ,
  Layout* ,
  Target_i386* ,
  Sized_relobj_file<32, false>* ,
  unsigned int ,
  Output_section* ,
  const elfcpp::Rel<32, false>& ,
  unsigned int r_type,
  Symbol*)
{
  return possible_function_pointer_reloc(r_type);
}

// Scan a relocation for a global symbol.

inline void
Target_i386::Scan::global(Symbol_table* symtab,
				 Layout* layout,
				 Target_i386* target,
				 Sized_relobj_file<32, false>* object,
				 unsigned int data_shndx,
				 Output_section* output_section,
				 const elfcpp::Rel<32, false>& reloc,
				 unsigned int r_type,
				 Symbol* gsym)
{
  // A STT_GNU_IFUNC symbol may require a PLT entry.
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && this->reloc_needs_plt_for_ifunc(object, r_type))
    target->make_plt_entry(symtab, layout, gsym);

  switch (r_type)
    {
    case elfcpp::R_386_NONE:
    case elfcpp::R_386_GNU_VTINHERIT:
    case elfcpp::R_386_GNU_VTENTRY:
      break;

    case elfcpp::R_386_32:
    case elfcpp::R_386_16:
    case elfcpp::R_386_8:
      {
	// Make a PLT entry if necessary.
	if (gsym->needs_plt_entry())
	  {
	    target->make_plt_entry(symtab, layout, gsym);
	    // Since this is not a PC-relative relocation, we may be
	    // taking the address of a function. In that case we need to
	    // set the entry in the dynamic symbol table to the address of
	    // the PLT entry.
	    if (gsym->is_from_dynobj() && !parameters->options().shared())
	      gsym->set_needs_dynsym_value();
	  }
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
	  {
	    if (!parameters->options().output_is_position_independent()
		&& gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, reloc);
	      }
	    else if (r_type == elfcpp::R_386_32
		     && gsym->type() == elfcpp::STT_GNU_IFUNC
		     && gsym->can_use_relative_reloc(false)
		     && !gsym->is_from_dynobj()
		     && !gsym->is_undefined()
		     && !gsym->is_preemptible())
	      {
		// Use an IRELATIVE reloc for a locally defined
		// STT_GNU_IFUNC symbol.  This makes a function
		// address in a PIE executable match the address in a
		// shared library that it links against.
		Reloc_section* rel_dyn = target->rel_irelative_section(layout);
		rel_dyn->add_symbolless_global_addend(gsym,
						      elfcpp::R_386_IRELATIVE,
						      output_section,
						      object, data_shndx,
						      reloc.get_r_offset());
	      }
	    else if (r_type == elfcpp::R_386_32
		     && gsym->can_use_relative_reloc(false))
	      {
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
					     output_section, object,
					     data_shndx, reloc.get_r_offset());
	      }
	    else
	      {
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global(gsym, r_type, output_section, object,
				    data_shndx, reloc.get_r_offset());
	      }
	  }
      }
      break;

    case elfcpp::R_386_PC32:
    case elfcpp::R_386_PC16:
    case elfcpp::R_386_PC8:
      {
	// Make a PLT entry if necessary.
	if (gsym->needs_plt_entry())
	  {
	    // These relocations are used for function calls only in
	    // non-PIC code.  For a 32-bit relocation in a shared library,
	    // we'll need a text relocation anyway, so we can skip the
	    // PLT entry and let the dynamic linker bind the call directly
	    // to the target.  For smaller relocations, we should use a
	    // PLT entry to ensure that the call can reach.
	    if (!parameters->options().shared()
		|| r_type != elfcpp::R_386_PC32)
	      target->make_plt_entry(symtab, layout, gsym);
	  }
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
	  {
	    if (parameters->options().output_is_executable()
		&& gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, reloc);
	      }
	    else
	      {
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global(gsym, r_type, output_section, object,
				    data_shndx, reloc.get_r_offset());
	      }
	  }
      }
      break;

    case elfcpp::R_386_GOT32:
    case elfcpp::R_386_GOT32X:
      {
	// The symbol requires a GOT section.
	Output_data_got<32, false>* got = target->got_section(symtab, layout);

	// If we convert this from
	// mov foo@GOT(%reg), %reg
	// to
	// lea foo@GOTOFF(%reg), %reg
	// in Relocate::relocate, then there is nothing to do here.
	if (reloc.get_r_offset() >= 2
	    && Target_i386::can_convert_mov_to_lea(gsym))
	  {
	    section_size_type stype;
	    const unsigned char* view = object->section_contents(data_shndx,
								 &stype, true);
	    if (view[reloc.get_r_offset() - 2] == 0x8b)
	      break;
	  }

	if (gsym->final_value_is_known())
	  {
	    // For a STT_GNU_IFUNC symbol we want the PLT address.
	    if (gsym->type() == elfcpp::STT_GNU_IFUNC)
	      got->add_global_plt(gsym, GOT_TYPE_STANDARD);
	    else
	      got->add_global(gsym, GOT_TYPE_STANDARD);
	  }
	else
	  {
	    // If this symbol is not fully resolved, we need to add a
	    // GOT entry with a dynamic relocation.
	    Reloc_section* rel_dyn = target->rel_dyn_section(layout);

	    // Use a GLOB_DAT rather than a RELATIVE reloc if:
	    //
	    // 1) The symbol may be defined in some other module.
	    //
	    // 2) We are building a shared library and this is a
	    // protected symbol; using GLOB_DAT means that the dynamic
	    // linker can use the address of the PLT in the main
	    // executable when appropriate so that function address
	    // comparisons work.
	    //
	    // 3) This is a STT_GNU_IFUNC symbol in position dependent
	    // code, again so that function address comparisons work.
	    if (gsym->is_from_dynobj()
		|| gsym->is_undefined()
		|| gsym->is_preemptible()
		|| (gsym->visibility() == elfcpp::STV_PROTECTED
		    && parameters->options().shared())
		|| (gsym->type() == elfcpp::STT_GNU_IFUNC
		    && parameters->options().output_is_position_independent()))
	      got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
				       rel_dyn, elfcpp::R_386_GLOB_DAT);
	    else
	      {
		// For a STT_GNU_IFUNC symbol we want to write the PLT
		// offset into the GOT, so that function pointer
		// comparisons work correctly.
		bool is_new;
		if (gsym->type() != elfcpp::STT_GNU_IFUNC)
		  is_new = got->add_global(gsym, GOT_TYPE_STANDARD);
		else
		  {
		    is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD);
		    // Tell the dynamic linker to use the PLT address
		    // when resolving relocations.
		    if (gsym->is_from_dynobj()
			&& !parameters->options().shared())
		      gsym->set_needs_dynsym_value();
		  }
		if (is_new)
		  {
		    unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
		    rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
						 got, got_off);
		  }
	      }
	  }
      }
      break;

    case elfcpp::R_386_PLT32:
      // If the symbol is fully resolved, this is just a PC32 reloc.
      // Otherwise we need a PLT entry.
      if (gsym->final_value_is_known())
	break;
      // If building a shared library, we can also skip the PLT entry
      // if the symbol is defined in the output file and is protected
      // or hidden.
      if (gsym->is_defined()
	  && !gsym->is_from_dynobj()
	  && !gsym->is_preemptible())
	break;
      target->make_plt_entry(symtab, layout, gsym);
      break;

    case elfcpp::R_386_GOTOFF:
      // A GOT-relative reference must resolve locally.
      if (!gsym->is_defined())
        gold_error(_("%s: relocation R_386_GOTOFF against undefined symbol %s"
		     " cannot be used when making a shared object"),
		   object->name().c_str(), gsym->name());
      else if (gsym->is_from_dynobj())
        gold_error(_("%s: relocation R_386_GOTOFF against external symbol %s"
		     " cannot be used when making a shared object"),
		   object->name().c_str(), gsym->name());
      else if (gsym->is_preemptible())
        gold_error(_("%s: relocation R_386_GOTOFF against preemptible symbol %s"
		     " cannot be used when making a shared object"),
		   object->name().c_str(), gsym->name());
      // We need a GOT section.
      target->got_section(symtab, layout);
      break;

    case elfcpp::R_386_GOTPC:
      // We need a GOT section.
      target->got_section(symtab, layout);
      break;

      // These are relocations which should only be seen by the
      // dynamic linker, and should never be seen here.
    case elfcpp::R_386_COPY:
    case elfcpp::R_386_GLOB_DAT:
    case elfcpp::R_386_JUMP_SLOT:
    case elfcpp::R_386_RELATIVE:
    case elfcpp::R_386_IRELATIVE:
    case elfcpp::R_386_TLS_TPOFF:
    case elfcpp::R_386_TLS_DTPMOD32:
    case elfcpp::R_386_TLS_DTPOFF32:
    case elfcpp::R_386_TLS_TPOFF32:
    case elfcpp::R_386_TLS_DESC:
      gold_error(_("%s: unexpected reloc %u in object file"),
		 object->name().c_str(), r_type);
      break;

      // These are initial tls relocs, which are expected when
      // linking.
    case elfcpp::R_386_TLS_GD:            // Global-dynamic
    case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    case elfcpp::R_386_TLS_DESC_CALL:
    case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    case elfcpp::R_386_TLS_IE:            // Initial-exec
    case elfcpp::R_386_TLS_IE_32:
    case elfcpp::R_386_TLS_GOTIE:
    case elfcpp::R_386_TLS_LE:            // Local-exec
    case elfcpp::R_386_TLS_LE_32:
      {
	const bool is_final = gsym->final_value_is_known();
	const tls::Tls_optimization optimized_type
	    = Target_i386::optimize_tls_reloc(is_final, r_type);
	switch (r_type)
	  {
	  case elfcpp::R_386_TLS_GD:          // Global-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a pair of GOT entries for the module index and
		// dtv-relative offset.
		Output_data_got<32, false>* got
		    = target->got_section(symtab, layout);
		got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
					     target->rel_dyn_section(layout),
					     elfcpp::R_386_TLS_DTPMOD32,
					     elfcpp::R_386_TLS_DTPOFF32);
	      }
	    else if (optimized_type == tls::TLSOPT_TO_IE)
	      {
		// Create a GOT entry for the tp-relative offset.
		Output_data_got<32, false>* got
		    = target->got_section(symtab, layout);
		got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
					 target->rel_dyn_section(layout),
					 elfcpp::R_386_TLS_TPOFF);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_global(object, r_type, gsym);
	    break;

	  case elfcpp::R_386_TLS_GOTDESC:     // Global-dynamic (~oliva url)
	    target->define_tls_base_symbol(symtab, layout);
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a double GOT entry with an R_386_TLS_DESC
		// reloc.  The R_386_TLS_DESC reloc is resolved
		// lazily, so the GOT entry needs to be in an area in
		// .got.plt, not .got.  Call got_section to make sure
		// the section has been created.
		target->got_section(symtab, layout);
		Output_data_got<32, false>* got = target->got_tlsdesc_section();
		Reloc_section* rt = target->rel_tls_desc_section(layout);
		got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt,
					     elfcpp::R_386_TLS_DESC, 0);
	      }
	    else if (optimized_type == tls::TLSOPT_TO_IE)
	      {
		// Create a GOT entry for the tp-relative offset.
		Output_data_got<32, false>* got
		    = target->got_section(symtab, layout);
		got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
					 target->rel_dyn_section(layout),
					 elfcpp::R_386_TLS_TPOFF);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_global(object, r_type, gsym);
	    break;

	  case elfcpp::R_386_TLS_DESC_CALL:
	    break;

	  case elfcpp::R_386_TLS_LDM:         // Local-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the module index.
		target->got_mod_index_entry(symtab, layout, object);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_global(object, r_type, gsym);
	    break;

	  case elfcpp::R_386_TLS_LDO_32:      // Alternate local-dynamic
	    break;

	  case elfcpp::R_386_TLS_IE:          // Initial-exec
	  case elfcpp::R_386_TLS_IE_32:
	  case elfcpp::R_386_TLS_GOTIE:
	    layout->set_has_static_tls();
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// For the R_386_TLS_IE relocation, we need to create a
		// dynamic relocation when building a shared library.
		if (r_type == elfcpp::R_386_TLS_IE
		    && parameters->options().shared())
		  {
		    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		    rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
						 output_section, object,
						 data_shndx,
						 reloc.get_r_offset());
		  }
		// Create a GOT entry for the tp-relative offset.
		Output_data_got<32, false>* got
		    = target->got_section(symtab, layout);
		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
					   ? elfcpp::R_386_TLS_TPOFF32
					   : elfcpp::R_386_TLS_TPOFF);
		unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
					 ? GOT_TYPE_TLS_OFFSET
					 : GOT_TYPE_TLS_NOFFSET);
		got->add_global_with_rel(gsym, got_type,
					 target->rel_dyn_section(layout),
					 dyn_r_type);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_global(object, r_type, gsym);
	    break;

	  case elfcpp::R_386_TLS_LE:          // Local-exec
	  case elfcpp::R_386_TLS_LE_32:
	    layout->set_has_static_tls();
	    if (parameters->options().shared())
	      {
		// We need to create a dynamic relocation.
		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_LE_32
					   ? elfcpp::R_386_TLS_TPOFF32
					   : elfcpp::R_386_TLS_TPOFF);
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global(gsym, dyn_r_type, output_section, object,
				    data_shndx, reloc.get_r_offset());
	      }
	    break;

	  default:
	    gold_unreachable();
	  }
      }
      break;

    case elfcpp::R_386_32PLT:
    case elfcpp::R_386_TLS_GD_32:
    case elfcpp::R_386_TLS_GD_PUSH:
    case elfcpp::R_386_TLS_GD_CALL:
    case elfcpp::R_386_TLS_GD_POP:
    case elfcpp::R_386_TLS_LDM_32:
    case elfcpp::R_386_TLS_LDM_PUSH:
    case elfcpp::R_386_TLS_LDM_CALL:
    case elfcpp::R_386_TLS_LDM_POP:
    case elfcpp::R_386_USED_BY_INTEL_200:
    default:
      unsupported_reloc_global(object, r_type, gsym);
      break;
    }
}

// Process relocations for gc.

void
Target_i386::gc_process_relocs(Symbol_table* symtab,
				      Layout* layout,
				      Sized_relobj_file<32, false>* object,
				      unsigned int data_shndx,
				      unsigned int,
				      const unsigned char* prelocs,
				      size_t reloc_count,
				      Output_section* output_section,
				      bool needs_special_offset_handling,
				      size_t local_symbol_count,
				      const unsigned char* plocal_symbols)
{
  gold::gc_process_relocs<32, false, Target_i386, Scan, Classify_reloc>(
    symtab,
    layout,
    this,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols);
}

// Scan relocations for a section.

void
Target_i386::scan_relocs(Symbol_table* symtab,
				Layout* layout,
				Sized_relobj_file<32, false>* object,
				unsigned int data_shndx,
				unsigned int sh_type,
				const unsigned char* prelocs,
				size_t reloc_count,
				Output_section* output_section,
				bool needs_special_offset_handling,
				size_t local_symbol_count,
				const unsigned char* plocal_symbols)
{
  if (sh_type == elfcpp::SHT_RELA)
    {
      gold_error(_("%s: unsupported RELA reloc section"),
		 object->name().c_str());
      return;
    }

  gold::scan_relocs<32, false, Target_i386, Scan, Classify_reloc>(
    symtab,
    layout,
    this,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols);
}

// Finalize the sections.

void
Target_i386::do_finalize_sections(
    Layout* layout,
    const Input_objects*,
    Symbol_table* symtab)
{
  const Reloc_section* rel_plt = (this->plt_ == NULL
				  ? NULL
				  : this->plt_->rel_plt());
  layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
				  this->rel_dyn_, true, false);

  // Emit any relocs we saved in an attempt to avoid generating COPY
  // relocs.
  if (this->copy_relocs_.any_saved_relocs())
    this->copy_relocs_.emit(this->rel_dyn_section(layout));

  // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
  // the .got.plt section.
  Symbol* sym = this->global_offset_table_;
  if (sym != NULL)
    {
      uint32_t data_size = this->got_plt_->current_data_size();
      symtab->get_sized_symbol<32>(sym)->set_symsize(data_size);
    }

  if (parameters->doing_static_link()
      && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
    {
      // If linking statically, make sure that the __rel_iplt symbols
      // were defined if necessary, even if we didn't create a PLT.
      static const Define_symbol_in_segment syms[] =
	{
	  {
	    "__rel_iplt_start",		// name
	    elfcpp::PT_LOAD,		// segment_type
	    elfcpp::PF_W,		// segment_flags_set
	    elfcpp::PF(0),		// segment_flags_clear
	    0,				// value
	    0,				// size
	    elfcpp::STT_NOTYPE,		// type
	    elfcpp::STB_GLOBAL,		// binding
	    elfcpp::STV_HIDDEN,		// visibility
	    0,				// nonvis
	    Symbol::SEGMENT_START,	// offset_from_base
	    true			// only_if_ref
	  },
	  {
	    "__rel_iplt_end",		// name
	    elfcpp::PT_LOAD,		// segment_type
	    elfcpp::PF_W,		// segment_flags_set
	    elfcpp::PF(0),		// segment_flags_clear
	    0,				// value
	    0,				// size
	    elfcpp::STT_NOTYPE,		// type
	    elfcpp::STB_GLOBAL,		// binding
	    elfcpp::STV_HIDDEN,		// visibility
	    0,				// nonvis
	    Symbol::SEGMENT_START,	// offset_from_base
	    true			// only_if_ref
	  }
	};

      symtab->define_symbols(layout, 2, syms,
			     layout->script_options()->saw_sections_clause());
    }
}

// Return whether a direct absolute static relocation needs to be applied.
// In cases where Scan::local() or Scan::global() has created
// a dynamic relocation other than R_386_RELATIVE, the addend
// of the relocation is carried in the data, and we must not
// apply the static relocation.

inline bool
Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
						 unsigned int r_type,
						 bool is_32bit,
						 Output_section* output_section)
{
  // If the output section is not allocated, then we didn't call
  // scan_relocs, we didn't create a dynamic reloc, and we must apply
  // the reloc here.
  if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
    return true;

  int ref_flags = Scan::get_reference_flags(r_type);

  // For local symbols, we will have created a non-RELATIVE dynamic
  // relocation only if (a) the output is position independent,
  // (b) the relocation is absolute (not pc- or segment-relative), and
  // (c) the relocation is not 32 bits wide.
  if (gsym == NULL)
    return !(parameters->options().output_is_position_independent()
	     && (ref_flags & Symbol::ABSOLUTE_REF)
	     && !is_32bit);

  // For global symbols, we use the same helper routines used in the
  // scan pass.  If we did not create a dynamic relocation, or if we
  // created a RELATIVE dynamic relocation, we should apply the static
  // relocation.
  bool has_dyn = gsym->needs_dynamic_reloc(ref_flags);
  bool is_rel = (ref_flags & Symbol::ABSOLUTE_REF)
		&& gsym->can_use_relative_reloc(ref_flags
						& Symbol::FUNCTION_CALL);
  return !has_dyn || is_rel;
}

// Perform a relocation.

inline bool
Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
				unsigned int,
				Target_i386* target,
				Output_section* output_section,
				size_t relnum,
				const unsigned char* preloc,
				const Sized_symbol<32>* gsym,
				const Symbol_value<32>* psymval,
				unsigned char* view,
				elfcpp::Elf_types<32>::Elf_Addr address,
				section_size_type view_size)
{
  const elfcpp::Rel<32, false> rel(preloc);
  unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info());

  if (this->skip_call_tls_get_addr_)
    {
      if ((r_type != elfcpp::R_386_PLT32
	   && r_type != elfcpp::R_386_GOT32X
	   && r_type != elfcpp::R_386_PC32)
	  || gsym == NULL
	  || strcmp(gsym->name(), "___tls_get_addr") != 0)
	{
	  gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
				 _("missing expected TLS relocation"));
	  this->skip_call_tls_get_addr_ = false;
	}
      else
	{
	  this->skip_call_tls_get_addr_ = false;
	  return false;
	}
    }

  if (view == NULL)
    return true;

  const Sized_relobj_file<32, false>* object = relinfo->object;

  // Pick the value to use for symbols defined in shared objects.
  Symbol_value<32> symval;
  if (gsym != NULL
      && gsym->type() == elfcpp::STT_GNU_IFUNC
      && r_type == elfcpp::R_386_32
      && gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))
      && gsym->can_use_relative_reloc(false)
      && !gsym->is_from_dynobj()
      && !gsym->is_undefined()
      && !gsym->is_preemptible())
    {
      // In this case we are generating a R_386_IRELATIVE reloc.  We
      // want to use the real value of the symbol, not the PLT offset.
    }
  else if (gsym != NULL
	   && gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
    {
      symval.set_output_value(target->plt_address_for_global(gsym));
      psymval = &symval;
    }
  else if (gsym == NULL && psymval->is_ifunc_symbol())
    {
      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
      if (object->local_has_plt_offset(r_sym))
	{
	  symval.set_output_value(target->plt_address_for_local(object, r_sym));
	  psymval = &symval;
	}
    }

  bool baseless;

  switch (r_type)
    {
    case elfcpp::R_386_NONE:
    case elfcpp::R_386_GNU_VTINHERIT:
    case elfcpp::R_386_GNU_VTENTRY:
      break;

    case elfcpp::R_386_32:
      if (should_apply_static_reloc(gsym, r_type, true, output_section))
	Relocate_functions<32, false>::rel32(view, object, psymval);
      break;

    case elfcpp::R_386_PC32:
      if (should_apply_static_reloc(gsym, r_type, true, output_section))
	Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
      break;

    case elfcpp::R_386_16:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	Relocate_functions<32, false>::rel16(view, object, psymval);
      break;

    case elfcpp::R_386_PC16:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	Relocate_functions<32, false>::pcrel16(view, object, psymval, address);
      break;

    case elfcpp::R_386_8:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	Relocate_functions<32, false>::rel8(view, object, psymval);
      break;

    case elfcpp::R_386_PC8:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	Relocate_functions<32, false>::pcrel8(view, object, psymval, address);
      break;

    case elfcpp::R_386_PLT32:
      gold_assert(gsym == NULL
		  || gsym->has_plt_offset()
		  || gsym->final_value_is_known()
		  || (gsym->is_defined()
		      && !gsym->is_from_dynobj()
		      && !gsym->is_preemptible()));
      Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
      break;

    case elfcpp::R_386_GOT32:
    case elfcpp::R_386_GOT32X:
      baseless = (view[-1] & 0xc7) == 0x5;
      // R_386_GOT32 and R_386_GOT32X don't work without base register
      // when generating a position-independent output file.
      if (baseless
	  && parameters->options().output_is_position_independent())
	{
	  if(gsym)
	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
				   _("unexpected reloc %u against global symbol %s without base register in object file when generating a position-independent output file"),
				   r_type, gsym->demangled_name().c_str());
	  else
	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
				   _("unexpected reloc %u against local symbol without base register in object file when generating a position-independent output file"),
				   r_type);
	}

      // Convert
      // mov foo@GOT(%reg), %reg
      // to
      // lea foo@GOTOFF(%reg), %reg
      // if possible.
      if (rel.get_r_offset() >= 2
	  && view[-2] == 0x8b
	  && ((gsym == NULL && !psymval->is_ifunc_symbol())
	      || (gsym != NULL
		  && Target_i386::can_convert_mov_to_lea(gsym))))
	{
	  view[-2] = 0x8d;
	  elfcpp::Elf_types<32>::Elf_Addr value;
	  value = psymval->value(object, 0);
	  // Don't subtract the .got.plt section address for baseless
	  // addressing.
	  if (!baseless)
	    value -= target->got_plt_section()->address();
	  Relocate_functions<32, false>::rel32(view, value);
	}
      else
	{
	  // The GOT pointer points to the end of the GOT section.
	  // We need to subtract the size of the GOT section to get
	  // the actual offset to use in the relocation.
	  unsigned int got_offset = 0;
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
	      got_offset = (gsym->got_offset(GOT_TYPE_STANDARD)
			    - target->got_size());
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
	      got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
			    - target->got_size());
	    }
	  // Add the .got.plt section address for baseless addressing.
	  if (baseless)
	    got_offset += target->got_plt_section()->address();
	  Relocate_functions<32, false>::rel32(view, got_offset);
	}
      break;

    case elfcpp::R_386_GOTOFF:
      {
	elfcpp::Elf_types<32>::Elf_Addr value;
	value = (psymval->value(object, 0)
		 - target->got_plt_section()->address());
	Relocate_functions<32, false>::rel32(view, value);
      }
      break;

    case elfcpp::R_386_GOTPC:
      {
	elfcpp::Elf_types<32>::Elf_Addr value;
	value = target->got_plt_section()->address();
	Relocate_functions<32, false>::pcrel32(view, value, address);
      }
      break;

    case elfcpp::R_386_COPY:
    case elfcpp::R_386_GLOB_DAT:
    case elfcpp::R_386_JUMP_SLOT:
    case elfcpp::R_386_RELATIVE:
    case elfcpp::R_386_IRELATIVE:
      // These are outstanding tls relocs, which are unexpected when
      // linking.
    case elfcpp::R_386_TLS_TPOFF:
    case elfcpp::R_386_TLS_DTPMOD32:
    case elfcpp::R_386_TLS_DTPOFF32:
    case elfcpp::R_386_TLS_TPOFF32:
    case elfcpp::R_386_TLS_DESC:
      gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			     _("unexpected reloc %u in object file"),
			     r_type);
      break;

      // These are initial tls relocs, which are expected when
      // linking.
    case elfcpp::R_386_TLS_GD:             // Global-dynamic
    case elfcpp::R_386_TLS_GOTDESC:        // Global-dynamic (from ~oliva url)
    case elfcpp::R_386_TLS_DESC_CALL:
    case elfcpp::R_386_TLS_LDM:            // Local-dynamic
    case elfcpp::R_386_TLS_LDO_32:         // Alternate local-dynamic
    case elfcpp::R_386_TLS_IE:             // Initial-exec
    case elfcpp::R_386_TLS_IE_32:
    case elfcpp::R_386_TLS_GOTIE:
    case elfcpp::R_386_TLS_LE:             // Local-exec
    case elfcpp::R_386_TLS_LE_32:
      this->relocate_tls(relinfo, target, relnum, rel, r_type, gsym, psymval,
			 view, address, view_size);
      break;

    case elfcpp::R_386_32PLT:
    case elfcpp::R_386_TLS_GD_32:
    case elfcpp::R_386_TLS_GD_PUSH:
    case elfcpp::R_386_TLS_GD_CALL:
    case elfcpp::R_386_TLS_GD_POP:
    case elfcpp::R_386_TLS_LDM_32:
    case elfcpp::R_386_TLS_LDM_PUSH:
    case elfcpp::R_386_TLS_LDM_CALL:
    case elfcpp::R_386_TLS_LDM_POP:
    case elfcpp::R_386_USED_BY_INTEL_200:
    default:
      gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			     _("unsupported reloc %u"),
			     r_type);
      break;
    }

  return true;
}

// Perform a TLS relocation.

inline void
Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
				    Target_i386* target,
				    size_t relnum,
				    const elfcpp::Rel<32, false>& rel,
				    unsigned int r_type,
				    const Sized_symbol<32>* gsym,
				    const Symbol_value<32>* psymval,
				    unsigned char* view,
				    elfcpp::Elf_types<32>::Elf_Addr,
				    section_size_type view_size)
{
  Output_segment* tls_segment = relinfo->layout->tls_segment();

  const Sized_relobj_file<32, false>* object = relinfo->object;

  elfcpp::Elf_types<32>::Elf_Addr value = psymval->value(object, 0);

  const bool is_final = (gsym == NULL
			 ? !parameters->options().shared()
			 : gsym->final_value_is_known());
  const tls::Tls_optimization optimized_type
      = Target_i386::optimize_tls_reloc(is_final, r_type);
  switch (r_type)
    {
    case elfcpp::R_386_TLS_GD:           // Global-dynamic
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return;
	    }
	  this->tls_gd_to_le(relinfo, relnum, tls_segment,
			     rel, r_type, value, view,
			     view_size);
	  break;
	}
      else
	{
	  unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
				   ? GOT_TYPE_TLS_NOFFSET
				   : GOT_TYPE_TLS_PAIR);
	  unsigned int got_offset;
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(got_type));
	      got_offset = gsym->got_offset(got_type) - target->got_size();
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym, got_type));
	      got_offset = (object->local_got_offset(r_sym, got_type)
			    - target->got_size());
	    }
	  if (optimized_type == tls::TLSOPT_TO_IE)
	    {
	      this->tls_gd_to_ie(relinfo, relnum, rel, r_type,
				 got_offset, view, view_size);
	      break;
	    }
	  else if (optimized_type == tls::TLSOPT_NONE)
	    {
	      // Relocate the field with the offset of the pair of GOT
	      // entries.
	      Relocate_functions<32, false>::rel32(view, got_offset);
	      break;
	    }
	}
      gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			     _("unsupported reloc %u"),
			     r_type);
      break;

    case elfcpp::R_386_TLS_GOTDESC:      // Global-dynamic (from ~oliva url)
    case elfcpp::R_386_TLS_DESC_CALL:
      this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return;
	    }
	  this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
				  rel, r_type, value, view,
				  view_size);
	  break;
	}
      else
	{
	  unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
				   ? GOT_TYPE_TLS_NOFFSET
				   : GOT_TYPE_TLS_DESC);
	  unsigned int got_offset = 0;
	  if (r_type == elfcpp::R_386_TLS_GOTDESC
	      && optimized_type == tls::TLSOPT_NONE)
	    {
	      // We created GOT entries in the .got.tlsdesc portion of
	      // the .got.plt section, but the offset stored in the
	      // symbol is the offset within .got.tlsdesc.
	      got_offset = (target->got_size()
			    + target->got_plt_section()->data_size());
	    }
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(got_type));
	      got_offset += gsym->got_offset(got_type) - target->got_size();
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym, got_type));
	      got_offset += (object->local_got_offset(r_sym, got_type)
			     - target->got_size());
	    }
	  if (optimized_type == tls::TLSOPT_TO_IE)
	    {
	      this->tls_desc_gd_to_ie(relinfo, relnum, rel, r_type,
				      got_offset, view, view_size);
	      break;
	    }
	  else if (optimized_type == tls::TLSOPT_NONE)
	    {
	      if (r_type == elfcpp::R_386_TLS_GOTDESC)
		{
		  // Relocate the field with the offset of the pair of GOT
		  // entries.
		  Relocate_functions<32, false>::rel32(view, got_offset);
		}
	      break;
	    }
	}
      gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			     _("unsupported reloc %u"),
			     r_type);
      break;

    case elfcpp::R_386_TLS_LDM:          // Local-dynamic
      if (this->local_dynamic_type_ == LOCAL_DYNAMIC_SUN)
	{
	  gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
				 _("both SUN and GNU model "
				   "TLS relocations"));
	  break;
	}
      this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return;
	    }
	  this->tls_ld_to_le(relinfo, relnum, tls_segment, rel, r_type,
			     value, view, view_size);
	  break;
	}
      else if (optimized_type == tls::TLSOPT_NONE)
	{
	  // Relocate the field with the offset of the GOT entry for
	  // the module index.
	  unsigned int got_offset;
	  got_offset = (target->got_mod_index_entry(NULL, NULL, NULL)
			- target->got_size());
	  Relocate_functions<32, false>::rel32(view, got_offset);
	  break;
	}
      gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			     _("unsupported reloc %u"),
			     r_type);
      break;

    case elfcpp::R_386_TLS_LDO_32:       // Alternate local-dynamic
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  // This reloc can appear in debugging sections, in which
	  // case we must not convert to local-exec.  We decide what
	  // to do based on whether the section is marked as
	  // containing executable code.  That is what the GNU linker
	  // does as well.
	  elfcpp::Shdr<32, false> shdr(relinfo->data_shdr);
	  if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
	    {
	      if (tls_segment == NULL)
		{
		  gold_assert(parameters->errors()->error_count() > 0
			      || issue_undefined_symbol_error(gsym));
		  return;
		}
	      value -= tls_segment->memsz();
	    }
	}
      Relocate_functions<32, false>::rel32(view, value);
      break;

    case elfcpp::R_386_TLS_IE:           // Initial-exec
    case elfcpp::R_386_TLS_GOTIE:
    case elfcpp::R_386_TLS_IE_32:
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return;
	    }
	  Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
					      rel, r_type, value, view,
					      view_size);
	  break;
	}
      else if (optimized_type == tls::TLSOPT_NONE)
	{
	  // Relocate the field with the offset of the GOT entry for
	  // the tp-relative offset of the symbol.
	  unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
				   ? GOT_TYPE_TLS_OFFSET
				   : GOT_TYPE_TLS_NOFFSET);
	  unsigned int got_offset;
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(got_type));
	      got_offset = gsym->got_offset(got_type);
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym, got_type));
	      got_offset = object->local_got_offset(r_sym, got_type);
	    }
	  // For the R_386_TLS_IE relocation, we need to apply the
	  // absolute address of the GOT entry.
	  if (r_type == elfcpp::R_386_TLS_IE)
	    got_offset += target->got_plt_section()->address();
	  // All GOT offsets are relative to the end of the GOT.
	  got_offset -= target->got_size();
	  Relocate_functions<32, false>::rel32(view, got_offset);
	  break;
	}
      gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			     _("unsupported reloc %u"),
			     r_type);
      break;

    case elfcpp::R_386_TLS_LE:           // Local-exec
      // If we're creating a shared library, a dynamic relocation will
      // have been created for this location, so do not apply it now.
      if (!parameters->options().shared())
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return;
	    }
	  value -= tls_segment->memsz();
	  Relocate_functions<32, false>::rel32(view, value);
	}
      break;

    case elfcpp::R_386_TLS_LE_32:
      // If we're creating a shared library, a dynamic relocation will
      // have been created for this location, so do not apply it now.
      if (!parameters->options().shared())
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return;
	    }
	  value = tls_segment->memsz() - value;
	  Relocate_functions<32, false>::rel32(view, value);
	}
      break;
    }
}

// Do a relocation in which we convert a TLS General-Dynamic to a
// Local-Exec.

inline void
Target_i386::Relocate::tls_gd_to_le(const Relocate_info<32, false>* relinfo,
				    size_t relnum,
				    Output_segment* tls_segment,
				    const elfcpp::Rel<32, false>& rel,
				    unsigned int,
				    elfcpp::Elf_types<32>::Elf_Addr value,
				    unsigned char* view,
				    section_size_type view_size)
{
  // leal foo(,%ebx,1),%eax; call ___tls_get_addr@PLT
  //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
  // leal foo(%ebx),%eax; call ___tls_get_addr@PLT
  //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
  // leal foo(%reg),%eax; call *___tls_get_addr@GOT(%reg)
  //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax

  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9);

  unsigned char op1 = view[-1];
  unsigned char op2 = view[-2];
  unsigned char op3 = view[4];

  tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		 op2 == 0x8d || op2 == 0x04);
  tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		 op3 == 0xe8 || op3 == 0xff);

  int roff = 5;

  if (op2 == 0x04)
    {
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -3);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     ((op1 & 0xc7) == 0x05 && op1 != (4 << 3)));
      memcpy(view - 3, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
    }
  else
    {
      unsigned char reg = op1 & 7;
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     ((op1 & 0xf8) == 0x80
		      && reg != 4
		      && reg != 0
		      && (op3 == 0xe8 || (view[5] & 0x7) == reg)));
      if (op3 == 0xff
	  || (rel.get_r_offset() + 9 < view_size
	      && view[9] == 0x90))
	{
	  // There is an indirect call or a trailing nop.  Use the size
	  // byte subl.
	  memcpy(view - 2, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
	  roff = 6;
	}
      else
	{
	  // Use the five byte subl.
	  memcpy(view - 2, "\x65\xa1\0\0\0\0\x2d\0\0\0", 11);
	}
    }

  value = tls_segment->memsz() - value;
  Relocate_functions<32, false>::rel32(view + roff, value);

  // The next reloc should be a PLT32 reloc against __tls_get_addr.
  // We can skip it.
  this->skip_call_tls_get_addr_ = true;
}

// Do a relocation in which we convert a TLS General-Dynamic to an
// Initial-Exec.

inline void
Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
				    size_t relnum,
				    const elfcpp::Rel<32, false>& rel,
				    unsigned int,
				    elfcpp::Elf_types<32>::Elf_Addr value,
				    unsigned char* view,
				    section_size_type view_size)
{
  // leal foo(,%ebx,1),%eax; call ___tls_get_addr@PLT
  //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
  // leal foo(%ebx),%eax; call ___tls_get_addr@PLT; nop
  //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
  // leal foo(%reg),%eax; call *___tls_get_addr@GOT(%reg)
  //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%reg),%eax

  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9);

  unsigned char op1 = view[-1];
  unsigned char op2 = view[-2];
  unsigned char op3 = view[4];

  tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		 op2 == 0x8d || op2 == 0x04);
  tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		 op3 == 0xe8 || op3 == 0xff);

  int roff;

  if (op2 == 0x04)
    {
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -3);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     ((op1 & 0xc7) == 0x05 && op1 != (4 << 3)));
      roff = 5;
    }
  else
    {
      unsigned char reg = op1 & 7;
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 10);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     ((op1 & 0xf8) == 0x80
		      && reg != 4
		      && reg != 0
		      && ((op3 == 0xe8 && view[9] == 0x90)
			   || (view[5] & 0x7) == reg)));
      roff = 6;
    }

  memcpy(view + roff - 8, "\x65\xa1\0\0\0\0\x03\x83\0\0\0", 12);
  Relocate_functions<32, false>::rel32(view + roff, value);

  // The next reloc should be a PLT32 reloc against __tls_get_addr.
  // We can skip it.
  this->skip_call_tls_get_addr_ = true;
}

// Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
// General-Dynamic to a Local-Exec.

inline void
Target_i386::Relocate::tls_desc_gd_to_le(
    const Relocate_info<32, false>* relinfo,
    size_t relnum,
    Output_segment* tls_segment,
    const elfcpp::Rel<32, false>& rel,
    unsigned int r_type,
    elfcpp::Elf_types<32>::Elf_Addr value,
    unsigned char* view,
    section_size_type view_size)
{
  if (r_type == elfcpp::R_386_TLS_GOTDESC)
    {
      // leal foo@TLSDESC(%ebx), %eax
      // ==> leal foo@NTPOFF, %eax
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     view[-2] == 0x8d && view[-1] == 0x83);
      view[-1] = 0x05;
      value -= tls_segment->memsz();
      Relocate_functions<32, false>::rel32(view, value);
    }
  else
    {
      // call *foo@TLSCALL(%eax)
      // ==> nop; nop
      gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     view[0] == 0xff && view[1] == 0x10);
      view[0] = 0x66;
      view[1] = 0x90;
    }
}

// Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
// General-Dynamic to an Initial-Exec.

inline void
Target_i386::Relocate::tls_desc_gd_to_ie(
    const Relocate_info<32, false>* relinfo,
    size_t relnum,
    const elfcpp::Rel<32, false>& rel,
    unsigned int r_type,
    elfcpp::Elf_types<32>::Elf_Addr value,
    unsigned char* view,
    section_size_type view_size)
{
  if (r_type == elfcpp::R_386_TLS_GOTDESC)
    {
      // leal foo@TLSDESC(%ebx), %eax
      // ==> movl foo@GOTNTPOFF(%ebx), %eax
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     view[-2] == 0x8d && view[-1] == 0x83);
      view[-2] = 0x8b;
      Relocate_functions<32, false>::rel32(view, value);
    }
  else
    {
      // call *foo@TLSCALL(%eax)
      // ==> nop; nop
      gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     view[0] == 0xff && view[1] == 0x10);
      view[0] = 0x66;
      view[1] = 0x90;
    }
}

// Do a relocation in which we convert a TLS Local-Dynamic to a
// Local-Exec.

inline void
Target_i386::Relocate::tls_ld_to_le(const Relocate_info<32, false>* relinfo,
				    size_t relnum,
				    Output_segment*,
				    const elfcpp::Rel<32, false>& rel,
				    unsigned int,
				    elfcpp::Elf_types<32>::Elf_Addr,
				    unsigned char* view,
				    section_size_type view_size)
{
  // leal foo(%ebx), %eax; call ___tls_get_addr@PLT
  // ==> movl %gs:0,%eax; nop; leal 0(%esi,1),%esi
  // leal foo(%reg), %eax; call call *___tls_get_addr@GOT(%reg)
  // ==> movl %gs:0,%eax; leal (%esi),%esi

  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);

  unsigned char op1 = view[-1];
  unsigned char op2 = view[-2];
  unsigned char op3 = view[4];

  tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		 op3 == 0xe8 || op3 == 0xff);
  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size,
		   op3 == 0xe8 ? 9 : 10);

  // FIXME: Does this test really always pass?
  tls::check_tls(relinfo, relnum, rel.get_r_offset(), op2 == 0x8d);

  unsigned char reg = op1 & 7;
  tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		 ((op1 & 0xf8) == 0x80
		  && reg != 4
		  && reg != 0
		  && (op3 == 0xe8 || (view[5] & 0x7) == reg)));

  if (op3 == 0xe8)
    memcpy(view - 2, "\x65\xa1\0\0\0\0\x90\x8d\x74\x26\0", 11);
  else
    memcpy(view - 2, "\x65\xa1\0\0\0\0\x8d\xb6\0\0\0\0", 12);

  // The next reloc should be a PLT32 reloc against __tls_get_addr.
  // We can skip it.
  this->skip_call_tls_get_addr_ = true;
}

// Do a relocation in which we convert a TLS Initial-Exec to a
// Local-Exec.

inline void
Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
				    size_t relnum,
				    Output_segment* tls_segment,
				    const elfcpp::Rel<32, false>& rel,
				    unsigned int r_type,
				    elfcpp::Elf_types<32>::Elf_Addr value,
				    unsigned char* view,
				    section_size_type view_size)
{
  // We have to actually change the instructions, which means that we
  // need to examine the opcodes to figure out which instruction we
  // are looking at.
  if (r_type == elfcpp::R_386_TLS_IE)
    {
      // movl %gs:XX,%eax  ==>  movl $YY,%eax
      // movl %gs:XX,%reg  ==>  movl $YY,%reg
      // addl %gs:XX,%reg  ==>  addl $YY,%reg
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -1);
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);

      unsigned char op1 = view[-1];
      if (op1 == 0xa1)
	{
	  // movl XX,%eax  ==>  movl $YY,%eax
	  view[-1] = 0xb8;
	}
      else
	{
	  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);

	  unsigned char op2 = view[-2];
	  if (op2 == 0x8b)
	    {
	      // movl XX,%reg  ==>  movl $YY,%reg
	      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
			     (op1 & 0xc7) == 0x05);
	      view[-2] = 0xc7;
	      view[-1] = 0xc0 | ((op1 >> 3) & 7);
	    }
	  else if (op2 == 0x03)
	    {
	      // addl XX,%reg  ==>  addl $YY,%reg
	      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
			     (op1 & 0xc7) == 0x05);
	      view[-2] = 0x81;
	      view[-1] = 0xc0 | ((op1 >> 3) & 7);
	    }
	  else
	    tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0);
	}
    }
  else
    {
      // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
      // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
      // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
      tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);

      unsigned char op1 = view[-1];
      unsigned char op2 = view[-2];
      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
		     (op1 & 0xc0) == 0x80 && (op1 & 7) != 4);
      if (op2 == 0x8b)
	{
	  // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
	  view[-2] = 0xc7;
	  view[-1] = 0xc0 | ((op1 >> 3) & 7);
	}
      else if (op2 == 0x2b)
	{
	  // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
	  view[-2] = 0x81;
	  view[-1] = 0xe8 | ((op1 >> 3) & 7);
	}
      else if (op2 == 0x03)
	{
	  // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
	  view[-2] = 0x81;
	  view[-1] = 0xc0 | ((op1 >> 3) & 7);
	}
      else
	tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0);
    }

  value = tls_segment->memsz() - value;
  if (r_type == elfcpp::R_386_TLS_IE || r_type == elfcpp::R_386_TLS_GOTIE)
    value = - value;

  Relocate_functions<32, false>::rel32(view, value);
}

// Relocate section data.

void
Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
			      unsigned int sh_type,
			      const unsigned char* prelocs,
			      size_t reloc_count,
			      Output_section* output_section,
			      bool needs_special_offset_handling,
			      unsigned char* view,
			      elfcpp::Elf_types<32>::Elf_Addr address,
			      section_size_type view_size,
			      const Reloc_symbol_changes* reloc_symbol_changes)
{
  gold_assert(sh_type == elfcpp::SHT_REL);

  gold::relocate_section<32, false, Target_i386, Relocate,
			 gold::Default_comdat_behavior, Classify_reloc>(
    relinfo,
    this,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    view,
    address,
    view_size,
    reloc_symbol_changes);
}

// Return the size of a relocation while scanning during a relocatable
// link.

unsigned int
Target_i386::Classify_reloc::get_size_for_reloc(
    unsigned int r_type,
    Relobj* object)
{
  switch (r_type)
    {
    case elfcpp::R_386_NONE:
    case elfcpp::R_386_GNU_VTINHERIT:
    case elfcpp::R_386_GNU_VTENTRY:
    case elfcpp::R_386_TLS_GD:            // Global-dynamic
    case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    case elfcpp::R_386_TLS_DESC_CALL:
    case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    case elfcpp::R_386_TLS_IE:            // Initial-exec
    case elfcpp::R_386_TLS_IE_32:
    case elfcpp::R_386_TLS_GOTIE:
    case elfcpp::R_386_TLS_LE:            // Local-exec
    case elfcpp::R_386_TLS_LE_32:
      return 0;

    case elfcpp::R_386_32:
    case elfcpp::R_386_PC32:
    case elfcpp::R_386_GOT32:
    case elfcpp::R_386_GOT32X:
    case elfcpp::R_386_PLT32:
    case elfcpp::R_386_GOTOFF:
    case elfcpp::R_386_GOTPC:
     return 4;

    case elfcpp::R_386_16:
    case elfcpp::R_386_PC16:
      return 2;

    case elfcpp::R_386_8:
    case elfcpp::R_386_PC8:
      return 1;

      // These are relocations which should only be seen by the
      // dynamic linker, and should never be seen here.
    case elfcpp::R_386_COPY:
    case elfcpp::R_386_GLOB_DAT:
    case elfcpp::R_386_JUMP_SLOT:
    case elfcpp::R_386_RELATIVE:
    case elfcpp::R_386_IRELATIVE:
    case elfcpp::R_386_TLS_TPOFF:
    case elfcpp::R_386_TLS_DTPMOD32:
    case elfcpp::R_386_TLS_DTPOFF32:
    case elfcpp::R_386_TLS_TPOFF32:
    case elfcpp::R_386_TLS_DESC:
      object->error(_("unexpected reloc %u in object file"), r_type);
      return 0;

    case elfcpp::R_386_32PLT:
    case elfcpp::R_386_TLS_GD_32:
    case elfcpp::R_386_TLS_GD_PUSH:
    case elfcpp::R_386_TLS_GD_CALL:
    case elfcpp::R_386_TLS_GD_POP:
    case elfcpp::R_386_TLS_LDM_32:
    case elfcpp::R_386_TLS_LDM_PUSH:
    case elfcpp::R_386_TLS_LDM_CALL:
    case elfcpp::R_386_TLS_LDM_POP:
    case elfcpp::R_386_USED_BY_INTEL_200:
    default:
      object->error(_("unsupported reloc %u in object file"), r_type);
      return 0;
    }
}

// Scan the relocs during a relocatable link.

void
Target_i386::scan_relocatable_relocs(Symbol_table* symtab,
				     Layout* layout,
				     Sized_relobj_file<32, false>* object,
				     unsigned int data_shndx,
				     unsigned int sh_type,
				     const unsigned char* prelocs,
				     size_t reloc_count,
				     Output_section* output_section,
				     bool needs_special_offset_handling,
				     size_t local_symbol_count,
				     const unsigned char* plocal_symbols,
				     Relocatable_relocs* rr)
{
  typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
      Scan_relocatable_relocs;

  gold_assert(sh_type == elfcpp::SHT_REL);

  gold::scan_relocatable_relocs<32, false, Scan_relocatable_relocs>(
    symtab,
    layout,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols,
    rr);
}

// Scan the relocs for --emit-relocs.

void
Target_i386::emit_relocs_scan(Symbol_table* symtab,
			      Layout* layout,
			      Sized_relobj_file<32, false>* object,
			      unsigned int data_shndx,
			      unsigned int sh_type,
			      const unsigned char* prelocs,
			      size_t reloc_count,
			      Output_section* output_section,
			      bool needs_special_offset_handling,
			      size_t local_symbol_count,
			      const unsigned char* plocal_syms,
			      Relocatable_relocs* rr)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_REL, 32, false>
      Classify_reloc;
  typedef gold::Default_emit_relocs_strategy<Classify_reloc>
      Emit_relocs_strategy;

  gold_assert(sh_type == elfcpp::SHT_REL);

  gold::scan_relocatable_relocs<32, false, Emit_relocs_strategy>(
    symtab,
    layout,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_syms,
    rr);
}

// Emit relocations for a section.

void
Target_i386::relocate_relocs(
    const Relocate_info<32, false>* relinfo,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
    unsigned char* view,
    elfcpp::Elf_types<32>::Elf_Addr view_address,
    section_size_type view_size,
    unsigned char* reloc_view,
    section_size_type reloc_view_size)
{
  gold_assert(sh_type == elfcpp::SHT_REL);

  gold::relocate_relocs<32, false, Classify_reloc>(
    relinfo,
    prelocs,
    reloc_count,
    output_section,
    offset_in_output_section,
    view,
    view_address,
    view_size,
    reloc_view,
    reloc_view_size);
}

// Return the value to use for a dynamic which requires special
// treatment.  This is how we support equality comparisons of function
// pointers across shared library boundaries, as described in the
// processor specific ABI supplement.

uint64_t
Target_i386::do_dynsym_value(const Symbol* gsym) const
{
  gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
  return this->plt_address_for_global(gsym);
}

// Return a string used to fill a code section with nops to take up
// the specified length.

std::string
Target_i386::do_code_fill(section_size_type length) const
{
  if (length >= 16)
    {
      // Build a jmp instruction to skip over the bytes.
      unsigned char jmp[5];
      jmp[0] = 0xe9;
      elfcpp::Swap_unaligned<32, false>::writeval(jmp + 1, length - 5);
      return (std::string(reinterpret_cast<char*>(&jmp[0]), 5)
	      + std::string(length - 5, static_cast<char>(0x90)));
    }

  // Nop sequences of various lengths.
  const char nop1[1] = { '\x90' };                   // nop
  const char nop2[2] = { '\x66', '\x90' };           // xchg %ax %ax
  const char nop3[3] = { '\x8d', '\x76', '\x00' };   // leal 0(%esi),%esi
  const char nop4[4] = { '\x8d', '\x74', '\x26',     // leal 0(%esi,1),%esi
			 '\x00'};
  const char nop5[5] = { '\x90', '\x8d', '\x74',     // nop
			 '\x26', '\x00' };           // leal 0(%esi,1),%esi
  const char nop6[6] = { '\x8d', '\xb6', '\x00',     // leal 0L(%esi),%esi
			 '\x00', '\x00', '\x00' };
  const char nop7[7] = { '\x8d', '\xb4', '\x26',     // leal 0L(%esi,1),%esi
			 '\x00', '\x00', '\x00',
			 '\x00' };
  const char nop8[8] = { '\x90', '\x8d', '\xb4',     // nop
			 '\x26', '\x00', '\x00',     // leal 0L(%esi,1),%esi
			 '\x00', '\x00' };
  const char nop9[9] = { '\x89', '\xf6', '\x8d',     // movl %esi,%esi
			 '\xbc', '\x27', '\x00',     // leal 0L(%edi,1),%edi
			 '\x00', '\x00', '\x00' };
  const char nop10[10] = { '\x8d', '\x76', '\x00',   // leal 0(%esi),%esi
			   '\x8d', '\xbc', '\x27',   // leal 0L(%edi,1),%edi
			   '\x00', '\x00', '\x00',
			   '\x00' };
  const char nop11[11] = { '\x8d', '\x74', '\x26',   // leal 0(%esi,1),%esi
			   '\x00', '\x8d', '\xbc',   // leal 0L(%edi,1),%edi
			   '\x27', '\x00', '\x00',
			   '\x00', '\x00' };
  const char nop12[12] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
			   '\x00', '\x00', '\x00',   // leal 0L(%edi),%edi
			   '\x8d', '\xbf', '\x00',
			   '\x00', '\x00', '\x00' };
  const char nop13[13] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
			   '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
			   '\x8d', '\xbc', '\x27',
			   '\x00', '\x00', '\x00',
			   '\x00' };
  const char nop14[14] = { '\x8d', '\xb4', '\x26',   // leal 0L(%esi,1),%esi
			   '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
			   '\x00', '\x8d', '\xbc',
			   '\x27', '\x00', '\x00',
			   '\x00', '\x00' };
  const char nop15[15] = { '\xeb', '\x0d', '\x90',   // jmp .+15
			   '\x90', '\x90', '\x90',   // nop,nop,nop,...
			   '\x90', '\x90', '\x90',
			   '\x90', '\x90', '\x90',
			   '\x90', '\x90', '\x90' };

  const char* nops[16] = {
    NULL,
    nop1, nop2, nop3, nop4, nop5, nop6, nop7,
    nop8, nop9, nop10, nop11, nop12, nop13, nop14, nop15
  };

  return std::string(nops[length], length);
}

// Return the value to use for the base of a DW_EH_PE_datarel offset
// in an FDE.  Solaris and SVR4 use DW_EH_PE_datarel because their
// assembler can not write out the difference between two labels in
// different sections, so instead of using a pc-relative value they
// use an offset from the GOT.

uint64_t
Target_i386::do_ehframe_datarel_base() const
{
  gold_assert(this->global_offset_table_ != NULL);
  Symbol* sym = this->global_offset_table_;
  Sized_symbol<32>* ssym = static_cast<Sized_symbol<32>*>(sym);
  return ssym->value();
}

// Return whether SYM should be treated as a call to a non-split
// function.  We don't want that to be true of a call to a
// get_pc_thunk function.

bool
Target_i386::do_is_call_to_non_split(const Symbol* sym,
				     const unsigned char*,
				     const unsigned char*,
				     section_size_type) const
{
  return (sym->type() == elfcpp::STT_FUNC
	  && !is_prefix_of("__i686.get_pc_thunk.", sym->name()));
}

// FNOFFSET in section SHNDX in OBJECT is the start of a function
// compiled with -fsplit-stack.  The function calls non-split-stack
// code.  We have to change the function so that it always ensures
// that it has enough stack space to run some random function.

void
Target_i386::do_calls_non_split(Relobj* object, unsigned int shndx,
				       section_offset_type fnoffset,
				       section_size_type fnsize,
				       const unsigned char*,
				       size_t,
				       unsigned char* view,
				       section_size_type view_size,
				       std::string* from,
				       std::string* to) const
{
  // The function starts with a comparison of the stack pointer and a
  // field in the TCB.  This is followed by a jump.

  // cmp %gs:NN,%esp
  if (this->match_view(view, view_size, fnoffset, "\x65\x3b\x25", 3)
      && fnsize > 7)
    {
      // We will call __morestack if the carry flag is set after this
      // comparison.  We turn the comparison into an stc instruction
      // and some nops.
      view[fnoffset] = '\xf9';
      this->set_view_to_nop(view, view_size, fnoffset + 1, 6);
    }
  // lea NN(%esp),%ecx
  // lea NN(%esp),%edx
  else if ((this->match_view(view, view_size, fnoffset, "\x8d\x8c\x24", 3)
	    || this->match_view(view, view_size, fnoffset, "\x8d\x94\x24", 3))
	   && fnsize > 7)
    {
      // This is loading an offset from the stack pointer for a
      // comparison.  The offset is negative, so we decrease the
      // offset by the amount of space we need for the stack.  This
      // means we will avoid calling __morestack if there happens to
      // be plenty of space on the stack already.
      unsigned char* pval = view + fnoffset + 3;
      uint32_t val = elfcpp::Swap_unaligned<32, false>::readval(pval);
      val -= parameters->options().split_stack_adjust_size();
      elfcpp::Swap_unaligned<32, false>::writeval(pval, val);
    }
  else
    {
      if (!object->has_no_split_stack())
	object->error(_("failed to match split-stack sequence at "
			"section %u offset %0zx"),
		      shndx, static_cast<size_t>(fnoffset));
      return;
    }

  // We have to change the function so that it calls
  // __morestack_non_split instead of __morestack.  The former will
  // allocate additional stack space.
  *from = "__morestack";
  *to = "__morestack_non_split";
}

// The selector for i386 object files.  Note this is never instantiated
// directly.  It's only used in Target_selector_i386_nacl, below.

class Target_selector_i386 : public Target_selector_freebsd
{
public:
  Target_selector_i386()
    : Target_selector_freebsd(elfcpp::EM_386, 32, false,
			      "elf32-i386", "elf32-i386-freebsd",
			      "elf_i386")
  { }

  Target*
  do_instantiate_target()
  { return new Target_i386(); }
};

// NaCl variant.  It uses different PLT contents.

class Output_data_plt_i386_nacl : public Output_data_plt_i386
{
 public:
  Output_data_plt_i386_nacl(Layout* layout,
			    Output_data_got_plt_i386* got_plt,
			    Output_data_space* got_irelative)
    : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
  { }

 protected:
  virtual unsigned int
  do_get_plt_entry_size() const
  { return plt_entry_size; }

  virtual void
  do_add_eh_frame(Layout* layout)
  {
    layout->add_eh_frame_for_plt(this, plt_eh_frame_cie, plt_eh_frame_cie_size,
				 plt_eh_frame_fde, plt_eh_frame_fde_size);
  }

  // The size of an entry in the PLT.
  static const int plt_entry_size = 64;

  // The .eh_frame unwind information for the PLT.
  static const int plt_eh_frame_fde_size = 32;
  static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size];
};

class Output_data_plt_i386_nacl_exec : public Output_data_plt_i386_nacl
{
public:
  Output_data_plt_i386_nacl_exec(Layout* layout,
				 Output_data_got_plt_i386* got_plt,
				 Output_data_space* got_irelative)
    : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
  { }

 protected:
  virtual void
  do_fill_first_plt_entry(unsigned char* pov,
			  elfcpp::Elf_types<32>::Elf_Addr got_address);

  virtual unsigned int
  do_fill_plt_entry(unsigned char* pov,
		    elfcpp::Elf_types<32>::Elf_Addr got_address,
		    unsigned int got_offset,
		    unsigned int plt_offset,
		    unsigned int plt_rel_offset);

 private:
  // The first entry in the PLT for an executable.
  static const unsigned char first_plt_entry[plt_entry_size];

  // Other entries in the PLT for an executable.
  static const unsigned char plt_entry[plt_entry_size];
};

class Output_data_plt_i386_nacl_dyn : public Output_data_plt_i386_nacl
{
 public:
  Output_data_plt_i386_nacl_dyn(Layout* layout,
				Output_data_got_plt_i386* got_plt,
				Output_data_space* got_irelative)
    : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
  { }

 protected:
  virtual void
  do_fill_first_plt_entry(unsigned char* pov, elfcpp::Elf_types<32>::Elf_Addr);

  virtual unsigned int
  do_fill_plt_entry(unsigned char* pov,
		    elfcpp::Elf_types<32>::Elf_Addr,
		    unsigned int got_offset,
		    unsigned int plt_offset,
		    unsigned int plt_rel_offset);

 private:
  // The first entry in the PLT for a shared object.
  static const unsigned char first_plt_entry[plt_entry_size];

  // Other entries in the PLT for a shared object.
  static const unsigned char plt_entry[plt_entry_size];
};

class Target_i386_nacl : public Target_i386
{
 public:
  Target_i386_nacl()
    : Target_i386(&i386_nacl_info)
  { }

 protected:
  virtual Output_data_plt_i386*
  do_make_data_plt(Layout* layout,
		   Output_data_got_plt_i386* got_plt,
		   Output_data_space* got_irelative,
		   bool dyn)
  {
    if (dyn)
      return new Output_data_plt_i386_nacl_dyn(layout, got_plt, got_irelative);
    else
      return new Output_data_plt_i386_nacl_exec(layout, got_plt, got_irelative);
  }

  virtual std::string
  do_code_fill(section_size_type length) const;

 private:
  static const Target::Target_info i386_nacl_info;
};

const Target::Target_info Target_i386_nacl::i386_nacl_info =
{
  32,			// size
  false,		// is_big_endian
  elfcpp::EM_386,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  true,			// has_code_fill
  true,			// is_default_stack_executable
  true,			// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/lib/ld-nacl-x86-32.so.1", // dynamic_linker
  0x20000,		// default_text_segment_address
  0x10000,		// abi_pagesize (overridable by -z max-page-size)
  0x10000,		// common_pagesize (overridable by -z common-page-size)
  true,                 // isolate_execinstr
  0x10000000,           // rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
};

#define	NACLMASK	0xe0            // 32-byte alignment mask

const unsigned char
Output_data_plt_i386_nacl_exec::first_plt_entry[plt_entry_size] =
{
  0xff, 0x35,                          // pushl contents of memory address
  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
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90
};

void
Output_data_plt_i386_nacl_exec::do_fill_first_plt_entry(
    unsigned char* pov,
    elfcpp::Elf_types<32>::Elf_Addr got_address)
{
  memcpy(pov, first_plt_entry, plt_entry_size);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_address + 4);
  elfcpp::Swap<32, false>::writeval(pov + 8, got_address + 8);
}

// The first entry in the PLT for a shared object.

const unsigned char
Output_data_plt_i386_nacl_dyn::first_plt_entry[plt_entry_size] =
{
  0xff, 0xb3, 4, 0, 0, 0,	// pushl 4(%ebx)
  0x8b, 0x4b, 0x08,		// mov 0x8(%ebx), %ecx
  0x83, 0xe1, NACLMASK,         // andl $NACLMASK, %ecx
  0xff, 0xe1,                   // jmp *%ecx
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90,  // nops
  0x90, 0x90, 0x90, 0x90, 0x90   // nops
};

void
Output_data_plt_i386_nacl_dyn::do_fill_first_plt_entry(
    unsigned char* pov,
    elfcpp::Elf_types<32>::Elf_Addr)
{
  memcpy(pov, first_plt_entry, plt_entry_size);
}

// Subsequent entries in the PLT for an executable.

const unsigned char
Output_data_plt_i386_nacl_exec::plt_entry[plt_entry_size] =
{
  0x8b, 0x0d,                    // movl contents of address, %ecx */
  0, 0, 0, 0,                    // replaced with address of symbol in .got
  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,

  // 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
};

unsigned int
Output_data_plt_i386_nacl_exec::do_fill_plt_entry(
    unsigned char* pov,
    elfcpp::Elf_types<32>::Elf_Addr got_address,
    unsigned int got_offset,
    unsigned int plt_offset,
    unsigned int plt_rel_offset)
{
  memcpy(pov, plt_entry, plt_entry_size);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 2,
					      got_address + got_offset);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset);
  elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4));
  return 32;
}

// Subsequent entries in the PLT for a shared object.

const unsigned char
Output_data_plt_i386_nacl_dyn::plt_entry[plt_entry_size] =
{
  0x8b, 0x8b,          // movl offset(%ebx), %ecx
  0, 0, 0, 0,          // replaced with offset of 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
};

unsigned int
Output_data_plt_i386_nacl_dyn::do_fill_plt_entry(
    unsigned char* pov,
    elfcpp::Elf_types<32>::Elf_Addr,
    unsigned int got_offset,
    unsigned int plt_offset,
    unsigned int plt_rel_offset)
{
  memcpy(pov, plt_entry, plt_entry_size);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset);
  elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset);
  elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4));
  return 32;
}

const unsigned char
Output_data_plt_i386_nacl::plt_eh_frame_fde[plt_eh_frame_fde_size] =
{
  0, 0, 0, 0,				// Replaced with offset to .plt.
  0, 0, 0, 0,				// Replaced with size of .plt.
  0,					// Augmentation size.
  elfcpp::DW_CFA_def_cfa_offset, 8,	// DW_CFA_def_cfa_offset: 8.
  elfcpp::DW_CFA_advance_loc + 6,	// Advance 6 to __PLT__ + 6.
  elfcpp::DW_CFA_def_cfa_offset, 12,	// DW_CFA_def_cfa_offset: 12.
  elfcpp::DW_CFA_advance_loc + 58,	// Advance 58 to __PLT__ + 64.
  elfcpp::DW_CFA_def_cfa_expression,	// DW_CFA_def_cfa_expression.
  13,					// Block length.
  elfcpp::DW_OP_breg4, 4,		// Push %esp + 4.
  elfcpp::DW_OP_breg8, 0,		// Push %eip.
  elfcpp::DW_OP_const1u, 63,            // Push 0x3f.
  elfcpp::DW_OP_and,			// & (%eip & 0x3f).
  elfcpp::DW_OP_const1u, 37,            // Push 0x25.
  elfcpp::DW_OP_ge,			// >= ((%eip & 0x3f) >= 0x25)
  elfcpp::DW_OP_lit2,			// Push 2.
  elfcpp::DW_OP_shl,			// << (((%eip & 0x3f) >= 0x25) << 2)
  elfcpp::DW_OP_plus,			// + ((((%eip&0x3f)>=0x25)<<2)+%esp+4
  elfcpp::DW_CFA_nop,			// Align to 32 bytes.
  elfcpp::DW_CFA_nop
};

// Return a string used to fill a code section with nops.
// For NaCl, long NOPs are only valid if they do not cross
// bundle alignment boundaries, so keep it simple with one-byte NOPs.
std::string
Target_i386_nacl::do_code_fill(section_size_type length) const
{
  return std::string(length, static_cast<char>(0x90));
}

// The selector for i386-nacl object files.

class Target_selector_i386_nacl
  : public Target_selector_nacl<Target_selector_i386, Target_i386_nacl>
{
 public:
  Target_selector_i386_nacl()
    : Target_selector_nacl<Target_selector_i386,
			   Target_i386_nacl>("x86-32",
					     "elf32-i386-nacl",
					     "elf_i386_nacl")
  { }
};

Target_selector_i386_nacl target_selector_i386;

// IAMCU variant.  It uses EM_IAMCU, not EM_386.

class Target_iamcu : public Target_i386
{
 public:
  Target_iamcu()
    : Target_i386(&iamcu_info)
  { }

 private:
  // Information about this specific target which we pass to the
  // general Target structure.
  static const Target::Target_info iamcu_info;
};

const Target::Target_info Target_iamcu::iamcu_info =
{
  32,			// size
  false,		// is_big_endian
  elfcpp::EM_IAMCU,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  true,			// has_code_fill
  true,			// is_default_stack_executable
  true,			// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/usr/lib/libc.so.1",	// dynamic_linker
  0x08048000,		// default_text_segment_address
  0x1000,		// abi_pagesize (overridable by -z max-page-size)
  0x1000,		// common_pagesize (overridable by -z common-page-size)
  false,                // isolate_execinstr
  0,                    // rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
};

class Target_selector_iamcu : public Target_selector
{
public:
  Target_selector_iamcu()
    : Target_selector(elfcpp::EM_IAMCU, 32, false, "elf32-iamcu",
		      "elf_iamcu")
  { }

  Target*
  do_instantiate_target()
  { return new Target_iamcu(); }
};

Target_selector_iamcu target_selector_iamcu;

} // End anonymous namespace.
