Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
    33         kx // i386.cc -- i386 target support for gold.
    33         kx 
    33         kx // Copyright (C) 2006-2023 Free Software Foundation, Inc.
    33         kx // Written by Ian Lance Taylor <iant@google.com>.
    33         kx 
    33         kx // This file is part of gold.
    33         kx 
    33         kx // This program is free software; you can redistribute it and/or modify
    33         kx // it under the terms of the GNU General Public License as published by
    33         kx // the Free Software Foundation; either version 3 of the License, or
    33         kx // (at your option) any later version.
    33         kx 
    33         kx // This program is distributed in the hope that it will be useful,
    33         kx // but WITHOUT ANY WARRANTY; without even the implied warranty of
    33         kx // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    33         kx // GNU General Public License for more details.
    33         kx 
    33         kx // You should have received a copy of the GNU General Public License
    33         kx // along with this program; if not, write to the Free Software
    33         kx // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    33         kx // MA 02110-1301, USA.
    33         kx 
    33         kx #include "gold.h"
    33         kx 
    33         kx #include <cstring>
    33         kx 
    33         kx #include "elfcpp.h"
    33         kx #include "dwarf.h"
    33         kx #include "parameters.h"
    33         kx #include "reloc.h"
    33         kx #include "i386.h"
    33         kx #include "object.h"
    33         kx #include "symtab.h"
    33         kx #include "layout.h"
    33         kx #include "output.h"
    33         kx #include "copy-relocs.h"
    33         kx #include "target.h"
    33         kx #include "target-reloc.h"
    33         kx #include "target-select.h"
    33         kx #include "tls.h"
    33         kx #include "freebsd.h"
    33         kx #include "nacl.h"
    33         kx #include "gc.h"
    33         kx 
    33         kx namespace
    33         kx {
    33         kx 
    33         kx using namespace gold;
    33         kx 
    33         kx // A class to handle the .got.plt section.
    33         kx 
    33         kx class Output_data_got_plt_i386 : public Output_section_data_build
    33         kx {
    33         kx  public:
    33         kx   Output_data_got_plt_i386(Layout* layout)
    33         kx     : Output_section_data_build(4),
    33         kx       layout_(layout)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   // Write out the PLT data.
    33         kx   void
    33         kx   do_write(Output_file*);
    33         kx 
    33         kx   // Write to a map file.
    33         kx   void
    33         kx   do_print_to_mapfile(Mapfile* mapfile) const
    33         kx   { mapfile->print_output_data(this, "** GOT PLT"); }
    33         kx 
    33         kx  private:
    33         kx   // A pointer to the Layout class, so that we can find the .dynamic
    33         kx   // section when we write out the GOT PLT section.
    33         kx   Layout* layout_;
    33         kx };
    33         kx 
    33         kx // A class to handle the PLT data.
    33         kx // This is an abstract base class that handles most of the linker details
    33         kx // but does not know the actual contents of PLT entries.  The derived
    33         kx // classes below fill in those details.
    33         kx 
    33         kx class Output_data_plt_i386 : public Output_section_data
    33         kx {
    33         kx  public:
    33         kx   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
    33         kx 
    33         kx   Output_data_plt_i386(Layout*, uint64_t addralign,
    33         kx 		       Output_data_got_plt_i386*, Output_data_space*);
    33         kx 
    33         kx   // Add an entry to the PLT.
    33         kx   void
    33         kx   add_entry(Symbol_table*, Layout*, Symbol* gsym);
    33         kx 
    33         kx   // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
    33         kx   unsigned int
    33         kx   add_local_ifunc_entry(Symbol_table*, Layout*,
    33         kx 			Sized_relobj_file<32, false>* relobj,
    33         kx 			unsigned int local_sym_index);
    33         kx 
    33         kx   // Return the .rel.plt section data.
    33         kx   Reloc_section*
    33         kx   rel_plt() const
    33         kx   { return this->rel_; }
    33         kx 
    33         kx   // Return where the TLS_DESC relocations should go.
    33         kx   Reloc_section*
    33         kx   rel_tls_desc(Layout*);
    33         kx 
    33         kx   // Return where the IRELATIVE relocations should go.
    33         kx   Reloc_section*
    33         kx   rel_irelative(Symbol_table*, Layout*);
    33         kx 
    33         kx   // Return whether we created a section for IRELATIVE relocations.
    33         kx   bool
    33         kx   has_irelative_section() const
    33         kx   { return this->irelative_rel_ != NULL; }
    33         kx 
    33         kx   // Return the number of PLT entries.
    33         kx   unsigned int
    33         kx   entry_count() const
    33         kx   { return this->count_ + this->irelative_count_; }
    33         kx 
    33         kx   // Return the offset of the first non-reserved PLT entry.
    33         kx   unsigned int
    33         kx   first_plt_entry_offset()
    33         kx   { return this->get_plt_entry_size(); }
    33         kx 
    33         kx   // Return the size of a PLT entry.
    33         kx   unsigned int
    33         kx   get_plt_entry_size() const
    33         kx   { return this->do_get_plt_entry_size(); }
    33         kx 
    33         kx   // Return the PLT address to use for a global symbol.
    33         kx   uint64_t
    33         kx   address_for_global(const Symbol*);
    33         kx 
    33         kx   // Return the PLT address to use for a local symbol.
    33         kx   uint64_t
    33         kx   address_for_local(const Relobj*, unsigned int symndx);
    33         kx 
    33         kx   // Add .eh_frame information for the PLT.
    33         kx   void
    33         kx   add_eh_frame(Layout* layout)
    33         kx   { this->do_add_eh_frame(layout); }
    33         kx 
    33         kx  protected:
    33         kx   // Fill the first PLT entry, given the pointer to the PLT section data
    33         kx   // and the runtime address of the GOT.
    33         kx   void
    33         kx   fill_first_plt_entry(unsigned char* pov,
    33         kx 		       elfcpp::Elf_types<32>::Elf_Addr got_address)
    33         kx   { this->do_fill_first_plt_entry(pov, got_address); }
    33         kx 
    33         kx   // Fill a normal PLT entry, given the pointer to the entry's data in the
    33         kx   // section, the runtime address of the GOT, the offset into the GOT of
    33         kx   // the corresponding slot, the offset into the relocation section of the
    33         kx   // corresponding reloc, and the offset of this entry within the whole
    33         kx   // PLT.  Return the offset from this PLT entry's runtime address that
    33         kx   // should be used to compute the initial value of the GOT slot.
    33         kx   unsigned int
    33         kx   fill_plt_entry(unsigned char* pov,
    33         kx 		 elfcpp::Elf_types<32>::Elf_Addr got_address,
    33         kx 		 unsigned int got_offset,
    33         kx 		 unsigned int plt_offset,
    33         kx 		 unsigned int plt_rel_offset)
    33         kx   {
    33         kx     return this->do_fill_plt_entry(pov, got_address, got_offset,
    33         kx 				   plt_offset, plt_rel_offset);
    33         kx   }
    33         kx 
    33         kx   virtual unsigned int
    33         kx   do_get_plt_entry_size() const = 0;
    33         kx 
    33         kx   virtual void
    33         kx   do_fill_first_plt_entry(unsigned char* pov,
    33         kx 			  elfcpp::Elf_types<32>::Elf_Addr got_address) = 0;
    33         kx 
    33         kx   virtual unsigned int
    33         kx   do_fill_plt_entry(unsigned char* pov,
    33         kx 		    elfcpp::Elf_types<32>::Elf_Addr got_address,
    33         kx 		    unsigned int got_offset,
    33         kx 		    unsigned int plt_offset,
    33         kx 		    unsigned int plt_rel_offset) = 0;
    33         kx 
    33         kx   virtual void
    33         kx   do_add_eh_frame(Layout*) = 0;
    33         kx 
    33         kx   void
    33         kx   do_adjust_output_section(Output_section* os);
    33         kx 
    33         kx   // Write to a map file.
    33         kx   void
    33         kx   do_print_to_mapfile(Mapfile* mapfile) const
    33         kx   { mapfile->print_output_data(this, _("** PLT")); }
    33         kx 
    33         kx   // The .eh_frame unwind information for the PLT.
    33         kx   // The CIE is common across variants of the PLT format.
    33         kx   static const int plt_eh_frame_cie_size = 16;
    33         kx   static const unsigned char plt_eh_frame_cie[plt_eh_frame_cie_size];
    33         kx 
    33         kx  private:
    33         kx   // Set the final size.
    33         kx   void
    33         kx   set_final_data_size()
    33         kx   {
    33         kx     this->set_data_size((this->count_ + this->irelative_count_ + 1)
    33         kx 			* this->get_plt_entry_size());
    33         kx   }
    33         kx 
    33         kx   // Write out the PLT data.
    33         kx   void
    33         kx   do_write(Output_file*);
    33         kx 
    33         kx   // We keep a list of global STT_GNU_IFUNC symbols, each with its
    33         kx   // offset in the GOT.
    33         kx   struct Global_ifunc
    33         kx   {
    33         kx     Symbol* sym;
    33         kx     unsigned int got_offset;
    33         kx   };
    33         kx 
    33         kx   // We keep a list of local STT_GNU_IFUNC symbols, each with its
    33         kx   // offset in the GOT.
    33         kx   struct Local_ifunc
    33         kx   {
    33         kx     Sized_relobj_file<32, false>* object;
    33         kx     unsigned int local_sym_index;
    33         kx     unsigned int got_offset;
    33         kx   };
    33         kx 
    33         kx   // The reloc section.
    33         kx   Reloc_section* rel_;
    33         kx   // The TLS_DESC relocations, if necessary.  These must follow the
    33         kx   // regular PLT relocs.
    33         kx   Reloc_section* tls_desc_rel_;
    33         kx   // The IRELATIVE relocations, if necessary.  These must follow the
    33         kx   // regular relocatoins and the TLS_DESC relocations.
    33         kx   Reloc_section* irelative_rel_;
    33         kx   // The .got.plt section.
    33         kx   Output_data_got_plt_i386* got_plt_;
    33         kx   // The part of the .got.plt section used for IRELATIVE relocs.
    33         kx   Output_data_space* got_irelative_;
    33         kx   // The number of PLT entries.
    33         kx   unsigned int count_;
    33         kx   // Number of PLT entries with R_386_IRELATIVE relocs.  These follow
    33         kx   // the regular PLT entries.
    33         kx   unsigned int irelative_count_;
    33         kx   // Global STT_GNU_IFUNC symbols.
    33         kx   std::vector<Global_ifunc> global_ifuncs_;
    33         kx   // Local STT_GNU_IFUNC symbols.
    33         kx   std::vector<Local_ifunc> local_ifuncs_;
    33         kx };
    33         kx 
    33         kx // This is an abstract class for the standard PLT layout.
    33         kx // The derived classes below handle the actual PLT contents
    33         kx // for the executable (non-PIC) and shared-library (PIC) cases.
    33         kx // The unwind information is uniform across those two, so it's here.
    33         kx 
    33         kx class Output_data_plt_i386_standard : public Output_data_plt_i386
    33         kx {
    33         kx  public:
    33         kx   Output_data_plt_i386_standard(Layout* layout,
    33         kx 				Output_data_got_plt_i386* got_plt,
    33         kx 				Output_data_space* got_irelative)
    33         kx     : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   virtual unsigned int
    33         kx   do_get_plt_entry_size() const
    33         kx   { return plt_entry_size; }
    33         kx 
    33         kx   virtual void
    33         kx   do_add_eh_frame(Layout* layout)
    33         kx   {
    33         kx     layout->add_eh_frame_for_plt(this, plt_eh_frame_cie, plt_eh_frame_cie_size,
    33         kx 				 plt_eh_frame_fde, plt_eh_frame_fde_size);
    33         kx   }
    33         kx 
    33         kx   // The size of an entry in the PLT.
    33         kx   static const int plt_entry_size = 16;
    33         kx 
    33         kx   // The .eh_frame unwind information for the PLT.
    33         kx   static const int plt_eh_frame_fde_size = 32;
    33         kx   static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size];
    33         kx };
    33         kx 
    33         kx // Actually fill the PLT contents for an executable (non-PIC).
    33         kx 
    33         kx class Output_data_plt_i386_exec : public Output_data_plt_i386_standard
    33         kx {
    33         kx public:
    33         kx   Output_data_plt_i386_exec(Layout* layout,
    33         kx 			    Output_data_got_plt_i386* got_plt,
    33         kx 			    Output_data_space* got_irelative)
    33         kx     : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   virtual void
    33         kx   do_fill_first_plt_entry(unsigned char* pov,
    33         kx 			  elfcpp::Elf_types<32>::Elf_Addr got_address);
    33         kx 
    33         kx   virtual unsigned int
    33         kx   do_fill_plt_entry(unsigned char* pov,
    33         kx 		    elfcpp::Elf_types<32>::Elf_Addr got_address,
    33         kx 		    unsigned int got_offset,
    33         kx 		    unsigned int plt_offset,
    33         kx 		    unsigned int plt_rel_offset);
    33         kx 
    33         kx  private:
    33         kx   // The first entry in the PLT for an executable.
    33         kx   static const unsigned char first_plt_entry[plt_entry_size];
    33         kx 
    33         kx   // Other entries in the PLT for an executable.
    33         kx   static const unsigned char plt_entry[plt_entry_size];
    33         kx };
    33         kx 
    33         kx // Actually fill the PLT contents for a shared library (PIC).
    33         kx 
    33         kx class Output_data_plt_i386_dyn : public Output_data_plt_i386_standard
    33         kx {
    33         kx  public:
    33         kx   Output_data_plt_i386_dyn(Layout* layout,
    33         kx 			   Output_data_got_plt_i386* got_plt,
    33         kx 			   Output_data_space* got_irelative)
    33         kx     : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   virtual void
    33         kx   do_fill_first_plt_entry(unsigned char* pov, elfcpp::Elf_types<32>::Elf_Addr);
    33         kx 
    33         kx   virtual unsigned int
    33         kx   do_fill_plt_entry(unsigned char* pov,
    33         kx 		    elfcpp::Elf_types<32>::Elf_Addr,
    33         kx 		    unsigned int got_offset,
    33         kx 		    unsigned int plt_offset,
    33         kx 		    unsigned int plt_rel_offset);
    33         kx 
    33         kx  private:
    33         kx   // The first entry in the PLT for a shared object.
    33         kx   static const unsigned char first_plt_entry[plt_entry_size];
    33         kx 
    33         kx   // Other entries in the PLT for a shared object.
    33         kx   static const unsigned char plt_entry[plt_entry_size];
    33         kx };
    33         kx 
    33         kx // The i386 target class.
    33         kx // TLS info comes from
    33         kx //   http://people.redhat.com/drepper/tls.pdf
    33         kx //   http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt
    33         kx 
    33         kx class Target_i386 : public Sized_target<32, false>
    33         kx {
    33         kx  public:
    33         kx   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
    33         kx 
    33         kx   Target_i386(const Target::Target_info* info = &i386_info)
    33         kx     : Sized_target<32, false>(info),
    33         kx       got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
    33         kx       got_tlsdesc_(NULL), global_offset_table_(NULL), rel_dyn_(NULL),
    33         kx       rel_irelative_(NULL), copy_relocs_(elfcpp::R_386_COPY),
    33         kx       got_mod_index_offset_(-1U), tls_base_symbol_defined_(false),
    33         kx       isa_1_used_(0), isa_1_needed_(0),
    33         kx       feature_1_(0), feature_2_used_(0), feature_2_needed_(0),
    33         kx       object_isa_1_used_(0), object_feature_1_(0),
    33         kx       object_feature_2_used_(0), seen_first_object_(false)
    33         kx   { }
    33         kx 
    33         kx   // Process the relocations to determine unreferenced sections for
    33         kx   // garbage collection.
    33         kx   void
    33         kx   gc_process_relocs(Symbol_table* symtab,
    33         kx 		    Layout* layout,
    33         kx 		    Sized_relobj_file<32, false>* object,
    33         kx 		    unsigned int data_shndx,
    33         kx 		    unsigned int sh_type,
    33         kx 		    const unsigned char* prelocs,
    33         kx 		    size_t reloc_count,
    33         kx 		    Output_section* output_section,
    33         kx 		    bool needs_special_offset_handling,
    33         kx 		    size_t local_symbol_count,
    33         kx 		    const unsigned char* plocal_symbols);
    33         kx 
    33         kx   // Scan the relocations to look for symbol adjustments.
    33         kx   void
    33         kx   scan_relocs(Symbol_table* symtab,
    33         kx 	      Layout* layout,
    33         kx 	      Sized_relobj_file<32, false>* object,
    33         kx 	      unsigned int data_shndx,
    33         kx 	      unsigned int sh_type,
    33         kx 	      const unsigned char* prelocs,
    33         kx 	      size_t reloc_count,
    33         kx 	      Output_section* output_section,
    33         kx 	      bool needs_special_offset_handling,
    33         kx 	      size_t local_symbol_count,
    33         kx 	      const unsigned char* plocal_symbols);
    33         kx 
    33         kx   // Finalize the sections.
    33         kx   void
    33         kx   do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
    33         kx 
    33         kx   // Return the value to use for a dynamic which requires special
    33         kx   // treatment.
    33         kx   uint64_t
    33         kx   do_dynsym_value(const Symbol*) const;
    33         kx 
    33         kx   // Relocate a section.
    33         kx   void
    33         kx   relocate_section(const Relocate_info<32, false>*,
    33         kx 		   unsigned int sh_type,
    33         kx 		   const unsigned char* prelocs,
    33         kx 		   size_t reloc_count,
    33         kx 		   Output_section* output_section,
    33         kx 		   bool needs_special_offset_handling,
    33         kx 		   unsigned char* view,
    33         kx 		   elfcpp::Elf_types<32>::Elf_Addr view_address,
    33         kx 		   section_size_type view_size,
    33         kx 		   const Reloc_symbol_changes*);
    33         kx 
    33         kx   // Scan the relocs during a relocatable link.
    33         kx   void
    33         kx   scan_relocatable_relocs(Symbol_table* symtab,
    33         kx 			  Layout* layout,
    33         kx 			  Sized_relobj_file<32, false>* object,
    33         kx 			  unsigned int data_shndx,
    33         kx 			  unsigned int sh_type,
    33         kx 			  const unsigned char* prelocs,
    33         kx 			  size_t reloc_count,
    33         kx 			  Output_section* output_section,
    33         kx 			  bool needs_special_offset_handling,
    33         kx 			  size_t local_symbol_count,
    33         kx 			  const unsigned char* plocal_symbols,
    33         kx 			  Relocatable_relocs*);
    33         kx 
    33         kx   // Scan the relocs for --emit-relocs.
    33         kx   void
    33         kx   emit_relocs_scan(Symbol_table* symtab,
    33         kx 		   Layout* layout,
    33         kx 		   Sized_relobj_file<32, false>* object,
    33         kx 		   unsigned int data_shndx,
    33         kx 		   unsigned int sh_type,
    33         kx 		   const unsigned char* prelocs,
    33         kx 		   size_t reloc_count,
    33         kx 		   Output_section* output_section,
    33         kx 		   bool needs_special_offset_handling,
    33         kx 		   size_t local_symbol_count,
    33         kx 		   const unsigned char* plocal_syms,
    33         kx 		   Relocatable_relocs* rr);
    33         kx 
    33         kx   // Emit relocations for a section.
    33         kx   void
    33         kx   relocate_relocs(const Relocate_info<32, false>*,
    33         kx 		  unsigned int sh_type,
    33         kx 		  const unsigned char* prelocs,
    33         kx 		  size_t reloc_count,
    33         kx 		  Output_section* output_section,
    33         kx 		  elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
    33         kx 		  unsigned char* view,
    33         kx 		  elfcpp::Elf_types<32>::Elf_Addr view_address,
    33         kx 		  section_size_type view_size,
    33         kx 		  unsigned char* reloc_view,
    33         kx 		  section_size_type reloc_view_size);
    33         kx 
    33         kx   // Return a string used to fill a code section with nops.
    33         kx   std::string
    33         kx   do_code_fill(section_size_type length) const;
    33         kx 
    33         kx   // Return whether SYM is defined by the ABI.
    33         kx   bool
    33         kx   do_is_defined_by_abi(const Symbol* sym) const
    33         kx   { return strcmp(sym->name(), "___tls_get_addr") == 0; }
    33         kx 
    33         kx   // Return whether a symbol name implies a local label.  The UnixWare
    33         kx   // 2.1 cc generates temporary symbols that start with .X, so we
    33         kx   // recognize them here.  FIXME: do other SVR4 compilers also use .X?.
    33         kx   // If so, we should move the .X recognition into
    33         kx   // Target::do_is_local_label_name.
    33         kx   bool
    33         kx   do_is_local_label_name(const char* name) const
    33         kx   {
    33         kx     if (name[0] == '.' && name[1] == 'X')
    33         kx       return true;
    33         kx     return Target::do_is_local_label_name(name);
    33         kx   }
    33         kx 
    33         kx   // Return the PLT address to use for a global symbol.
    33         kx   uint64_t
    33         kx   do_plt_address_for_global(const Symbol* gsym) const
    33         kx   { return this->plt_section()->address_for_global(gsym); }
    33         kx 
    33         kx   uint64_t
    33         kx   do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
    33         kx   { return this->plt_section()->address_for_local(relobj, symndx); }
    33         kx 
    33         kx   // We can tell whether we take the address of a function.
    33         kx   inline bool
    33         kx   do_can_check_for_function_pointers() const
    33         kx   { return true; }
    33         kx 
    33         kx   // Return the base for a DW_EH_PE_datarel encoding.
    33         kx   uint64_t
    33         kx   do_ehframe_datarel_base() const;
    33         kx 
    33         kx   // Return whether SYM is call to a non-split function.
    33         kx   bool
    33         kx   do_is_call_to_non_split(const Symbol* sym, const unsigned char*,
    33         kx 			  const unsigned char*, section_size_type) const;
    33         kx 
    33         kx   // Adjust -fsplit-stack code which calls non-split-stack code.
    33         kx   void
    33         kx   do_calls_non_split(Relobj* object, unsigned int shndx,
    33         kx 		     section_offset_type fnoffset, section_size_type fnsize,
    33         kx 		     const unsigned char* prelocs, size_t reloc_count,
    33         kx 		     unsigned char* view, section_size_type view_size,
    33         kx 		     std::string* from, std::string* to) const;
    33         kx 
    33         kx   // Return the size of the GOT section.
    33         kx   section_size_type
    33         kx   got_size() const
    33         kx   {
    33         kx     gold_assert(this->got_ != NULL);
    33         kx     return this->got_->data_size();
    33         kx   }
    33         kx 
    33         kx   // Return the number of entries in the GOT.
    33         kx   unsigned int
    33         kx   got_entry_count() const
    33         kx   {
    33         kx     if (this->got_ == NULL)
    33         kx       return 0;
    33         kx     return this->got_size() / 4;
    33         kx   }
    33         kx 
    33         kx   // Return the number of entries in the PLT.
    33         kx   unsigned int
    33         kx   plt_entry_count() const;
    33         kx 
    33         kx   // Return the offset of the first non-reserved PLT entry.
    33         kx   unsigned int
    33         kx   first_plt_entry_offset() const;
    33         kx 
    33         kx   // Return the size of each PLT entry.
    33         kx   unsigned int
    33         kx   plt_entry_size() const;
    33         kx 
    33         kx  protected:
    33         kx   // Instantiate the plt_ member.
    33         kx   // This chooses the right PLT flavor for an executable or a shared object.
    33         kx   Output_data_plt_i386*
    33         kx   make_data_plt(Layout* layout,
    33         kx 		Output_data_got_plt_i386* got_plt,
    33         kx 		Output_data_space* got_irelative,
    33         kx 		bool dyn)
    33         kx   { return this->do_make_data_plt(layout, got_plt, got_irelative, dyn); }
    33         kx 
    33         kx   virtual Output_data_plt_i386*
    33         kx   do_make_data_plt(Layout* layout,
    33         kx 		   Output_data_got_plt_i386* got_plt,
    33         kx 		   Output_data_space* got_irelative,
    33         kx 		   bool dyn)
    33         kx   {
    33         kx     if (dyn)
    33         kx       return new Output_data_plt_i386_dyn(layout, got_plt, got_irelative);
    33         kx     else
    33         kx       return new Output_data_plt_i386_exec(layout, got_plt, got_irelative);
    33         kx   }
    33         kx 
    33         kx  private:
    33         kx   // The class which scans relocations.
    33         kx   struct Scan
    33         kx   {
    33         kx     static inline int
    33         kx 
    33         kx     get_reference_flags(unsigned int r_type);
    33         kx 
    33         kx     inline void
    33         kx     local(Symbol_table* symtab, Layout* layout, Target_i386* target,
    33         kx 	  Sized_relobj_file<32, false>* object,
    33         kx 	  unsigned int data_shndx,
    33         kx 	  Output_section* output_section,
    33         kx 	  const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
    33         kx 	  const elfcpp::Sym<32, false>& lsym,
    33         kx 	  bool is_discarded);
    33         kx 
    33         kx     inline void
    33         kx     global(Symbol_table* symtab, Layout* layout, Target_i386* target,
    33         kx 	   Sized_relobj_file<32, false>* object,
    33         kx 	   unsigned int data_shndx,
    33         kx 	   Output_section* output_section,
    33         kx 	   const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
    33         kx 	   Symbol* gsym);
    33         kx 
    33         kx     inline bool
    33         kx     local_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
    33         kx 					Target_i386* target,
    33         kx 					Sized_relobj_file<32, false>* object,
    33         kx 					unsigned int data_shndx,
    33         kx 					Output_section* output_section,
    33         kx 					const elfcpp::Rel<32, false>& reloc,
    33         kx 					unsigned int r_type,
    33         kx 					const elfcpp::Sym<32, false>& lsym);
    33         kx 
    33         kx     inline bool
    33         kx     global_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
    33         kx 					 Target_i386* target,
    33         kx 					 Sized_relobj_file<32, false>* object,
    33         kx 					 unsigned int data_shndx,
    33         kx 					 Output_section* output_section,
    33         kx 					 const elfcpp::Rel<32, false>& reloc,
    33         kx 					 unsigned int r_type,
    33         kx 					 Symbol* gsym);
    33         kx 
    33         kx     inline bool
    33         kx     possible_function_pointer_reloc(unsigned int r_type);
    33         kx 
    33         kx     bool
    33         kx     reloc_needs_plt_for_ifunc(Sized_relobj_file<32, false>*,
    33         kx 			      unsigned int r_type);
    33         kx 
    33         kx     static void
    33         kx     unsupported_reloc_local(Sized_relobj_file<32, false>*, unsigned int r_type);
    33         kx 
    33         kx     static void
    33         kx     unsupported_reloc_global(Sized_relobj_file<32, false>*, unsigned int r_type,
    33         kx 			     Symbol*);
    33         kx   };
    33         kx 
    33         kx   // The class which implements relocation.
    33         kx   class Relocate
    33         kx   {
    33         kx    public:
    33         kx     Relocate()
    33         kx       : skip_call_tls_get_addr_(false),
    33         kx 	local_dynamic_type_(LOCAL_DYNAMIC_NONE)
    33         kx     { }
    33         kx 
    33         kx     ~Relocate()
    33         kx     {
    33         kx       if (this->skip_call_tls_get_addr_)
    33         kx 	{
    33         kx 	  // FIXME: This needs to specify the location somehow.
    33         kx 	  gold_error(_("missing expected TLS relocation"));
    33         kx 	}
    33         kx     }
    33         kx 
    33         kx     // Return whether the static relocation needs to be applied.
    33         kx     inline bool
    33         kx     should_apply_static_reloc(const Sized_symbol<32>* gsym,
    33         kx 			      unsigned int r_type,
    33         kx 			      bool is_32bit,
    33         kx 			      Output_section* output_section);
    33         kx 
    33         kx     // Do a relocation.  Return false if the caller should not issue
    33         kx     // any warnings about this relocation.
    33         kx     inline bool
    33         kx     relocate(const Relocate_info<32, false>*, unsigned int,
    33         kx 	     Target_i386*, Output_section*, size_t, const unsigned char*,
    33         kx 	     const Sized_symbol<32>*, const Symbol_value<32>*,
    33         kx 	     unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
    33         kx 	     section_size_type);
    33         kx 
    33         kx    private:
    33         kx     // Do a TLS relocation.
    33         kx     inline void
    33         kx     relocate_tls(const Relocate_info<32, false>*, Target_i386* target,
    33         kx 		 size_t relnum, const elfcpp::Rel<32, false>&,
    33         kx 		 unsigned int r_type, const Sized_symbol<32>*,
    33         kx 		 const Symbol_value<32>*,
    33         kx 		 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
    33         kx 		 section_size_type);
    33         kx 
    33         kx     // Do a TLS General-Dynamic to Initial-Exec transition.
    33         kx     inline void
    33         kx     tls_gd_to_ie(const Relocate_info<32, false>*, size_t relnum,
    33         kx 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
    33         kx 		 elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 		 unsigned char* view,
    33         kx 		 section_size_type view_size);
    33         kx 
    33         kx     // Do a TLS General-Dynamic to Local-Exec transition.
    33         kx     inline void
    33         kx     tls_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
    33         kx 		 Output_segment* tls_segment,
    33         kx 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
    33         kx 		 elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 		 unsigned char* view,
    33         kx 		 section_size_type view_size);
    33         kx 
    33         kx     // Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Initial-Exec
    33         kx     // transition.
    33         kx     inline void
    33         kx     tls_desc_gd_to_ie(const Relocate_info<32, false>*, size_t relnum,
    33         kx 		      const elfcpp::Rel<32, false>&, unsigned int r_type,
    33         kx 		      elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 		      unsigned char* view,
    33         kx 		      section_size_type view_size);
    33         kx 
    33         kx     // Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Local-Exec
    33         kx     // transition.
    33         kx     inline void
    33         kx     tls_desc_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
    33         kx 		      Output_segment* tls_segment,
    33         kx 		      const elfcpp::Rel<32, false>&, unsigned int r_type,
    33         kx 		      elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 		      unsigned char* view,
    33         kx 		      section_size_type view_size);
    33         kx 
    33         kx     // Do a TLS Local-Dynamic to Local-Exec transition.
    33         kx     inline void
    33         kx     tls_ld_to_le(const Relocate_info<32, false>*, size_t relnum,
    33         kx 		 Output_segment* tls_segment,
    33         kx 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
    33         kx 		 elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 		 unsigned char* view,
    33         kx 		 section_size_type view_size);
    33         kx 
    33         kx     // Do a TLS Initial-Exec to Local-Exec transition.
    33         kx     static inline void
    33         kx     tls_ie_to_le(const Relocate_info<32, false>*, size_t relnum,
    33         kx 		 Output_segment* tls_segment,
    33         kx 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
    33         kx 		 elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 		 unsigned char* view,
    33         kx 		 section_size_type view_size);
    33         kx 
    33         kx     // We need to keep track of which type of local dynamic relocation
    33         kx     // we have seen, so that we can optimize R_386_TLS_LDO_32 correctly.
    33         kx     enum Local_dynamic_type
    33         kx     {
    33         kx       LOCAL_DYNAMIC_NONE,
    33         kx       LOCAL_DYNAMIC_SUN,
    33         kx       LOCAL_DYNAMIC_GNU
    33         kx     };
    33         kx 
    33         kx     // This is set if we should skip the next reloc, which should be a
    33         kx     // PLT32 reloc against ___tls_get_addr.
    33         kx     bool skip_call_tls_get_addr_;
    33         kx     // The type of local dynamic relocation we have seen in the section
    33         kx     // being relocated, if any.
    33         kx     Local_dynamic_type local_dynamic_type_;
    33         kx   };
    33         kx 
    33         kx   // A class for inquiring about properties of a relocation,
    33         kx   // used while scanning relocs during a relocatable link and
    33         kx   // garbage collection.
    33         kx   class Classify_reloc :
    33         kx       public gold::Default_classify_reloc<elfcpp::SHT_REL, 32, false>
    33         kx   {
    33         kx    public:
    33         kx     typedef Reloc_types<elfcpp::SHT_REL, 32, false>::Reloc Reltype;
    33         kx 
    33         kx     // Return the explicit addend of the relocation (return 0 for SHT_REL).
    33         kx     static elfcpp::Elf_types<32>::Elf_Swxword
    33         kx     get_r_addend(const Reltype*)
    33         kx     { return 0; }
    33         kx 
    33         kx     // Return the size of the addend of the relocation (only used for SHT_REL).
    33         kx     static unsigned int
    33         kx     get_size_for_reloc(unsigned int, Relobj*);
    33         kx   };
    33         kx 
    33         kx   // Adjust TLS relocation type based on the options and whether this
    33         kx   // is a local symbol.
    33         kx   static tls::Tls_optimization
    33         kx   optimize_tls_reloc(bool is_final, int r_type);
    33         kx 
    33         kx   // Check if relocation against this symbol is a candidate for
    33         kx   // conversion from
    33         kx   // mov foo@GOT(%reg), %reg
    33         kx   // to
    33         kx   // lea foo@GOTOFF(%reg), %reg.
    33         kx   static bool
    33         kx   can_convert_mov_to_lea(const Symbol* gsym)
    33         kx   {
    33         kx     gold_assert(gsym != NULL);
    33         kx     return (gsym->type() != elfcpp::STT_GNU_IFUNC
    33         kx 	    && !gsym->is_undefined ()
    33         kx 	    && !gsym->is_from_dynobj()
    33         kx 	    && !gsym->is_preemptible()
    33         kx 	    && (!parameters->options().shared()
    33         kx 		|| (gsym->visibility() != elfcpp::STV_DEFAULT
    33         kx 		    && gsym->visibility() != elfcpp::STV_PROTECTED)
    33         kx 		|| parameters->options().Bsymbolic())
    33         kx 	    && strcmp(gsym->name(), "_DYNAMIC") != 0);
    33         kx   }
    33         kx 
    33         kx   // Get the GOT section, creating it if necessary.
    33         kx   Output_data_got<32, false>*
    33         kx   got_section(Symbol_table*, Layout*);
    33         kx 
    33         kx   // Get the GOT PLT section.
    33         kx   Output_data_got_plt_i386*
    33         kx   got_plt_section() const
    33         kx   {
    33         kx     gold_assert(this->got_plt_ != NULL);
    33         kx     return this->got_plt_;
    33         kx   }
    33         kx 
    33         kx   // Get the GOT section for TLSDESC entries.
    33         kx   Output_data_got<32, false>*
    33         kx   got_tlsdesc_section() const
    33         kx   {
    33         kx     gold_assert(this->got_tlsdesc_ != NULL);
    33         kx     return this->got_tlsdesc_;
    33         kx   }
    33         kx 
    33         kx   // Create the PLT section.
    33         kx   void
    33         kx   make_plt_section(Symbol_table* symtab, Layout* layout);
    33         kx 
    33         kx   // Create a PLT entry for a global symbol.
    33         kx   void
    33         kx   make_plt_entry(Symbol_table*, Layout*, Symbol*);
    33         kx 
    33         kx   // Create a PLT entry for a local STT_GNU_IFUNC symbol.
    33         kx   void
    33         kx   make_local_ifunc_plt_entry(Symbol_table*, Layout*,
    33         kx 			     Sized_relobj_file<32, false>* relobj,
    33         kx 			     unsigned int local_sym_index);
    33         kx 
    33         kx   // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
    33         kx   void
    33         kx   define_tls_base_symbol(Symbol_table*, Layout*);
    33         kx 
    33         kx   // Create a GOT entry for the TLS module index.
    33         kx   unsigned int
    33         kx   got_mod_index_entry(Symbol_table* symtab, Layout* layout,
    33         kx 		      Sized_relobj_file<32, false>* object);
    33         kx 
    33         kx   // Get the PLT section.
    33         kx   Output_data_plt_i386*
    33         kx   plt_section() const
    33         kx   {
    33         kx     gold_assert(this->plt_ != NULL);
    33         kx     return this->plt_;
    33         kx   }
    33         kx 
    33         kx   // Get the dynamic reloc section, creating it if necessary.
    33         kx   Reloc_section*
    33         kx   rel_dyn_section(Layout*);
    33         kx 
    33         kx   // Get the section to use for TLS_DESC relocations.
    33         kx   Reloc_section*
    33         kx   rel_tls_desc_section(Layout*) const;
    33         kx 
    33         kx   // Get the section to use for IRELATIVE relocations.
    33         kx   Reloc_section*
    33         kx   rel_irelative_section(Layout*);
    33         kx 
    33         kx   // Add a potential copy relocation.
    33         kx   void
    33         kx   copy_reloc(Symbol_table* symtab, Layout* layout,
    33         kx 	     Sized_relobj_file<32, false>* object,
    33         kx 	     unsigned int shndx, Output_section* output_section,
    33         kx 	     Symbol* sym, const elfcpp::Rel<32, false>& reloc)
    33         kx   {
    33         kx     unsigned int r_type = elfcpp::elf_r_type<32>(reloc.get_r_info());
    33         kx     this->copy_relocs_.copy_reloc(symtab, layout,
    33         kx 				  symtab->get_sized_symbol<32>(sym),
    33         kx 				  object, shndx, output_section,
    33         kx 				  r_type, reloc.get_r_offset(), 0,
    33         kx 				  this->rel_dyn_section(layout));
    33         kx   }
    33         kx 
    33         kx   // Record a target-specific program property in the .note.gnu.property
    33         kx   // section.
    33         kx   void
    33         kx   record_gnu_property(unsigned int, unsigned int, size_t,
    33         kx 		      const unsigned char*, const Object*);
    33         kx 
    33         kx   // Merge the target-specific program properties from the current object.
    33         kx   void
    33         kx   merge_gnu_properties(const Object*);
    33         kx 
    33         kx   // Finalize the target-specific program properties and add them back to
    33         kx   // the layout.
    33         kx   void
    33         kx   do_finalize_gnu_properties(Layout*) const;
    33         kx 
    33         kx   // Information about this specific target which we pass to the
    33         kx   // general Target structure.
    33         kx   static const Target::Target_info i386_info;
    33         kx 
    33         kx   // The types of GOT entries needed for this platform.
    33         kx   // These values are exposed to the ABI in an incremental link.
    33         kx   // Do not renumber existing values without changing the version
    33         kx   // number of the .gnu_incremental_inputs section.
    33         kx   enum Got_type
    33         kx   {
    33         kx     GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
    33         kx     GOT_TYPE_TLS_NOFFSET = 1,   // GOT entry for negative TLS offset
    33         kx     GOT_TYPE_TLS_OFFSET = 2,    // GOT entry for positive TLS offset
    33         kx     GOT_TYPE_TLS_PAIR = 3,      // GOT entry for TLS module/offset pair
    33         kx     GOT_TYPE_TLS_DESC = 4       // GOT entry for TLS_DESC pair
    33         kx   };
    33         kx 
    33         kx   // The GOT section.
    33         kx   Output_data_got<32, false>* got_;
    33         kx   // The PLT section.
    33         kx   Output_data_plt_i386* plt_;
    33         kx   // The GOT PLT section.
    33         kx   Output_data_got_plt_i386* got_plt_;
    33         kx   // The GOT section for IRELATIVE relocations.
    33         kx   Output_data_space* got_irelative_;
    33         kx   // The GOT section for TLSDESC relocations.
    33         kx   Output_data_got<32, false>* got_tlsdesc_;
    33         kx   // The _GLOBAL_OFFSET_TABLE_ symbol.
    33         kx   Symbol* global_offset_table_;
    33         kx   // The dynamic reloc section.
    33         kx   Reloc_section* rel_dyn_;
    33         kx   // The section to use for IRELATIVE relocs.
    33         kx   Reloc_section* rel_irelative_;
    33         kx   // Relocs saved to avoid a COPY reloc.
    33         kx   Copy_relocs<elfcpp::SHT_REL, 32, false> copy_relocs_;
    33         kx   // Offset of the GOT entry for the TLS module index.
    33         kx   unsigned int got_mod_index_offset_;
    33         kx   // True if the _TLS_MODULE_BASE_ symbol has been defined.
    33         kx   bool tls_base_symbol_defined_;
    33         kx 
    33         kx   // Target-specific program properties, from .note.gnu.property section.
    33         kx   // Each bit represents a specific feature.
    33         kx   uint32_t isa_1_used_;
    33         kx   uint32_t isa_1_needed_;
    33         kx   uint32_t feature_1_;
    33         kx   uint32_t feature_2_used_;
    33         kx   uint32_t feature_2_needed_;
    33         kx   // Target-specific properties from the current object.
    33         kx   // These bits get ORed into ISA_1_USED_ after all properties for the object
    33         kx   // have been processed. But if either is all zeroes (as when the property
    33         kx   // is absent from an object), the result should be all zeroes.
    33         kx   // (See PR ld/23486.)
    33         kx   uint32_t object_isa_1_used_;
    33         kx   // These bits get ANDed into FEATURE_1_ after all properties for the object
    33         kx   // have been processed.
    33         kx   uint32_t object_feature_1_;
    33         kx   uint32_t object_feature_2_used_;
    33         kx   // Whether we have seen our first object, for use in initializing FEATURE_1_.
    33         kx   bool seen_first_object_;
    33         kx };
    33         kx 
    33         kx const Target::Target_info Target_i386::i386_info =
    33         kx {
    33         kx   32,			// size
    33         kx   false,		// is_big_endian
    33         kx   elfcpp::EM_386,	// machine_code
    33         kx   false,		// has_make_symbol
    33         kx   false,		// has_resolve
    33         kx   true,			// has_code_fill
    33         kx   true,			// is_default_stack_executable
    33         kx   true,			// can_icf_inline_merge_sections
    33         kx   '\0',			// wrap_char
    33         kx   "/usr/lib/libc.so.1",	// dynamic_linker
    33         kx   0x08048000,		// default_text_segment_address
    33         kx   0x1000,		// abi_pagesize (overridable by -z max-page-size)
    33         kx   0x1000,		// common_pagesize (overridable by -z common-page-size)
    33         kx   false,                // isolate_execinstr
    33         kx   0,                    // rosegment_gap
    33         kx   elfcpp::SHN_UNDEF,	// small_common_shndx
    33         kx   elfcpp::SHN_UNDEF,	// large_common_shndx
    33         kx   0,			// small_common_section_flags
    33         kx   0,			// large_common_section_flags
    33         kx   NULL,			// attributes_section
    33         kx   NULL,			// attributes_vendor
    33         kx   "_start",		// entry_symbol_name
    33         kx   32,			// hash_entry_size
    33         kx   elfcpp::SHT_PROGBITS,	// unwind_section_type
    33         kx };
    33         kx 
    33         kx // Get the GOT section, creating it if necessary.
    33         kx 
    33         kx Output_data_got<32, false>*
    33         kx Target_i386::got_section(Symbol_table* symtab, Layout* layout)
    33         kx {
    33         kx   if (this->got_ == NULL)
    33         kx     {
    33         kx       gold_assert(symtab != NULL && layout != NULL);
    33         kx 
    33         kx       this->got_ = new Output_data_got<32, false>();
    33         kx 
    33         kx       // When using -z now, we can treat .got.plt as a relro section.
    33         kx       // Without -z now, it is modified after program startup by lazy
    33         kx       // PLT relocations.
    33         kx       bool is_got_plt_relro = parameters->options().now();
    33         kx       Output_section_order got_order = (is_got_plt_relro
    33         kx 					? ORDER_RELRO
    33         kx 					: ORDER_RELRO_LAST);
    33         kx       Output_section_order got_plt_order = (is_got_plt_relro
    33         kx 					    ? ORDER_RELRO
    33         kx 					    : ORDER_NON_RELRO_FIRST);
    33         kx 
    33         kx       layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
    33         kx 				      (elfcpp::SHF_ALLOC
    33         kx 				       | elfcpp::SHF_WRITE),
    33         kx 				      this->got_, got_order, true);
    33         kx 
    33         kx       this->got_plt_ = new Output_data_got_plt_i386(layout);
    33         kx       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
    33         kx 				      (elfcpp::SHF_ALLOC
    33         kx 				       | elfcpp::SHF_WRITE),
    33         kx 				      this->got_plt_, got_plt_order,
    33         kx 				      is_got_plt_relro);
    33         kx 
    33         kx       // The first three entries are reserved.
    33         kx       this->got_plt_->set_current_data_size(3 * 4);
    33         kx 
    33         kx       if (!is_got_plt_relro)
    33         kx 	{
    33         kx 	  // Those bytes can go into the relro segment.
    33         kx 	  layout->increase_relro(3 * 4);
    33         kx 	}
    33         kx 
    33         kx       // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
    33         kx       this->global_offset_table_ =
    33         kx 	symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
    33         kx 				      Symbol_table::PREDEFINED,
    33         kx 				      this->got_plt_,
    33         kx 				      0, 0, elfcpp::STT_OBJECT,
    33         kx 				      elfcpp::STB_LOCAL,
    33         kx 				      elfcpp::STV_HIDDEN, 0,
    33         kx 				      false, false);
    33         kx 
    33         kx       // If there are any IRELATIVE relocations, they get GOT entries
    33         kx       // in .got.plt after the jump slot relocations.
    33         kx       this->got_irelative_ = new Output_data_space(4, "** GOT IRELATIVE PLT");
    33         kx       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
    33         kx 				      (elfcpp::SHF_ALLOC
    33         kx 				       | elfcpp::SHF_WRITE),
    33         kx 				      this->got_irelative_,
    33         kx 				      got_plt_order, is_got_plt_relro);
    33         kx 
    33         kx       // If there are any TLSDESC relocations, they get GOT entries in
    33         kx       // .got.plt after the jump slot entries.
    33         kx       this->got_tlsdesc_ = new Output_data_got<32, false>();
    33         kx       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
    33         kx 				      (elfcpp::SHF_ALLOC
    33         kx 				       | elfcpp::SHF_WRITE),
    33         kx 				      this->got_tlsdesc_,
    33         kx 				      got_plt_order, is_got_plt_relro);
    33         kx     }
    33         kx 
    33         kx   return this->got_;
    33         kx }
    33         kx 
    33         kx // Get the dynamic reloc section, creating it if necessary.
    33         kx 
    33         kx Target_i386::Reloc_section*
    33         kx Target_i386::rel_dyn_section(Layout* layout)
    33         kx {
    33         kx   if (this->rel_dyn_ == NULL)
    33         kx     {
    33         kx       gold_assert(layout != NULL);
    33         kx       this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
    33         kx       layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
    33         kx 				      elfcpp::SHF_ALLOC, this->rel_dyn_,
    33         kx 				      ORDER_DYNAMIC_RELOCS, false);
    33         kx     }
    33         kx   return this->rel_dyn_;
    33         kx }
    33         kx 
    33         kx // Get the section to use for IRELATIVE relocs, creating it if
    33         kx // necessary.  These go in .rel.dyn, but only after all other dynamic
    33         kx // relocations.  They need to follow the other dynamic relocations so
    33         kx // that they can refer to global variables initialized by those
    33         kx // relocs.
    33         kx 
    33         kx Target_i386::Reloc_section*
    33         kx Target_i386::rel_irelative_section(Layout* layout)
    33         kx {
    33         kx   if (this->rel_irelative_ == NULL)
    33         kx     {
    33         kx       // Make sure we have already create the dynamic reloc section.
    33         kx       this->rel_dyn_section(layout);
    33         kx       this->rel_irelative_ = new Reloc_section(false);
    33         kx       layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
    33         kx 				      elfcpp::SHF_ALLOC, this->rel_irelative_,
    33         kx 				      ORDER_DYNAMIC_RELOCS, false);
    33         kx       gold_assert(this->rel_dyn_->output_section()
    33         kx 		  == this->rel_irelative_->output_section());
    33         kx     }
    33         kx   return this->rel_irelative_;
    33         kx }
    33         kx 
    33         kx // Record a target-specific program property from the .note.gnu.property
    33         kx // section.
    33         kx void
    33         kx Target_i386::record_gnu_property(
    33         kx     unsigned int, unsigned int pr_type,
    33         kx     size_t pr_datasz, const unsigned char* pr_data,
    33         kx     const Object* object)
    33         kx {
    33         kx   uint32_t val = 0;
    33         kx 
    33         kx   switch (pr_type)
    33         kx     {
    33         kx     case elfcpp::GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
    33         kx     case elfcpp::GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
    33         kx     case elfcpp::GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
    33         kx     case elfcpp::GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
    33         kx     case elfcpp::GNU_PROPERTY_X86_ISA_1_USED:
    33         kx     case elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED:
    33         kx     case elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND:
    33         kx     case elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED:
    33         kx     case elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED:
    33         kx       if (pr_datasz != 4)
    33         kx 	{
    33         kx 	  gold_warning(_("%s: corrupt .note.gnu.property section "
    33         kx 			 "(pr_datasz for property %d is not 4)"),
    33         kx 		       object->name().c_str(), pr_type);
    33         kx 	  return;
    33         kx 	}
    33         kx       val = elfcpp::Swap<32, false>::readval(pr_data);
    33         kx       break;
    33         kx     default:
    33         kx       gold_warning(_("%s: unknown program property type 0x%x "
    33         kx 		     "in .note.gnu.property section"),
    33         kx 		   object->name().c_str(), pr_type);
    33         kx       break;
    33         kx     }
    33         kx 
    33         kx   switch (pr_type)
    33         kx     {
    33         kx     case elfcpp::GNU_PROPERTY_X86_ISA_1_USED:
    33         kx       this->object_isa_1_used_ |= val;
    33         kx       break;
    33         kx     case elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED:
    33         kx       this->isa_1_needed_ |= val;
    33         kx       break;
    33         kx     case elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND:
    33         kx       // If we see multiple feature props in one object, OR them together.
    33         kx       this->object_feature_1_ |= val;
    33         kx       break;
    33         kx     case elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED:
    33         kx       this->object_feature_2_used_ |= val;
    33         kx       break;
    33         kx     case elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED:
    33         kx       this->feature_2_needed_ |= val;
    33         kx       break;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Merge the target-specific program properties from the current object.
    33         kx void
    33         kx Target_i386::merge_gnu_properties(const Object*)
    33         kx {
    33         kx   if (this->seen_first_object_)
    33         kx     {
    33         kx       // If any object is missing the ISA_1_USED property, we must omit
    33         kx       // it from the output file.
    33         kx       if (this->object_isa_1_used_ == 0)
    33         kx 	this->isa_1_used_ = 0;
    33         kx       else if (this->isa_1_used_ != 0)
    33         kx 	this->isa_1_used_ |= this->object_isa_1_used_;
    33         kx       this->feature_1_ &= this->object_feature_1_;
    33         kx       // If any object is missing the FEATURE_2_USED property, we must
    33         kx       // omit it from the output file.
    33         kx       if (this->object_feature_2_used_ == 0)
    33         kx 	this->feature_2_used_ = 0;
    33         kx       else if (this->feature_2_used_ != 0)
    33         kx 	this->feature_2_used_ |= this->object_feature_2_used_;
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       this->isa_1_used_ = this->object_isa_1_used_;
    33         kx       this->feature_1_ = this->object_feature_1_;
    33         kx       this->feature_2_used_ = this->object_feature_2_used_;
    33         kx       this->seen_first_object_ = true;
    33         kx     }
    33         kx   this->object_isa_1_used_ = 0;
    33         kx   this->object_feature_1_ = 0;
    33         kx   this->object_feature_2_used_ = 0;
    33         kx }
    33         kx 
    33         kx static inline void
    33         kx add_property(Layout* layout, unsigned int pr_type, uint32_t val)
    33         kx {
    33         kx   unsigned char buf[4];
    33         kx   elfcpp::Swap<32, false>::writeval(buf, val);
    33         kx   layout->add_gnu_property(elfcpp::NT_GNU_PROPERTY_TYPE_0, pr_type, 4, buf);
    33         kx }
    33         kx 
    33         kx // Finalize the target-specific program properties and add them back to
    33         kx // the layout.
    33         kx void
    33         kx Target_i386::do_finalize_gnu_properties(Layout* layout) const
    33         kx {
    33         kx   if (this->isa_1_used_ != 0)
    33         kx     add_property(layout, elfcpp::GNU_PROPERTY_X86_ISA_1_USED,
    33         kx 		 this->isa_1_used_);
    33         kx   if (this->isa_1_needed_ != 0)
    33         kx     add_property(layout, elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED,
    33         kx 		 this->isa_1_needed_);
    33         kx   if (this->feature_1_ != 0)
    33         kx     add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND,
    33         kx 		 this->feature_1_);
    33         kx   if (this->feature_2_used_ != 0)
    33         kx     add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED,
    33         kx 		 this->feature_2_used_);
    33         kx   if (this->feature_2_needed_ != 0)
    33         kx     add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED,
    33         kx 		 this->feature_2_needed_);
    33         kx }
    33         kx 
    33         kx // Write the first three reserved words of the .got.plt section.
    33         kx // The remainder of the section is written while writing the PLT
    33         kx // in Output_data_plt_i386::do_write.
    33         kx 
    33         kx void
    33         kx Output_data_got_plt_i386::do_write(Output_file* of)
    33         kx {
    33         kx   // The first entry in the GOT is the address of the .dynamic section
    33         kx   // aka the PT_DYNAMIC segment.  The next two entries are reserved.
    33         kx   // We saved space for them when we created the section in
    33         kx   // Target_i386::got_section.
    33         kx   const off_t got_file_offset = this->offset();
    33         kx   gold_assert(this->data_size() >= 12);
    33         kx   unsigned char* const got_view = of->get_output_view(got_file_offset, 12);
    33         kx   Output_section* dynamic = this->layout_->dynamic_section();
    33         kx   uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
    33         kx   elfcpp::Swap<32, false>::writeval(got_view, dynamic_addr);
    33         kx   memset(got_view + 4, 0, 8);
    33         kx   of->write_output_view(got_file_offset, 12, got_view);
    33         kx }
    33         kx 
    33         kx // Create the PLT section.  The ordinary .got section is an argument,
    33         kx // since we need to refer to the start.  We also create our own .got
    33         kx // section just for PLT entries.
    33         kx 
    33         kx Output_data_plt_i386::Output_data_plt_i386(Layout* layout,
    33         kx 					   uint64_t addralign,
    33         kx 					   Output_data_got_plt_i386* got_plt,
    33         kx 					   Output_data_space* got_irelative)
    33         kx   : Output_section_data(addralign),
    33         kx     tls_desc_rel_(NULL), irelative_rel_(NULL), got_plt_(got_plt),
    33         kx     got_irelative_(got_irelative), count_(0), irelative_count_(0),
    33         kx     global_ifuncs_(), local_ifuncs_()
    33         kx {
    33         kx   this->rel_ = new Reloc_section(false);
    33         kx   layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
    33         kx 				  elfcpp::SHF_ALLOC, this->rel_,
    33         kx 				  ORDER_DYNAMIC_PLT_RELOCS, false);
    33         kx }
    33         kx 
    33         kx void
    33         kx Output_data_plt_i386::do_adjust_output_section(Output_section* os)
    33         kx {
    33         kx   // UnixWare sets the entsize of .plt to 4, and so does the old GNU
    33         kx   // linker, and so do we.
    33         kx   os->set_entsize(4);
    33         kx }
    33         kx 
    33         kx // Add an entry to the PLT.
    33         kx 
    33         kx void
    33         kx Output_data_plt_i386::add_entry(Symbol_table* symtab, Layout* layout,
    33         kx 				Symbol* gsym)
    33         kx {
    33         kx   gold_assert(!gsym->has_plt_offset());
    33         kx 
    33         kx   // Every PLT entry needs a reloc.
    33         kx   if (gsym->type() == elfcpp::STT_GNU_IFUNC
    33         kx       && gsym->can_use_relative_reloc(false))
    33         kx     {
    33         kx       gsym->set_plt_offset(this->irelative_count_ * this->get_plt_entry_size());
    33         kx       ++this->irelative_count_;
    33         kx       section_offset_type got_offset =
    33         kx 	this->got_irelative_->current_data_size();
    33         kx       this->got_irelative_->set_current_data_size(got_offset + 4);
    33         kx       Reloc_section* rel = this->rel_irelative(symtab, layout);
    33         kx       rel->add_symbolless_global_addend(gsym, elfcpp::R_386_IRELATIVE,
    33         kx 					this->got_irelative_, got_offset);
    33         kx       struct Global_ifunc gi;
    33         kx       gi.sym = gsym;
    33         kx       gi.got_offset = got_offset;
    33         kx       this->global_ifuncs_.push_back(gi);
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       // When setting the PLT offset we skip the initial reserved PLT
    33         kx       // entry.
    33         kx       gsym->set_plt_offset((this->count_ + 1) * this->get_plt_entry_size());
    33         kx 
    33         kx       ++this->count_;
    33         kx 
    33         kx       section_offset_type got_offset = this->got_plt_->current_data_size();
    33         kx 
    33         kx       // Every PLT entry needs a GOT entry which points back to the
    33         kx       // PLT entry (this will be changed by the dynamic linker,
    33         kx       // normally lazily when the function is called).
    33         kx       this->got_plt_->set_current_data_size(got_offset + 4);
    33         kx 
    33         kx       gsym->set_needs_dynsym_entry();
    33         kx       this->rel_->add_global(gsym, elfcpp::R_386_JUMP_SLOT, this->got_plt_,
    33         kx 			     got_offset);
    33         kx     }
    33         kx 
    33         kx   // Note that we don't need to save the symbol.  The contents of the
    33         kx   // PLT are independent of which symbols are used.  The symbols only
    33         kx   // appear in the relocations.
    33         kx }
    33         kx 
    33         kx // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.  Return
    33         kx // the PLT offset.
    33         kx 
    33         kx unsigned int
    33         kx Output_data_plt_i386::add_local_ifunc_entry(
    33         kx     Symbol_table* symtab,
    33         kx     Layout* layout,
    33         kx     Sized_relobj_file<32, false>* relobj,
    33         kx     unsigned int local_sym_index)
    33         kx {
    33         kx   unsigned int plt_offset = this->irelative_count_ * this->get_plt_entry_size();
    33         kx   ++this->irelative_count_;
    33         kx 
    33         kx   section_offset_type got_offset = this->got_irelative_->current_data_size();
    33         kx 
    33         kx   // Every PLT entry needs a GOT entry which points back to the PLT
    33         kx   // entry.
    33         kx   this->got_irelative_->set_current_data_size(got_offset + 4);
    33         kx 
    33         kx   // Every PLT entry needs a reloc.
    33         kx   Reloc_section* rel = this->rel_irelative(symtab, layout);
    33         kx   rel->add_symbolless_local_addend(relobj, local_sym_index,
    33         kx 				   elfcpp::R_386_IRELATIVE,
    33         kx 				   this->got_irelative_, got_offset);
    33         kx 
    33         kx   struct Local_ifunc li;
    33         kx   li.object = relobj;
    33         kx   li.local_sym_index = local_sym_index;
    33         kx   li.got_offset = got_offset;
    33         kx   this->local_ifuncs_.push_back(li);
    33         kx 
    33         kx   return plt_offset;
    33         kx }
    33         kx 
    33         kx // Return where the TLS_DESC relocations should go, creating it if
    33         kx // necessary. These follow the JUMP_SLOT relocations.
    33         kx 
    33         kx Output_data_plt_i386::Reloc_section*
    33         kx Output_data_plt_i386::rel_tls_desc(Layout* layout)
    33         kx {
    33         kx   if (this->tls_desc_rel_ == NULL)
    33         kx     {
    33         kx       this->tls_desc_rel_ = new Reloc_section(false);
    33         kx       layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
    33         kx 				      elfcpp::SHF_ALLOC, this->tls_desc_rel_,
    33         kx 				      ORDER_DYNAMIC_PLT_RELOCS, false);
    33         kx       gold_assert(this->tls_desc_rel_->output_section()
    33         kx 		  == this->rel_->output_section());
    33         kx     }
    33         kx   return this->tls_desc_rel_;
    33         kx }
    33         kx 
    33         kx // Return where the IRELATIVE relocations should go in the PLT.  These
    33         kx // follow the JUMP_SLOT and TLS_DESC relocations.
    33         kx 
    33         kx Output_data_plt_i386::Reloc_section*
    33         kx Output_data_plt_i386::rel_irelative(Symbol_table* symtab, Layout* layout)
    33         kx {
    33         kx   if (this->irelative_rel_ == NULL)
    33         kx     {
    33         kx       // Make sure we have a place for the TLS_DESC relocations, in
    33         kx       // case we see any later on.
    33         kx       this->rel_tls_desc(layout);
    33         kx       this->irelative_rel_ = new Reloc_section(false);
    33         kx       layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
    33         kx 				      elfcpp::SHF_ALLOC, this->irelative_rel_,
    33         kx 				      ORDER_DYNAMIC_PLT_RELOCS, false);
    33         kx       gold_assert(this->irelative_rel_->output_section()
    33         kx 		  == this->rel_->output_section());
    33         kx 
    33         kx       if (parameters->doing_static_link())
    33         kx 	{
    33         kx 	  // A statically linked executable will only have a .rel.plt
    33         kx 	  // section to hold R_386_IRELATIVE relocs for STT_GNU_IFUNC
    33         kx 	  // symbols.  The library will use these symbols to locate
    33         kx 	  // the IRELATIVE relocs at program startup time.
    33         kx 	  symtab->define_in_output_data("__rel_iplt_start", NULL,
    33         kx 					Symbol_table::PREDEFINED,
    33         kx 					this->irelative_rel_, 0, 0,
    33         kx 					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
    33         kx 					elfcpp::STV_HIDDEN, 0, false, true);
    33         kx 	  symtab->define_in_output_data("__rel_iplt_end", NULL,
    33         kx 					Symbol_table::PREDEFINED,
    33         kx 					this->irelative_rel_, 0, 0,
    33         kx 					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
    33         kx 					elfcpp::STV_HIDDEN, 0, true, true);
    33         kx 	}
    33         kx     }
    33         kx   return this->irelative_rel_;
    33         kx }
    33         kx 
    33         kx // Return the PLT address to use for a global symbol.
    33         kx 
    33         kx uint64_t
    33         kx Output_data_plt_i386::address_for_global(const Symbol* gsym)
    33         kx {
    33         kx   uint64_t offset = 0;
    33         kx   if (gsym->type() == elfcpp::STT_GNU_IFUNC
    33         kx       && gsym->can_use_relative_reloc(false))
    33         kx     offset = (this->count_ + 1) * this->get_plt_entry_size();
    33         kx   return this->address() + offset + gsym->plt_offset();
    33         kx }
    33         kx 
    33         kx // Return the PLT address to use for a local symbol.  These are always
    33         kx // IRELATIVE relocs.
    33         kx 
    33         kx uint64_t
    33         kx Output_data_plt_i386::address_for_local(const Relobj* object,
    33         kx 					unsigned int r_sym)
    33         kx {
    33         kx   return (this->address()
    33         kx 	  + (this->count_ + 1) * this->get_plt_entry_size()
    33         kx 	  + object->local_plt_offset(r_sym));
    33         kx }
    33         kx 
    33         kx // The first entry in the PLT for an executable.
    33         kx 
    33         kx const unsigned char Output_data_plt_i386_exec::first_plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0xff, 0x35,	// pushl contents of memory address
    33         kx   0, 0, 0, 0,	// replaced with address of .got + 4
    33         kx   0xff, 0x25,	// jmp indirect
    33         kx   0, 0, 0, 0,	// replaced with address of .got + 8
    33         kx   0, 0, 0, 0	// unused
    33         kx };
    33         kx 
    33         kx void
    33         kx Output_data_plt_i386_exec::do_fill_first_plt_entry(
    33         kx     unsigned char* pov,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr got_address)
    33         kx {
    33         kx   memcpy(pov, first_plt_entry, plt_entry_size);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_address + 4);
    33         kx   elfcpp::Swap<32, false>::writeval(pov + 8, got_address + 8);
    33         kx }
    33         kx 
    33         kx // The first entry in the PLT for a shared object.
    33         kx 
    33         kx const unsigned char Output_data_plt_i386_dyn::first_plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0xff, 0xb3, 4, 0, 0, 0,	// pushl 4(%ebx)
    33         kx   0xff, 0xa3, 8, 0, 0, 0,	// jmp *8(%ebx)
    33         kx   0, 0, 0, 0			// unused
    33         kx };
    33         kx 
    33         kx void
    33         kx Output_data_plt_i386_dyn::do_fill_first_plt_entry(
    33         kx     unsigned char* pov,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr)
    33         kx {
    33         kx   memcpy(pov, first_plt_entry, plt_entry_size);
    33         kx }
    33         kx 
    33         kx // Subsequent entries in the PLT for an executable.
    33         kx 
    33         kx const unsigned char Output_data_plt_i386_exec::plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0xff, 0x25,	// jmp indirect
    33         kx   0, 0, 0, 0,	// replaced with address of symbol in .got
    33         kx   0x68,		// pushl immediate
    33         kx   0, 0, 0, 0,	// replaced with offset into relocation table
    33         kx   0xe9,		// jmp relative
    33         kx   0, 0, 0, 0	// replaced with offset to start of .plt
    33         kx };
    33         kx 
    33         kx unsigned int
    33         kx Output_data_plt_i386_exec::do_fill_plt_entry(
    33         kx     unsigned char* pov,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr got_address,
    33         kx     unsigned int got_offset,
    33         kx     unsigned int plt_offset,
    33         kx     unsigned int plt_rel_offset)
    33         kx {
    33         kx   memcpy(pov, plt_entry, plt_entry_size);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2,
    33         kx 					      got_address + got_offset);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 7, plt_rel_offset);
    33         kx   elfcpp::Swap<32, false>::writeval(pov + 12, - (plt_offset + 12 + 4));
    33         kx   return 6;
    33         kx }
    33         kx 
    33         kx // Subsequent entries in the PLT for a shared object.
    33         kx 
    33         kx const unsigned char Output_data_plt_i386_dyn::plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0xff, 0xa3,	// jmp *offset(%ebx)
    33         kx   0, 0, 0, 0,	// replaced with offset of symbol in .got
    33         kx   0x68,		// pushl immediate
    33         kx   0, 0, 0, 0,	// replaced with offset into relocation table
    33         kx   0xe9,		// jmp relative
    33         kx   0, 0, 0, 0	// replaced with offset to start of .plt
    33         kx };
    33         kx 
    33         kx unsigned int
    33         kx Output_data_plt_i386_dyn::do_fill_plt_entry(unsigned char* pov,
    33         kx 					    elfcpp::Elf_types<32>::Elf_Addr,
    33         kx 					    unsigned int got_offset,
    33         kx 					    unsigned int plt_offset,
    33         kx 					    unsigned int plt_rel_offset)
    33         kx {
    33         kx   memcpy(pov, plt_entry, plt_entry_size);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 7, plt_rel_offset);
    33         kx   elfcpp::Swap<32, false>::writeval(pov + 12, - (plt_offset + 12 + 4));
    33         kx   return 6;
    33         kx }
    33         kx 
    33         kx // The .eh_frame unwind information for the PLT.
    33         kx 
    33         kx const unsigned char
    33         kx Output_data_plt_i386::plt_eh_frame_cie[plt_eh_frame_cie_size] =
    33         kx {
    33         kx   1,				// CIE version.
    33         kx   'z',				// Augmentation: augmentation size included.
    33         kx   'R',				// Augmentation: FDE encoding included.
    33         kx   '\0',				// End of augmentation string.
    33         kx   1,				// Code alignment factor.
    33         kx   0x7c,				// Data alignment factor.
    33         kx   8,				// Return address column.
    33         kx   1,				// Augmentation size.
    33         kx   (elfcpp::DW_EH_PE_pcrel	// FDE encoding.
    33         kx    | elfcpp::DW_EH_PE_sdata4),
    33         kx   elfcpp::DW_CFA_def_cfa, 4, 4,	// DW_CFA_def_cfa: r4 (esp) ofs 4.
    33         kx   elfcpp::DW_CFA_offset + 8, 1,	// DW_CFA_offset: r8 (eip) at cfa-4.
    33         kx   elfcpp::DW_CFA_nop,		// Align to 16 bytes.
    33         kx   elfcpp::DW_CFA_nop
    33         kx };
    33         kx 
    33         kx const unsigned char
    33         kx Output_data_plt_i386_standard::plt_eh_frame_fde[plt_eh_frame_fde_size] =
    33         kx {
    33         kx   0, 0, 0, 0,				// Replaced with offset to .plt.
    33         kx   0, 0, 0, 0,				// Replaced with size of .plt.
    33         kx   0,					// Augmentation size.
    33         kx   elfcpp::DW_CFA_def_cfa_offset, 8,	// DW_CFA_def_cfa_offset: 8.
    33         kx   elfcpp::DW_CFA_advance_loc + 6,	// Advance 6 to __PLT__ + 6.
    33         kx   elfcpp::DW_CFA_def_cfa_offset, 12,	// DW_CFA_def_cfa_offset: 12.
    33         kx   elfcpp::DW_CFA_advance_loc + 10,	// Advance 10 to __PLT__ + 16.
    33         kx   elfcpp::DW_CFA_def_cfa_expression,	// DW_CFA_def_cfa_expression.
    33         kx   11,					// Block length.
    33         kx   elfcpp::DW_OP_breg4, 4,		// Push %esp + 4.
    33         kx   elfcpp::DW_OP_breg8, 0,		// Push %eip.
    33         kx   elfcpp::DW_OP_lit15,			// Push 0xf.
    33         kx   elfcpp::DW_OP_and,			// & (%eip & 0xf).
    33         kx   elfcpp::DW_OP_lit11,			// Push 0xb.
    33         kx   elfcpp::DW_OP_ge,			// >= ((%eip & 0xf) >= 0xb)
    33         kx   elfcpp::DW_OP_lit2,			// Push 2.
    33         kx   elfcpp::DW_OP_shl,			// << (((%eip & 0xf) >= 0xb) << 2)
    33         kx   elfcpp::DW_OP_plus,			// + ((((%eip&0xf)>=0xb)<<2)+%esp+4
    33         kx   elfcpp::DW_CFA_nop,			// Align to 32 bytes.
    33         kx   elfcpp::DW_CFA_nop,
    33         kx   elfcpp::DW_CFA_nop,
    33         kx   elfcpp::DW_CFA_nop
    33         kx };
    33         kx 
    33         kx // Write out the PLT.  This uses the hand-coded instructions above,
    33         kx // and adjusts them as needed.  This is all specified by the i386 ELF
    33         kx // Processor Supplement.
    33         kx 
    33         kx void
    33         kx Output_data_plt_i386::do_write(Output_file* of)
    33         kx {
    33         kx   const off_t offset = this->offset();
    33         kx   const section_size_type oview_size =
    33         kx     convert_to_section_size_type(this->data_size());
    33         kx   unsigned char* const oview = of->get_output_view(offset, oview_size);
    33         kx 
    33         kx   const off_t got_file_offset = this->got_plt_->offset();
    33         kx   gold_assert(parameters->incremental_update()
    33         kx 	      || (got_file_offset + this->got_plt_->data_size()
    33         kx 		  == this->got_irelative_->offset()));
    33         kx   const section_size_type got_size =
    33         kx     convert_to_section_size_type(this->got_plt_->data_size()
    33         kx 				 + this->got_irelative_->data_size());
    33         kx 
    33         kx   unsigned char* const got_view = of->get_output_view(got_file_offset,
    33         kx 						      got_size);
    33         kx 
    33         kx   unsigned char* pov = oview;
    33         kx 
    33         kx   elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address();
    33         kx   elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address();
    33         kx 
    33         kx   this->fill_first_plt_entry(pov, got_address);
    33         kx   pov += this->get_plt_entry_size();
    33         kx 
    33         kx   // The first three entries in the GOT are reserved, and are written
    33         kx   // by Output_data_got_plt_i386::do_write.
    33         kx   unsigned char* got_pov = got_view + 12;
    33         kx 
    33         kx   const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
    33         kx 
    33         kx   unsigned int plt_offset = this->get_plt_entry_size();
    33         kx   unsigned int plt_rel_offset = 0;
    33         kx   unsigned int got_offset = 12;
    33         kx   const unsigned int count = this->count_ + this->irelative_count_;
    33         kx   for (unsigned int i = 0;
    33         kx        i < count;
    33         kx        ++i,
    33         kx 	 pov += this->get_plt_entry_size(),
    33         kx 	 got_pov += 4,
    33         kx 	 plt_offset += this->get_plt_entry_size(),
    33         kx 	 plt_rel_offset += rel_size,
    33         kx 	 got_offset += 4)
    33         kx     {
    33         kx       // Set and adjust the PLT entry itself.
    33         kx       unsigned int lazy_offset = this->fill_plt_entry(pov,
    33         kx 						      got_address,
    33         kx 						      got_offset,
    33         kx 						      plt_offset,
    33         kx 						      plt_rel_offset);
    33         kx 
    33         kx       // Set the entry in the GOT.
    33         kx       elfcpp::Swap<32, false>::writeval(got_pov,
    33         kx 					plt_address + plt_offset + lazy_offset);
    33         kx     }
    33         kx 
    33         kx   // If any STT_GNU_IFUNC symbols have PLT entries, we need to change
    33         kx   // the GOT to point to the actual symbol value, rather than point to
    33         kx   // the PLT entry.  That will let the dynamic linker call the right
    33         kx   // function when resolving IRELATIVE relocations.
    33         kx   unsigned char* got_irelative_view = got_view + this->got_plt_->data_size();
    33         kx   for (std::vector<Global_ifunc>::const_iterator p =
    33         kx 	 this->global_ifuncs_.begin();
    33         kx        p != this->global_ifuncs_.end();
    33         kx        ++p)
    33         kx     {
    33         kx       const Sized_symbol<32>* ssym =
    33         kx 	static_cast<const Sized_symbol<32>*>(p->sym);
    33         kx       elfcpp::Swap<32, false>::writeval(got_irelative_view + p->got_offset,
    33         kx 					ssym->value());
    33         kx     }
    33         kx 
    33         kx   for (std::vector<Local_ifunc>::const_iterator p =
    33         kx 	 this->local_ifuncs_.begin();
    33         kx        p != this->local_ifuncs_.end();
    33         kx        ++p)
    33         kx     {
    33         kx       const Symbol_value<32>* psymval =
    33         kx 	p->object->local_symbol(p->local_sym_index);
    33         kx       elfcpp::Swap<32, false>::writeval(got_irelative_view + p->got_offset,
    33         kx 					psymval->value(p->object, 0));
    33         kx     }
    33         kx 
    33         kx   gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
    33         kx   gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
    33         kx 
    33         kx   of->write_output_view(offset, oview_size, oview);
    33         kx   of->write_output_view(got_file_offset, got_size, got_view);
    33         kx }
    33         kx 
    33         kx // Create the PLT section.
    33         kx 
    33         kx void
    33         kx Target_i386::make_plt_section(Symbol_table* symtab, Layout* layout)
    33         kx {
    33         kx   if (this->plt_ == NULL)
    33         kx     {
    33         kx       // Create the GOT sections first.
    33         kx       this->got_section(symtab, layout);
    33         kx 
    33         kx       const bool dyn = parameters->options().output_is_position_independent();
    33         kx       this->plt_ = this->make_data_plt(layout,
    33         kx 				       this->got_plt_,
    33         kx 				       this->got_irelative_,
    33         kx 				       dyn);
    33         kx 
    33         kx       // Add unwind information if requested.
    33         kx       if (parameters->options().ld_generated_unwind_info())
    33         kx 	this->plt_->add_eh_frame(layout);
    33         kx 
    33         kx       layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
    33         kx 				      (elfcpp::SHF_ALLOC
    33         kx 				       | elfcpp::SHF_EXECINSTR),
    33         kx 				      this->plt_, ORDER_PLT, false);
    33         kx 
    33         kx       // Make the sh_info field of .rel.plt point to .plt.
    33         kx       Output_section* rel_plt_os = this->plt_->rel_plt()->output_section();
    33         kx       rel_plt_os->set_info_section(this->plt_->output_section());
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Create a PLT entry for a global symbol.
    33         kx 
    33         kx void
    33         kx Target_i386::make_plt_entry(Symbol_table* symtab, Layout* layout, Symbol* gsym)
    33         kx {
    33         kx   if (gsym->has_plt_offset())
    33         kx     return;
    33         kx   if (this->plt_ == NULL)
    33         kx     this->make_plt_section(symtab, layout);
    33         kx   this->plt_->add_entry(symtab, layout, gsym);
    33         kx }
    33         kx 
    33         kx // Make a PLT entry for a local STT_GNU_IFUNC symbol.
    33         kx 
    33         kx void
    33         kx Target_i386::make_local_ifunc_plt_entry(Symbol_table* symtab, Layout* layout,
    33         kx 					Sized_relobj_file<32, false>* relobj,
    33         kx 					unsigned int local_sym_index)
    33         kx {
    33         kx   if (relobj->local_has_plt_offset(local_sym_index))
    33         kx     return;
    33         kx   if (this->plt_ == NULL)
    33         kx     this->make_plt_section(symtab, layout);
    33         kx   unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout,
    33         kx 							      relobj,
    33         kx 							      local_sym_index);
    33         kx   relobj->set_local_plt_offset(local_sym_index, plt_offset);
    33         kx }
    33         kx 
    33         kx // Return the number of entries in the PLT.
    33         kx 
    33         kx unsigned int
    33         kx Target_i386::plt_entry_count() const
    33         kx {
    33         kx   if (this->plt_ == NULL)
    33         kx     return 0;
    33         kx   return this->plt_->entry_count();
    33         kx }
    33         kx 
    33         kx // Return the offset of the first non-reserved PLT entry.
    33         kx 
    33         kx unsigned int
    33         kx Target_i386::first_plt_entry_offset() const
    33         kx {
    33         kx   if (this->plt_ == NULL)
    33         kx     return 0;
    33         kx   return this->plt_->first_plt_entry_offset();
    33         kx }
    33         kx 
    33         kx // Return the size of each PLT entry.
    33         kx 
    33         kx unsigned int
    33         kx Target_i386::plt_entry_size() const
    33         kx {
    33         kx   if (this->plt_ == NULL)
    33         kx     return 0;
    33         kx   return this->plt_->get_plt_entry_size();
    33         kx }
    33         kx 
    33         kx // Get the section to use for TLS_DESC relocations.
    33         kx 
    33         kx Target_i386::Reloc_section*
    33         kx Target_i386::rel_tls_desc_section(Layout* layout) const
    33         kx {
    33         kx   return this->plt_section()->rel_tls_desc(layout);
    33         kx }
    33         kx 
    33         kx // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
    33         kx 
    33         kx void
    33         kx Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
    33         kx {
    33         kx   if (this->tls_base_symbol_defined_)
    33         kx     return;
    33         kx 
    33         kx   Output_segment* tls_segment = layout->tls_segment();
    33         kx   if (tls_segment != NULL)
    33         kx     {
    33         kx       bool is_exec = parameters->options().output_is_executable();
    33         kx       symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
    33         kx 				       Symbol_table::PREDEFINED,
    33         kx 				       tls_segment, 0, 0,
    33         kx 				       elfcpp::STT_TLS,
    33         kx 				       elfcpp::STB_LOCAL,
    33         kx 				       elfcpp::STV_HIDDEN, 0,
    33         kx 				       (is_exec
    33         kx 					? Symbol::SEGMENT_END
    33         kx 					: Symbol::SEGMENT_START),
    33         kx 				       true);
    33         kx     }
    33         kx   this->tls_base_symbol_defined_ = true;
    33         kx }
    33         kx 
    33         kx // Create a GOT entry for the TLS module index.
    33         kx 
    33         kx unsigned int
    33         kx Target_i386::got_mod_index_entry(Symbol_table* symtab, Layout* layout,
    33         kx 				 Sized_relobj_file<32, false>* object)
    33         kx {
    33         kx   if (this->got_mod_index_offset_ == -1U)
    33         kx     {
    33         kx       gold_assert(symtab != NULL && layout != NULL && object != NULL);
    33         kx       Reloc_section* rel_dyn = this->rel_dyn_section(layout);
    33         kx       Output_data_got<32, false>* got = this->got_section(symtab, layout);
    33         kx       unsigned int got_offset = got->add_constant(0);
    33         kx       rel_dyn->add_local(object, 0, elfcpp::R_386_TLS_DTPMOD32, got,
    33         kx 			 got_offset);
    33         kx       got->add_constant(0);
    33         kx       this->got_mod_index_offset_ = got_offset;
    33         kx     }
    33         kx   return this->got_mod_index_offset_;
    33         kx }
    33         kx 
    33         kx // Optimize the TLS relocation type based on what we know about the
    33         kx // symbol.  IS_FINAL is true if the final address of this symbol is
    33         kx // known at link time.
    33         kx 
    33         kx tls::Tls_optimization
    33         kx Target_i386::optimize_tls_reloc(bool is_final, int r_type)
    33         kx {
    33         kx   // If we are generating a shared library, then we can't do anything
    33         kx   // in the linker.
    33         kx   if (parameters->options().shared())
    33         kx     return tls::TLSOPT_NONE;
    33         kx 
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_TLS_GD:
    33         kx     case elfcpp::R_386_TLS_GOTDESC:
    33         kx     case elfcpp::R_386_TLS_DESC_CALL:
    33         kx       // These are General-Dynamic which permits fully general TLS
    33         kx       // access.  Since we know that we are generating an executable,
    33         kx       // we can convert this to Initial-Exec.  If we also know that
    33         kx       // this is a local symbol, we can further switch to Local-Exec.
    33         kx       if (is_final)
    33         kx 	return tls::TLSOPT_TO_LE;
    33         kx       return tls::TLSOPT_TO_IE;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_LDM:
    33         kx       // This is Local-Dynamic, which refers to a local symbol in the
    33         kx       // dynamic TLS block.  Since we know that we generating an
    33         kx       // executable, we can switch to Local-Exec.
    33         kx       return tls::TLSOPT_TO_LE;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_LDO_32:
    33         kx       // Another type of Local-Dynamic relocation.
    33         kx       return tls::TLSOPT_TO_LE;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_IE:
    33         kx     case elfcpp::R_386_TLS_GOTIE:
    33         kx     case elfcpp::R_386_TLS_IE_32:
    33         kx       // These are Initial-Exec relocs which get the thread offset
    33         kx       // from the GOT.  If we know that we are linking against the
    33         kx       // local symbol, we can switch to Local-Exec, which links the
    33         kx       // thread offset into the instruction.
    33         kx       if (is_final)
    33         kx 	return tls::TLSOPT_TO_LE;
    33         kx       return tls::TLSOPT_NONE;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_LE:
    33         kx     case elfcpp::R_386_TLS_LE_32:
    33         kx       // When we already have Local-Exec, there is nothing further we
    33         kx       // can do.
    33         kx       return tls::TLSOPT_NONE;
    33         kx 
    33         kx     default:
    33         kx       gold_unreachable();
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Get the Reference_flags for a particular relocation.
    33         kx 
    33         kx int
    33         kx Target_i386::Scan::get_reference_flags(unsigned int r_type)
    33         kx {
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_NONE:
    33         kx     case elfcpp::R_386_GNU_VTINHERIT:
    33         kx     case elfcpp::R_386_GNU_VTENTRY:
    33         kx     case elfcpp::R_386_GOTPC:
    33         kx       // No symbol reference.
    33         kx       return 0;
    33         kx 
    33         kx     case elfcpp::R_386_32:
    33         kx     case elfcpp::R_386_16:
    33         kx     case elfcpp::R_386_8:
    33         kx       return Symbol::ABSOLUTE_REF;
    33         kx 
    33         kx     case elfcpp::R_386_PC32:
    33         kx     case elfcpp::R_386_PC16:
    33         kx     case elfcpp::R_386_PC8:
    33         kx     case elfcpp::R_386_GOTOFF:
    33         kx       return Symbol::RELATIVE_REF;
    33         kx 
    33         kx     case elfcpp::R_386_PLT32:
    33         kx       return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
    33         kx 
    33         kx     case elfcpp::R_386_GOT32:
    33         kx     case elfcpp::R_386_GOT32X:
    33         kx       // Absolute in GOT.
    33         kx       return Symbol::ABSOLUTE_REF;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_GD:            // Global-dynamic
    33         kx     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    33         kx     case elfcpp::R_386_TLS_DESC_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    33         kx     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    33         kx     case elfcpp::R_386_TLS_IE:            // Initial-exec
    33         kx     case elfcpp::R_386_TLS_IE_32:
    33         kx     case elfcpp::R_386_TLS_GOTIE:
    33         kx     case elfcpp::R_386_TLS_LE:            // Local-exec
    33         kx     case elfcpp::R_386_TLS_LE_32:
    33         kx       return Symbol::TLS_REF;
    33         kx 
    33         kx     case elfcpp::R_386_COPY:
    33         kx     case elfcpp::R_386_GLOB_DAT:
    33         kx     case elfcpp::R_386_JUMP_SLOT:
    33         kx     case elfcpp::R_386_RELATIVE:
    33         kx     case elfcpp::R_386_IRELATIVE:
    33         kx     case elfcpp::R_386_TLS_TPOFF:
    33         kx     case elfcpp::R_386_TLS_DTPMOD32:
    33         kx     case elfcpp::R_386_TLS_DTPOFF32:
    33         kx     case elfcpp::R_386_TLS_TPOFF32:
    33         kx     case elfcpp::R_386_TLS_DESC:
    33         kx     case elfcpp::R_386_32PLT:
    33         kx     case elfcpp::R_386_TLS_GD_32:
    33         kx     case elfcpp::R_386_TLS_GD_PUSH:
    33         kx     case elfcpp::R_386_TLS_GD_CALL:
    33         kx     case elfcpp::R_386_TLS_GD_POP:
    33         kx     case elfcpp::R_386_TLS_LDM_32:
    33         kx     case elfcpp::R_386_TLS_LDM_PUSH:
    33         kx     case elfcpp::R_386_TLS_LDM_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM_POP:
    33         kx     case elfcpp::R_386_USED_BY_INTEL_200:
    33         kx     default:
    33         kx       // Not expected.  We will give an error later.
    33         kx       return 0;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Report an unsupported relocation against a local symbol.
    33         kx 
    33         kx void
    33         kx Target_i386::Scan::unsupported_reloc_local(Sized_relobj_file<32, false>* object,
    33         kx 					   unsigned int r_type)
    33         kx {
    33         kx   gold_error(_("%s: unsupported reloc %u against local symbol"),
    33         kx 	     object->name().c_str(), r_type);
    33         kx }
    33         kx 
    33         kx // Return whether we need to make a PLT entry for a relocation of a
    33         kx // given type against a STT_GNU_IFUNC symbol.
    33         kx 
    33         kx bool
    33         kx Target_i386::Scan::reloc_needs_plt_for_ifunc(
    33         kx     Sized_relobj_file<32, false>* object,
    33         kx     unsigned int r_type)
    33         kx {
    33         kx   int flags = Scan::get_reference_flags(r_type);
    33         kx   if (flags & Symbol::TLS_REF)
    33         kx     gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
    33         kx 	       object->name().c_str(), r_type);
    33         kx   return flags != 0;
    33         kx }
    33         kx 
    33         kx // Scan a relocation for a local symbol.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Scan::local(Symbol_table* symtab,
    33         kx 			 Layout* layout,
    33         kx 			 Target_i386* target,
    33         kx 			 Sized_relobj_file<32, false>* object,
    33         kx 			 unsigned int data_shndx,
    33         kx 			 Output_section* output_section,
    33         kx 			 const elfcpp::Rel<32, false>& reloc,
    33         kx 			 unsigned int r_type,
    33         kx 			 const elfcpp::Sym<32, false>& lsym,
    33         kx 			 bool is_discarded)
    33         kx {
    33         kx   if (is_discarded)
    33         kx     return;
    33         kx 
    33         kx   // A local STT_GNU_IFUNC symbol may require a PLT entry.
    33         kx   if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC
    33         kx       && this->reloc_needs_plt_for_ifunc(object, r_type))
    33         kx     {
    33         kx       unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx       target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
    33         kx     }
    33         kx 
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_NONE:
    33         kx     case elfcpp::R_386_GNU_VTINHERIT:
    33         kx     case elfcpp::R_386_GNU_VTENTRY:
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_32:
    33         kx       // If building a shared library (or a position-independent
    33         kx       // executable), we need to create a dynamic relocation for
    33         kx       // this location. The relocation applied at link time will
    33         kx       // apply the link-time value, so we flag the location with
    33         kx       // an R_386_RELATIVE relocation so the dynamic loader can
    33         kx       // relocate it easily.
    33         kx       if (parameters->options().output_is_position_independent())
    33         kx 	{
    33         kx 	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 	  rel_dyn->add_local_relative(object, r_sym, elfcpp::R_386_RELATIVE,
    33         kx 				      output_section, data_shndx,
    33         kx 				      reloc.get_r_offset());
    33         kx 	}
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_16:
    33         kx     case elfcpp::R_386_8:
    33         kx       // If building a shared library (or a position-independent
    33         kx       // executable), we need to create a dynamic relocation for
    33         kx       // this location. Because the addend needs to remain in the
    33         kx       // data section, we need to be careful not to apply this
    33         kx       // relocation statically.
    33         kx       if (parameters->options().output_is_position_independent())
    33         kx 	{
    33         kx 	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 	  if (lsym.get_st_type() != elfcpp::STT_SECTION)
    33         kx 	    rel_dyn->add_local(object, r_sym, r_type, output_section,
    33         kx 			       data_shndx, reloc.get_r_offset());
    33         kx 	  else
    33         kx 	    {
    33         kx 	      gold_assert(lsym.get_st_value() == 0);
    33         kx 	      unsigned int shndx = lsym.get_st_shndx();
    33         kx 	      bool is_ordinary;
    33         kx 	      shndx = object->adjust_sym_shndx(r_sym, shndx,
    33         kx 					       &is_ordinary);
    33         kx 	      if (!is_ordinary)
    33         kx 		object->error(_("section symbol %u has bad shndx %u"),
    33         kx 			      r_sym, shndx);
    33         kx 	      else
    33         kx 		rel_dyn->add_local_section(object, shndx,
    33         kx 					   r_type, output_section,
    33         kx 					   data_shndx, reloc.get_r_offset());
    33         kx 	    }
    33         kx 	}
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PC32:
    33         kx     case elfcpp::R_386_PC16:
    33         kx     case elfcpp::R_386_PC8:
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PLT32:
    33         kx       // Since we know this is a local symbol, we can handle this as a
    33         kx       // PC32 reloc.
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOTOFF:
    33         kx     case elfcpp::R_386_GOTPC:
    33         kx       // We need a GOT section.
    33         kx       target->got_section(symtab, layout);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOT32:
    33         kx     case elfcpp::R_386_GOT32X:
    33         kx       {
    33         kx 	// We need GOT section.
    33         kx 	Output_data_got<32, false>* got = target->got_section(symtab, layout);
    33         kx 
    33         kx 	// If the relocation symbol isn't IFUNC,
    33         kx 	// and is local, then we will convert
    33         kx 	// mov foo@GOT(%reg), %reg
    33         kx 	// to
    33         kx 	// lea foo@GOTOFF(%reg), %reg
    33         kx 	// in Relocate::relocate.
    33         kx 	if (reloc.get_r_offset() >= 2
    33         kx 	    && lsym.get_st_type() != elfcpp::STT_GNU_IFUNC)
    33         kx 	  {
    33         kx 	    section_size_type stype;
    33         kx 	    const unsigned char* view = object->section_contents(data_shndx,
    33         kx 								 &stype, true);
    33         kx 	    if (view[reloc.get_r_offset() - 2] == 0x8b)
    33         kx 	      break;
    33         kx 	  }
    33         kx 
    33         kx 	// Otherwise, the symbol requires a GOT entry.
    33         kx 	unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 
    33         kx 	// For a STT_GNU_IFUNC symbol we want the PLT offset.  That
    33         kx 	// lets function pointers compare correctly with shared
    33         kx 	// libraries.  Otherwise we would need an IRELATIVE reloc.
    33         kx 	bool is_new;
    33         kx 	if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC)
    33         kx 	  is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
    33         kx 	else
    33         kx 	  is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
    33         kx 	if (is_new)
    33         kx 	  {
    33         kx 	    // If we are generating a shared object, we need to add a
    33         kx 	    // dynamic RELATIVE relocation for this symbol's GOT entry.
    33         kx 	    if (parameters->options().output_is_position_independent())
    33         kx 	      {
    33         kx 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		unsigned int got_offset =
    33         kx 		  object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
    33         kx 		rel_dyn->add_local_relative(object, r_sym,
    33         kx 					    elfcpp::R_386_RELATIVE,
    33         kx 					    got, got_offset);
    33         kx 	      }
    33         kx 	  }
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx       // These are relocations which should only be seen by the
    33         kx       // dynamic linker, and should never be seen here.
    33         kx     case elfcpp::R_386_COPY:
    33         kx     case elfcpp::R_386_GLOB_DAT:
    33         kx     case elfcpp::R_386_JUMP_SLOT:
    33         kx     case elfcpp::R_386_RELATIVE:
    33         kx     case elfcpp::R_386_IRELATIVE:
    33         kx     case elfcpp::R_386_TLS_TPOFF:
    33         kx     case elfcpp::R_386_TLS_DTPMOD32:
    33         kx     case elfcpp::R_386_TLS_DTPOFF32:
    33         kx     case elfcpp::R_386_TLS_TPOFF32:
    33         kx     case elfcpp::R_386_TLS_DESC:
    33         kx       gold_error(_("%s: unexpected reloc %u in object file"),
    33         kx 		 object->name().c_str(), r_type);
    33         kx       break;
    33         kx 
    33         kx       // These are initial TLS relocs, which are expected when
    33         kx       // linking.
    33         kx     case elfcpp::R_386_TLS_GD:            // Global-dynamic
    33         kx     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    33         kx     case elfcpp::R_386_TLS_DESC_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    33         kx     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    33         kx     case elfcpp::R_386_TLS_IE:            // Initial-exec
    33         kx     case elfcpp::R_386_TLS_IE_32:
    33         kx     case elfcpp::R_386_TLS_GOTIE:
    33         kx     case elfcpp::R_386_TLS_LE:            // Local-exec
    33         kx     case elfcpp::R_386_TLS_LE_32:
    33         kx       {
    33         kx 	bool output_is_shared = parameters->options().shared();
    33         kx 	const tls::Tls_optimization optimized_type
    33         kx 	    = Target_i386::optimize_tls_reloc(!output_is_shared, r_type);
    33         kx 	switch (r_type)
    33         kx 	  {
    33         kx 	  case elfcpp::R_386_TLS_GD:          // Global-dynamic
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// Create a pair of GOT entries for the module index and
    33         kx 		// dtv-relative offset.
    33         kx 		Output_data_got<32, false>* got
    33         kx 		    = target->got_section(symtab, layout);
    33         kx 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 		unsigned int shndx = lsym.get_st_shndx();
    33         kx 		bool is_ordinary;
    33         kx 		shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
    33         kx 		if (!is_ordinary)
    33         kx 		  object->error(_("local symbol %u has bad shndx %u"),
    33         kx 			      r_sym, shndx);
    33         kx 		else
    33         kx 		  got->add_local_pair_with_rel(object, r_sym, shndx,
    33         kx 					       GOT_TYPE_TLS_PAIR,
    33         kx 					       target->rel_dyn_section(layout),
    33         kx 					       elfcpp::R_386_TLS_DTPMOD32);
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_local(object, r_type);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_GOTDESC:     // Global-dynamic (from ~oliva)
    33         kx 	    target->define_tls_base_symbol(symtab, layout);
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// Create a double GOT entry with an R_386_TLS_DESC
    33         kx 		// reloc.  The R_386_TLS_DESC reloc is resolved
    33         kx 		// lazily, so the GOT entry needs to be in an area in
    33         kx 		// .got.plt, not .got.  Call got_section to make sure
    33         kx 		// the section has been created.
    33         kx 		target->got_section(symtab, layout);
    33         kx 		Output_data_got<32, false>* got = target->got_tlsdesc_section();
    33         kx 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 		if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC))
    33         kx 		  {
    33         kx 		    unsigned int got_offset = got->add_constant(0);
    33         kx 		    // The local symbol value is stored in the second
    33         kx 		    // GOT entry.
    33         kx 		    got->add_local(object, r_sym, GOT_TYPE_TLS_DESC);
    33         kx 		    // That set the GOT offset of the local symbol to
    33         kx 		    // point to the second entry, but we want it to
    33         kx 		    // point to the first.
    33         kx 		    object->set_local_got_offset(r_sym, GOT_TYPE_TLS_DESC,
    33         kx 						 got_offset);
    33         kx 		    Reloc_section* rt = target->rel_tls_desc_section(layout);
    33         kx 		    rt->add_absolute(elfcpp::R_386_TLS_DESC, got, got_offset);
    33         kx 		  }
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_local(object, r_type);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_DESC_CALL:
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_LDM:         // Local-dynamic
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// Create a GOT entry for the module index.
    33         kx 		target->got_mod_index_entry(symtab, layout, object);
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_local(object, r_type);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_LDO_32:      // Alternate local-dynamic
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_IE:          // Initial-exec
    33         kx 	  case elfcpp::R_386_TLS_IE_32:
    33         kx 	  case elfcpp::R_386_TLS_GOTIE:
    33         kx 	    layout->set_has_static_tls();
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// For the R_386_TLS_IE relocation, we need to create a
    33         kx 		// dynamic relocation when building a shared library.
    33         kx 		if (r_type == elfcpp::R_386_TLS_IE
    33         kx 		    && parameters->options().shared())
    33         kx 		  {
    33         kx 		    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		    unsigned int r_sym
    33         kx 			= elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 		    rel_dyn->add_local_relative(object, r_sym,
    33         kx 						elfcpp::R_386_RELATIVE,
    33         kx 						output_section, data_shndx,
    33         kx 						reloc.get_r_offset());
    33         kx 		  }
    33         kx 		// Create a GOT entry for the tp-relative offset.
    33         kx 		Output_data_got<32, false>* got
    33         kx 		    = target->got_section(symtab, layout);
    33         kx 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
    33         kx 					   ? elfcpp::R_386_TLS_TPOFF32
    33         kx 					   : elfcpp::R_386_TLS_TPOFF);
    33         kx 		unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
    33         kx 					 ? GOT_TYPE_TLS_OFFSET
    33         kx 					 : GOT_TYPE_TLS_NOFFSET);
    33         kx 		got->add_local_with_rel(object, r_sym, got_type,
    33         kx 					target->rel_dyn_section(layout),
    33         kx 					dyn_r_type);
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_local(object, r_type);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_LE:          // Local-exec
    33         kx 	  case elfcpp::R_386_TLS_LE_32:
    33         kx 	    layout->set_has_static_tls();
    33         kx 	    if (output_is_shared)
    33         kx 	      {
    33         kx 		// We need to create a dynamic relocation.
    33         kx 		gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
    33         kx 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
    33         kx 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_LE_32
    33         kx 					   ? elfcpp::R_386_TLS_TPOFF32
    33         kx 					   : elfcpp::R_386_TLS_TPOFF);
    33         kx 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		rel_dyn->add_local(object, r_sym, dyn_r_type, output_section,
    33         kx 				   data_shndx, reloc.get_r_offset());
    33         kx 	      }
    33         kx 	    break;
    33         kx 
    33         kx 	  default:
    33         kx 	    gold_unreachable();
    33         kx 	  }
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_32PLT:
    33         kx     case elfcpp::R_386_TLS_GD_32:
    33         kx     case elfcpp::R_386_TLS_GD_PUSH:
    33         kx     case elfcpp::R_386_TLS_GD_CALL:
    33         kx     case elfcpp::R_386_TLS_GD_POP:
    33         kx     case elfcpp::R_386_TLS_LDM_32:
    33         kx     case elfcpp::R_386_TLS_LDM_PUSH:
    33         kx     case elfcpp::R_386_TLS_LDM_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM_POP:
    33         kx     case elfcpp::R_386_USED_BY_INTEL_200:
    33         kx     default:
    33         kx       unsupported_reloc_local(object, r_type);
    33         kx       break;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Report an unsupported relocation against a global symbol.
    33         kx 
    33         kx void
    33         kx Target_i386::Scan::unsupported_reloc_global(
    33         kx     Sized_relobj_file<32, false>* object,
    33         kx     unsigned int r_type,
    33         kx     Symbol* gsym)
    33         kx {
    33         kx   gold_error(_("%s: unsupported reloc %u against global symbol %s"),
    33         kx 	     object->name().c_str(), r_type, gsym->demangled_name().c_str());
    33         kx }
    33         kx 
    33         kx inline bool
    33         kx Target_i386::Scan::possible_function_pointer_reloc(unsigned int r_type)
    33         kx {
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_32:
    33         kx     case elfcpp::R_386_16:
    33         kx     case elfcpp::R_386_8:
    33         kx     case elfcpp::R_386_GOTOFF:
    33         kx     case elfcpp::R_386_GOT32:
    33         kx     case elfcpp::R_386_GOT32X:
    33         kx       {
    33         kx 	return true;
    33         kx       }
    33         kx     default:
    33         kx       return false;
    33         kx     }
    33         kx   return false;
    33         kx }
    33         kx 
    33         kx inline bool
    33         kx Target_i386::Scan::local_reloc_may_be_function_pointer(
    33         kx   Symbol_table* ,
    33         kx   Layout* ,
    33         kx   Target_i386* ,
    33         kx   Sized_relobj_file<32, false>* ,
    33         kx   unsigned int ,
    33         kx   Output_section* ,
    33         kx   const elfcpp::Rel<32, false>& ,
    33         kx   unsigned int r_type,
    33         kx   const elfcpp::Sym<32, false>&)
    33         kx {
    33         kx   return possible_function_pointer_reloc(r_type);
    33         kx }
    33         kx 
    33         kx inline bool
    33         kx Target_i386::Scan::global_reloc_may_be_function_pointer(
    33         kx   Symbol_table* ,
    33         kx   Layout* ,
    33         kx   Target_i386* ,
    33         kx   Sized_relobj_file<32, false>* ,
    33         kx   unsigned int ,
    33         kx   Output_section* ,
    33         kx   const elfcpp::Rel<32, false>& ,
    33         kx   unsigned int r_type,
    33         kx   Symbol*)
    33         kx {
    33         kx   return possible_function_pointer_reloc(r_type);
    33         kx }
    33         kx 
    33         kx // Scan a relocation for a global symbol.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Scan::global(Symbol_table* symtab,
    33         kx 				 Layout* layout,
    33         kx 				 Target_i386* target,
    33         kx 				 Sized_relobj_file<32, false>* object,
    33         kx 				 unsigned int data_shndx,
    33         kx 				 Output_section* output_section,
    33         kx 				 const elfcpp::Rel<32, false>& reloc,
    33         kx 				 unsigned int r_type,
    33         kx 				 Symbol* gsym)
    33         kx {
    33         kx   // A STT_GNU_IFUNC symbol may require a PLT entry.
    33         kx   if (gsym->type() == elfcpp::STT_GNU_IFUNC
    33         kx       && this->reloc_needs_plt_for_ifunc(object, r_type))
    33         kx     target->make_plt_entry(symtab, layout, gsym);
    33         kx 
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_NONE:
    33         kx     case elfcpp::R_386_GNU_VTINHERIT:
    33         kx     case elfcpp::R_386_GNU_VTENTRY:
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_32:
    33         kx     case elfcpp::R_386_16:
    33         kx     case elfcpp::R_386_8:
    33         kx       {
    33         kx 	// Make a PLT entry if necessary.
    33         kx 	if (gsym->needs_plt_entry())
    33         kx 	  {
    33         kx 	    target->make_plt_entry(symtab, layout, gsym);
    33         kx 	    // Since this is not a PC-relative relocation, we may be
    33         kx 	    // taking the address of a function. In that case we need to
    33         kx 	    // set the entry in the dynamic symbol table to the address of
    33         kx 	    // the PLT entry.
    33         kx 	    if (gsym->is_from_dynobj() && !parameters->options().shared())
    33         kx 	      gsym->set_needs_dynsym_value();
    33         kx 	  }
    33         kx 	// Make a dynamic relocation if necessary.
    33         kx 	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
    33         kx 	  {
    33         kx 	    if (!parameters->options().output_is_position_independent()
    33         kx 		&& gsym->may_need_copy_reloc())
    33         kx 	      {
    33         kx 		target->copy_reloc(symtab, layout, object,
    33         kx 				   data_shndx, output_section, gsym, reloc);
    33         kx 	      }
    33         kx 	    else if (r_type == elfcpp::R_386_32
    33         kx 		     && gsym->type() == elfcpp::STT_GNU_IFUNC
    33         kx 		     && gsym->can_use_relative_reloc(false)
    33         kx 		     && !gsym->is_from_dynobj()
    33         kx 		     && !gsym->is_undefined()
    33         kx 		     && !gsym->is_preemptible())
    33         kx 	      {
    33         kx 		// Use an IRELATIVE reloc for a locally defined
    33         kx 		// STT_GNU_IFUNC symbol.  This makes a function
    33         kx 		// address in a PIE executable match the address in a
    33         kx 		// shared library that it links against.
    33         kx 		Reloc_section* rel_dyn = target->rel_irelative_section(layout);
    33         kx 		rel_dyn->add_symbolless_global_addend(gsym,
    33         kx 						      elfcpp::R_386_IRELATIVE,
    33         kx 						      output_section,
    33         kx 						      object, data_shndx,
    33         kx 						      reloc.get_r_offset());
    33         kx 	      }
    33         kx 	    else if (r_type == elfcpp::R_386_32
    33         kx 		     && gsym->can_use_relative_reloc(false))
    33         kx 	      {
    33         kx 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
    33         kx 					     output_section, object,
    33         kx 					     data_shndx, reloc.get_r_offset());
    33         kx 	      }
    33         kx 	    else
    33         kx 	      {
    33         kx 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		rel_dyn->add_global(gsym, r_type, output_section, object,
    33         kx 				    data_shndx, reloc.get_r_offset());
    33         kx 	      }
    33         kx 	  }
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PC32:
    33         kx     case elfcpp::R_386_PC16:
    33         kx     case elfcpp::R_386_PC8:
    33         kx       {
    33         kx 	// Make a PLT entry if necessary.
    33         kx 	if (gsym->needs_plt_entry())
    33         kx 	  {
    33         kx 	    // These relocations are used for function calls only in
    33         kx 	    // non-PIC code.  For a 32-bit relocation in a shared library,
    33         kx 	    // we'll need a text relocation anyway, so we can skip the
    33         kx 	    // PLT entry and let the dynamic linker bind the call directly
    33         kx 	    // to the target.  For smaller relocations, we should use a
    33         kx 	    // PLT entry to ensure that the call can reach.
    33         kx 	    if (!parameters->options().shared()
    33         kx 		|| r_type != elfcpp::R_386_PC32)
    33         kx 	      target->make_plt_entry(symtab, layout, gsym);
    33         kx 	  }
    33         kx 	// Make a dynamic relocation if necessary.
    33         kx 	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
    33         kx 	  {
    33         kx 	    if (parameters->options().output_is_executable()
    33         kx 		&& gsym->may_need_copy_reloc())
    33         kx 	      {
    33         kx 		target->copy_reloc(symtab, layout, object,
    33         kx 				   data_shndx, output_section, gsym, reloc);
    33         kx 	      }
    33         kx 	    else
    33         kx 	      {
    33         kx 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		rel_dyn->add_global(gsym, r_type, output_section, object,
    33         kx 				    data_shndx, reloc.get_r_offset());
    33         kx 	      }
    33         kx 	  }
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOT32:
    33         kx     case elfcpp::R_386_GOT32X:
    33         kx       {
    33         kx 	// The symbol requires a GOT section.
    33         kx 	Output_data_got<32, false>* got = target->got_section(symtab, layout);
    33         kx 
    33         kx 	// If we convert this from
    33         kx 	// mov foo@GOT(%reg), %reg
    33         kx 	// to
    33         kx 	// lea foo@GOTOFF(%reg), %reg
    33         kx 	// in Relocate::relocate, then there is nothing to do here.
    33         kx 	if (reloc.get_r_offset() >= 2
    33         kx 	    && Target_i386::can_convert_mov_to_lea(gsym))
    33         kx 	  {
    33         kx 	    section_size_type stype;
    33         kx 	    const unsigned char* view = object->section_contents(data_shndx,
    33         kx 								 &stype, true);
    33         kx 	    if (view[reloc.get_r_offset() - 2] == 0x8b)
    33         kx 	      break;
    33         kx 	  }
    33         kx 
    33         kx 	if (gsym->final_value_is_known())
    33         kx 	  {
    33         kx 	    // For a STT_GNU_IFUNC symbol we want the PLT address.
    33         kx 	    if (gsym->type() == elfcpp::STT_GNU_IFUNC)
    33         kx 	      got->add_global_plt(gsym, GOT_TYPE_STANDARD);
    33         kx 	    else
    33         kx 	      got->add_global(gsym, GOT_TYPE_STANDARD);
    33         kx 	  }
    33         kx 	else
    33         kx 	  {
    33         kx 	    // If this symbol is not fully resolved, we need to add a
    33         kx 	    // GOT entry with a dynamic relocation.
    33         kx 	    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 
    33         kx 	    // Use a GLOB_DAT rather than a RELATIVE reloc if:
    33         kx 	    //
    33         kx 	    // 1) The symbol may be defined in some other module.
    33         kx 	    //
    33         kx 	    // 2) We are building a shared library and this is a
    33         kx 	    // protected symbol; using GLOB_DAT means that the dynamic
    33         kx 	    // linker can use the address of the PLT in the main
    33         kx 	    // executable when appropriate so that function address
    33         kx 	    // comparisons work.
    33         kx 	    //
    33         kx 	    // 3) This is a STT_GNU_IFUNC symbol in position dependent
    33         kx 	    // code, again so that function address comparisons work.
    33         kx 	    if (gsym->is_from_dynobj()
    33         kx 		|| gsym->is_undefined()
    33         kx 		|| gsym->is_preemptible()
    33         kx 		|| (gsym->visibility() == elfcpp::STV_PROTECTED
    33         kx 		    && parameters->options().shared())
    33         kx 		|| (gsym->type() == elfcpp::STT_GNU_IFUNC
    33         kx 		    && parameters->options().output_is_position_independent()))
    33         kx 	      got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
    33         kx 				       rel_dyn, elfcpp::R_386_GLOB_DAT);
    33         kx 	    else
    33         kx 	      {
    33         kx 		// For a STT_GNU_IFUNC symbol we want to write the PLT
    33         kx 		// offset into the GOT, so that function pointer
    33         kx 		// comparisons work correctly.
    33         kx 		bool is_new;
    33         kx 		if (gsym->type() != elfcpp::STT_GNU_IFUNC)
    33         kx 		  is_new = got->add_global(gsym, GOT_TYPE_STANDARD);
    33         kx 		else
    33         kx 		  {
    33         kx 		    is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD);
    33         kx 		    // Tell the dynamic linker to use the PLT address
    33         kx 		    // when resolving relocations.
    33         kx 		    if (gsym->is_from_dynobj()
    33         kx 			&& !parameters->options().shared())
    33         kx 		      gsym->set_needs_dynsym_value();
    33         kx 		  }
    33         kx 		if (is_new)
    33         kx 		  {
    33         kx 		    unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
    33         kx 		    rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
    33         kx 						 got, got_off);
    33         kx 		  }
    33         kx 	      }
    33         kx 	  }
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PLT32:
    33         kx       // If the symbol is fully resolved, this is just a PC32 reloc.
    33         kx       // Otherwise we need a PLT entry.
    33         kx       if (gsym->final_value_is_known())
    33         kx 	break;
    33         kx       // If building a shared library, we can also skip the PLT entry
    33         kx       // if the symbol is defined in the output file and is protected
    33         kx       // or hidden.
    33         kx       if (gsym->is_defined()
    33         kx 	  && !gsym->is_from_dynobj()
    33         kx 	  && !gsym->is_preemptible())
    33         kx 	break;
    33         kx       target->make_plt_entry(symtab, layout, gsym);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOTOFF:
    33         kx       // A GOT-relative reference must resolve locally.
    33         kx       if (!gsym->is_defined())
    33         kx         gold_error(_("%s: relocation R_386_GOTOFF against undefined symbol %s"
    33         kx 		     " cannot be used when making a shared object"),
    33         kx 		   object->name().c_str(), gsym->name());
    33         kx       else if (gsym->is_from_dynobj())
    33         kx         gold_error(_("%s: relocation R_386_GOTOFF against external symbol %s"
    33         kx 		     " cannot be used when making a shared object"),
    33         kx 		   object->name().c_str(), gsym->name());
    33         kx       else if (gsym->is_preemptible())
    33         kx         gold_error(_("%s: relocation R_386_GOTOFF against preemptible symbol %s"
    33         kx 		     " cannot be used when making a shared object"),
    33         kx 		   object->name().c_str(), gsym->name());
    33         kx       // We need a GOT section.
    33         kx       target->got_section(symtab, layout);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOTPC:
    33         kx       // We need a GOT section.
    33         kx       target->got_section(symtab, layout);
    33         kx       break;
    33         kx 
    33         kx       // These are relocations which should only be seen by the
    33         kx       // dynamic linker, and should never be seen here.
    33         kx     case elfcpp::R_386_COPY:
    33         kx     case elfcpp::R_386_GLOB_DAT:
    33         kx     case elfcpp::R_386_JUMP_SLOT:
    33         kx     case elfcpp::R_386_RELATIVE:
    33         kx     case elfcpp::R_386_IRELATIVE:
    33         kx     case elfcpp::R_386_TLS_TPOFF:
    33         kx     case elfcpp::R_386_TLS_DTPMOD32:
    33         kx     case elfcpp::R_386_TLS_DTPOFF32:
    33         kx     case elfcpp::R_386_TLS_TPOFF32:
    33         kx     case elfcpp::R_386_TLS_DESC:
    33         kx       gold_error(_("%s: unexpected reloc %u in object file"),
    33         kx 		 object->name().c_str(), r_type);
    33         kx       break;
    33         kx 
    33         kx       // These are initial tls relocs, which are expected when
    33         kx       // linking.
    33         kx     case elfcpp::R_386_TLS_GD:            // Global-dynamic
    33         kx     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    33         kx     case elfcpp::R_386_TLS_DESC_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    33         kx     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    33         kx     case elfcpp::R_386_TLS_IE:            // Initial-exec
    33         kx     case elfcpp::R_386_TLS_IE_32:
    33         kx     case elfcpp::R_386_TLS_GOTIE:
    33         kx     case elfcpp::R_386_TLS_LE:            // Local-exec
    33         kx     case elfcpp::R_386_TLS_LE_32:
    33         kx       {
    33         kx 	const bool is_final = gsym->final_value_is_known();
    33         kx 	const tls::Tls_optimization optimized_type
    33         kx 	    = Target_i386::optimize_tls_reloc(is_final, r_type);
    33         kx 	switch (r_type)
    33         kx 	  {
    33         kx 	  case elfcpp::R_386_TLS_GD:          // Global-dynamic
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// Create a pair of GOT entries for the module index and
    33         kx 		// dtv-relative offset.
    33         kx 		Output_data_got<32, false>* got
    33         kx 		    = target->got_section(symtab, layout);
    33         kx 		got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
    33         kx 					     target->rel_dyn_section(layout),
    33         kx 					     elfcpp::R_386_TLS_DTPMOD32,
    33         kx 					     elfcpp::R_386_TLS_DTPOFF32);
    33         kx 	      }
    33         kx 	    else if (optimized_type == tls::TLSOPT_TO_IE)
    33         kx 	      {
    33         kx 		// Create a GOT entry for the tp-relative offset.
    33         kx 		Output_data_got<32, false>* got
    33         kx 		    = target->got_section(symtab, layout);
    33         kx 		got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
    33         kx 					 target->rel_dyn_section(layout),
    33         kx 					 elfcpp::R_386_TLS_TPOFF);
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_global(object, r_type, gsym);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_GOTDESC:     // Global-dynamic (~oliva url)
    33         kx 	    target->define_tls_base_symbol(symtab, layout);
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// Create a double GOT entry with an R_386_TLS_DESC
    33         kx 		// reloc.  The R_386_TLS_DESC reloc is resolved
    33         kx 		// lazily, so the GOT entry needs to be in an area in
    33         kx 		// .got.plt, not .got.  Call got_section to make sure
    33         kx 		// the section has been created.
    33         kx 		target->got_section(symtab, layout);
    33         kx 		Output_data_got<32, false>* got = target->got_tlsdesc_section();
    33         kx 		Reloc_section* rt = target->rel_tls_desc_section(layout);
    33         kx 		got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt,
    33         kx 					     elfcpp::R_386_TLS_DESC, 0);
    33         kx 	      }
    33         kx 	    else if (optimized_type == tls::TLSOPT_TO_IE)
    33         kx 	      {
    33         kx 		// Create a GOT entry for the tp-relative offset.
    33         kx 		Output_data_got<32, false>* got
    33         kx 		    = target->got_section(symtab, layout);
    33         kx 		got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
    33         kx 					 target->rel_dyn_section(layout),
    33         kx 					 elfcpp::R_386_TLS_TPOFF);
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_global(object, r_type, gsym);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_DESC_CALL:
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_LDM:         // Local-dynamic
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// Create a GOT entry for the module index.
    33         kx 		target->got_mod_index_entry(symtab, layout, object);
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_global(object, r_type, gsym);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_LDO_32:      // Alternate local-dynamic
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_IE:          // Initial-exec
    33         kx 	  case elfcpp::R_386_TLS_IE_32:
    33         kx 	  case elfcpp::R_386_TLS_GOTIE:
    33         kx 	    layout->set_has_static_tls();
    33         kx 	    if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	      {
    33         kx 		// For the R_386_TLS_IE relocation, we need to create a
    33         kx 		// dynamic relocation when building a shared library.
    33         kx 		if (r_type == elfcpp::R_386_TLS_IE
    33         kx 		    && parameters->options().shared())
    33         kx 		  {
    33         kx 		    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		    rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
    33         kx 						 output_section, object,
    33         kx 						 data_shndx,
    33         kx 						 reloc.get_r_offset());
    33         kx 		  }
    33         kx 		// Create a GOT entry for the tp-relative offset.
    33         kx 		Output_data_got<32, false>* got
    33         kx 		    = target->got_section(symtab, layout);
    33         kx 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
    33         kx 					   ? elfcpp::R_386_TLS_TPOFF32
    33         kx 					   : elfcpp::R_386_TLS_TPOFF);
    33         kx 		unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
    33         kx 					 ? GOT_TYPE_TLS_OFFSET
    33         kx 					 : GOT_TYPE_TLS_NOFFSET);
    33         kx 		got->add_global_with_rel(gsym, got_type,
    33         kx 					 target->rel_dyn_section(layout),
    33         kx 					 dyn_r_type);
    33         kx 	      }
    33         kx 	    else if (optimized_type != tls::TLSOPT_TO_LE)
    33         kx 	      unsupported_reloc_global(object, r_type, gsym);
    33         kx 	    break;
    33         kx 
    33         kx 	  case elfcpp::R_386_TLS_LE:          // Local-exec
    33         kx 	  case elfcpp::R_386_TLS_LE_32:
    33         kx 	    layout->set_has_static_tls();
    33         kx 	    if (parameters->options().shared())
    33         kx 	      {
    33         kx 		// We need to create a dynamic relocation.
    33         kx 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_LE_32
    33         kx 					   ? elfcpp::R_386_TLS_TPOFF32
    33         kx 					   : elfcpp::R_386_TLS_TPOFF);
    33         kx 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
    33         kx 		rel_dyn->add_global(gsym, dyn_r_type, output_section, object,
    33         kx 				    data_shndx, reloc.get_r_offset());
    33         kx 	      }
    33         kx 	    break;
    33         kx 
    33         kx 	  default:
    33         kx 	    gold_unreachable();
    33         kx 	  }
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_32PLT:
    33         kx     case elfcpp::R_386_TLS_GD_32:
    33         kx     case elfcpp::R_386_TLS_GD_PUSH:
    33         kx     case elfcpp::R_386_TLS_GD_CALL:
    33         kx     case elfcpp::R_386_TLS_GD_POP:
    33         kx     case elfcpp::R_386_TLS_LDM_32:
    33         kx     case elfcpp::R_386_TLS_LDM_PUSH:
    33         kx     case elfcpp::R_386_TLS_LDM_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM_POP:
    33         kx     case elfcpp::R_386_USED_BY_INTEL_200:
    33         kx     default:
    33         kx       unsupported_reloc_global(object, r_type, gsym);
    33         kx       break;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Process relocations for gc.
    33         kx 
    33         kx void
    33         kx Target_i386::gc_process_relocs(Symbol_table* symtab,
    33         kx 				      Layout* layout,
    33         kx 				      Sized_relobj_file<32, false>* object,
    33         kx 				      unsigned int data_shndx,
    33         kx 				      unsigned int,
    33         kx 				      const unsigned char* prelocs,
    33         kx 				      size_t reloc_count,
    33         kx 				      Output_section* output_section,
    33         kx 				      bool needs_special_offset_handling,
    33         kx 				      size_t local_symbol_count,
    33         kx 				      const unsigned char* plocal_symbols)
    33         kx {
    33         kx   gold::gc_process_relocs<32, false, Target_i386, Scan, Classify_reloc>(
    33         kx     symtab,
    33         kx     layout,
    33         kx     this,
    33         kx     object,
    33         kx     data_shndx,
    33         kx     prelocs,
    33         kx     reloc_count,
    33         kx     output_section,
    33         kx     needs_special_offset_handling,
    33         kx     local_symbol_count,
    33         kx     plocal_symbols);
    33         kx }
    33         kx 
    33         kx // Scan relocations for a section.
    33         kx 
    33         kx void
    33         kx Target_i386::scan_relocs(Symbol_table* symtab,
    33         kx 				Layout* layout,
    33         kx 				Sized_relobj_file<32, false>* object,
    33         kx 				unsigned int data_shndx,
    33         kx 				unsigned int sh_type,
    33         kx 				const unsigned char* prelocs,
    33         kx 				size_t reloc_count,
    33         kx 				Output_section* output_section,
    33         kx 				bool needs_special_offset_handling,
    33         kx 				size_t local_symbol_count,
    33         kx 				const unsigned char* plocal_symbols)
    33         kx {
    33         kx   if (sh_type == elfcpp::SHT_RELA)
    33         kx     {
    33         kx       gold_error(_("%s: unsupported RELA reloc section"),
    33         kx 		 object->name().c_str());
    33         kx       return;
    33         kx     }
    33         kx 
    33         kx   gold::scan_relocs<32, false, Target_i386, Scan, Classify_reloc>(
    33         kx     symtab,
    33         kx     layout,
    33         kx     this,
    33         kx     object,
    33         kx     data_shndx,
    33         kx     prelocs,
    33         kx     reloc_count,
    33         kx     output_section,
    33         kx     needs_special_offset_handling,
    33         kx     local_symbol_count,
    33         kx     plocal_symbols);
    33         kx }
    33         kx 
    33         kx // Finalize the sections.
    33         kx 
    33         kx void
    33         kx Target_i386::do_finalize_sections(
    33         kx     Layout* layout,
    33         kx     const Input_objects*,
    33         kx     Symbol_table* symtab)
    33         kx {
    33         kx   const Reloc_section* rel_plt = (this->plt_ == NULL
    33         kx 				  ? NULL
    33         kx 				  : this->plt_->rel_plt());
    33         kx   layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
    33         kx 				  this->rel_dyn_, true, false);
    33         kx 
    33         kx   // Emit any relocs we saved in an attempt to avoid generating COPY
    33         kx   // relocs.
    33         kx   if (this->copy_relocs_.any_saved_relocs())
    33         kx     this->copy_relocs_.emit(this->rel_dyn_section(layout));
    33         kx 
    33         kx   // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
    33         kx   // the .got.plt section.
    33         kx   Symbol* sym = this->global_offset_table_;
    33         kx   if (sym != NULL)
    33         kx     {
    33         kx       uint32_t data_size = this->got_plt_->current_data_size();
    33         kx       symtab->get_sized_symbol<32>(sym)->set_symsize(data_size);
    33         kx     }
    33         kx 
    33         kx   if (parameters->doing_static_link()
    33         kx       && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
    33         kx     {
    33         kx       // If linking statically, make sure that the __rel_iplt symbols
    33         kx       // were defined if necessary, even if we didn't create a PLT.
    33         kx       static const Define_symbol_in_segment syms[] =
    33         kx 	{
    33         kx 	  {
    33         kx 	    "__rel_iplt_start",		// name
    33         kx 	    elfcpp::PT_LOAD,		// segment_type
    33         kx 	    elfcpp::PF_W,		// segment_flags_set
    33         kx 	    elfcpp::PF(0),		// segment_flags_clear
    33         kx 	    0,				// value
    33         kx 	    0,				// size
    33         kx 	    elfcpp::STT_NOTYPE,		// type
    33         kx 	    elfcpp::STB_GLOBAL,		// binding
    33         kx 	    elfcpp::STV_HIDDEN,		// visibility
    33         kx 	    0,				// nonvis
    33         kx 	    Symbol::SEGMENT_START,	// offset_from_base
    33         kx 	    true			// only_if_ref
    33         kx 	  },
    33         kx 	  {
    33         kx 	    "__rel_iplt_end",		// name
    33         kx 	    elfcpp::PT_LOAD,		// segment_type
    33         kx 	    elfcpp::PF_W,		// segment_flags_set
    33         kx 	    elfcpp::PF(0),		// segment_flags_clear
    33         kx 	    0,				// value
    33         kx 	    0,				// size
    33         kx 	    elfcpp::STT_NOTYPE,		// type
    33         kx 	    elfcpp::STB_GLOBAL,		// binding
    33         kx 	    elfcpp::STV_HIDDEN,		// visibility
    33         kx 	    0,				// nonvis
    33         kx 	    Symbol::SEGMENT_START,	// offset_from_base
    33         kx 	    true			// only_if_ref
    33         kx 	  }
    33         kx 	};
    33         kx 
    33         kx       symtab->define_symbols(layout, 2, syms,
    33         kx 			     layout->script_options()->saw_sections_clause());
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Return whether a direct absolute static relocation needs to be applied.
    33         kx // In cases where Scan::local() or Scan::global() has created
    33         kx // a dynamic relocation other than R_386_RELATIVE, the addend
    33         kx // of the relocation is carried in the data, and we must not
    33         kx // apply the static relocation.
    33         kx 
    33         kx inline bool
    33         kx Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
    33         kx 						 unsigned int r_type,
    33         kx 						 bool is_32bit,
    33         kx 						 Output_section* output_section)
    33         kx {
    33         kx   // If the output section is not allocated, then we didn't call
    33         kx   // scan_relocs, we didn't create a dynamic reloc, and we must apply
    33         kx   // the reloc here.
    33         kx   if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
    33         kx     return true;
    33         kx 
    33         kx   int ref_flags = Scan::get_reference_flags(r_type);
    33         kx 
    33         kx   // For local symbols, we will have created a non-RELATIVE dynamic
    33         kx   // relocation only if (a) the output is position independent,
    33         kx   // (b) the relocation is absolute (not pc- or segment-relative), and
    33         kx   // (c) the relocation is not 32 bits wide.
    33         kx   if (gsym == NULL)
    33         kx     return !(parameters->options().output_is_position_independent()
    33         kx 	     && (ref_flags & Symbol::ABSOLUTE_REF)
    33         kx 	     && !is_32bit);
    33         kx 
    33         kx   // For global symbols, we use the same helper routines used in the
    33         kx   // scan pass.  If we did not create a dynamic relocation, or if we
    33         kx   // created a RELATIVE dynamic relocation, we should apply the static
    33         kx   // relocation.
    33         kx   bool has_dyn = gsym->needs_dynamic_reloc(ref_flags);
    33         kx   bool is_rel = (ref_flags & Symbol::ABSOLUTE_REF)
    33         kx 		&& gsym->can_use_relative_reloc(ref_flags
    33         kx 						& Symbol::FUNCTION_CALL);
    33         kx   return !has_dyn || is_rel;
    33         kx }
    33         kx 
    33         kx // Perform a relocation.
    33         kx 
    33         kx inline bool
    33         kx Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
    33         kx 				unsigned int,
    33         kx 				Target_i386* target,
    33         kx 				Output_section* output_section,
    33         kx 				size_t relnum,
    33         kx 				const unsigned char* preloc,
    33         kx 				const Sized_symbol<32>* gsym,
    33         kx 				const Symbol_value<32>* psymval,
    33         kx 				unsigned char* view,
    33         kx 				elfcpp::Elf_types<32>::Elf_Addr address,
    33         kx 				section_size_type view_size)
    33         kx {
    33         kx   const elfcpp::Rel<32, false> rel(preloc);
    33         kx   unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info());
    33         kx 
    33         kx   if (this->skip_call_tls_get_addr_)
    33         kx     {
    33         kx       if ((r_type != elfcpp::R_386_PLT32
    33         kx 	   && r_type != elfcpp::R_386_GOT32X
    33         kx 	   && r_type != elfcpp::R_386_PC32)
    33         kx 	  || gsym == NULL
    33         kx 	  || strcmp(gsym->name(), "___tls_get_addr") != 0)
    33         kx 	{
    33         kx 	  gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 				 _("missing expected TLS relocation"));
    33         kx 	  this->skip_call_tls_get_addr_ = false;
    33         kx 	}
    33         kx       else
    33         kx 	{
    33         kx 	  this->skip_call_tls_get_addr_ = false;
    33         kx 	  return false;
    33         kx 	}
    33         kx     }
    33         kx 
    33         kx   if (view == NULL)
    33         kx     return true;
    33         kx 
    33         kx   const Sized_relobj_file<32, false>* object = relinfo->object;
    33         kx 
    33         kx   // Pick the value to use for symbols defined in shared objects.
    33         kx   Symbol_value<32> symval;
    33         kx   if (gsym != NULL
    33         kx       && gsym->type() == elfcpp::STT_GNU_IFUNC
    33         kx       && r_type == elfcpp::R_386_32
    33         kx       && gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))
    33         kx       && gsym->can_use_relative_reloc(false)
    33         kx       && !gsym->is_from_dynobj()
    33         kx       && !gsym->is_undefined()
    33         kx       && !gsym->is_preemptible())
    33         kx     {
    33         kx       // In this case we are generating a R_386_IRELATIVE reloc.  We
    33         kx       // want to use the real value of the symbol, not the PLT offset.
    33         kx     }
    33         kx   else if (gsym != NULL
    33         kx 	   && gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
    33         kx     {
    33         kx       symval.set_output_value(target->plt_address_for_global(gsym));
    33         kx       psymval = &symval;
    33         kx     }
    33         kx   else if (gsym == NULL && psymval->is_ifunc_symbol())
    33         kx     {
    33         kx       unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
    33         kx       if (object->local_has_plt_offset(r_sym))
    33         kx 	{
    33         kx 	  symval.set_output_value(target->plt_address_for_local(object, r_sym));
    33         kx 	  psymval = &symval;
    33         kx 	}
    33         kx     }
    33         kx 
    33         kx   bool baseless;
    33         kx 
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_NONE:
    33         kx     case elfcpp::R_386_GNU_VTINHERIT:
    33         kx     case elfcpp::R_386_GNU_VTENTRY:
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_32:
    33         kx       if (should_apply_static_reloc(gsym, r_type, true, output_section))
    33         kx 	Relocate_functions<32, false>::rel32(view, object, psymval);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PC32:
    33         kx       if (should_apply_static_reloc(gsym, r_type, true, output_section))
    33         kx 	Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_16:
    33         kx       if (should_apply_static_reloc(gsym, r_type, false, output_section))
    33         kx 	Relocate_functions<32, false>::rel16(view, object, psymval);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PC16:
    33         kx       if (should_apply_static_reloc(gsym, r_type, false, output_section))
    33         kx 	Relocate_functions<32, false>::pcrel16(view, object, psymval, address);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_8:
    33         kx       if (should_apply_static_reloc(gsym, r_type, false, output_section))
    33         kx 	Relocate_functions<32, false>::rel8(view, object, psymval);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PC8:
    33         kx       if (should_apply_static_reloc(gsym, r_type, false, output_section))
    33         kx 	Relocate_functions<32, false>::pcrel8(view, object, psymval, address);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_PLT32:
    33         kx       gold_assert(gsym == NULL
    33         kx 		  || gsym->has_plt_offset()
    33         kx 		  || gsym->final_value_is_known()
    33         kx 		  || (gsym->is_defined()
    33         kx 		      && !gsym->is_from_dynobj()
    33         kx 		      && !gsym->is_preemptible()));
    33         kx       Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOT32:
    33         kx     case elfcpp::R_386_GOT32X:
    33         kx       baseless = (view[-1] & 0xc7) == 0x5;
    33         kx       // R_386_GOT32 and R_386_GOT32X don't work without base register
    33         kx       // when generating a position-independent output file.
    33         kx       if (baseless
    33         kx 	  && parameters->options().output_is_position_independent())
    33         kx 	{
    33         kx 	  if(gsym)
    33         kx 	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 				   _("unexpected reloc %u against global symbol %s without base register in object file when generating a position-independent output file"),
    33         kx 				   r_type, gsym->demangled_name().c_str());
    33         kx 	  else
    33         kx 	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 				   _("unexpected reloc %u against local symbol without base register in object file when generating a position-independent output file"),
    33         kx 				   r_type);
    33         kx 	}
    33         kx 
    33         kx       // Convert
    33         kx       // mov foo@GOT(%reg), %reg
    33         kx       // to
    33         kx       // lea foo@GOTOFF(%reg), %reg
    33         kx       // if possible.
    33         kx       if (rel.get_r_offset() >= 2
    33         kx 	  && view[-2] == 0x8b
    33         kx 	  && ((gsym == NULL && !psymval->is_ifunc_symbol())
    33         kx 	      || (gsym != NULL
    33         kx 		  && Target_i386::can_convert_mov_to_lea(gsym))))
    33         kx 	{
    33         kx 	  view[-2] = 0x8d;
    33         kx 	  elfcpp::Elf_types<32>::Elf_Addr value;
    33         kx 	  value = psymval->value(object, 0);
    33         kx 	  // Don't subtract the .got.plt section address for baseless
    33         kx 	  // addressing.
    33         kx 	  if (!baseless)
    33         kx 	    value -= target->got_plt_section()->address();
    33         kx 	  Relocate_functions<32, false>::rel32(view, value);
    33         kx 	}
    33         kx       else
    33         kx 	{
    33         kx 	  // The GOT pointer points to the end of the GOT section.
    33         kx 	  // We need to subtract the size of the GOT section to get
    33         kx 	  // the actual offset to use in the relocation.
    33         kx 	  unsigned int got_offset = 0;
    33         kx 	  if (gsym != NULL)
    33         kx 	    {
    33         kx 	      gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
    33         kx 	      got_offset = (gsym->got_offset(GOT_TYPE_STANDARD)
    33         kx 			    - target->got_size());
    33         kx 	    }
    33         kx 	  else
    33         kx 	    {
    33         kx 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
    33         kx 	      gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
    33         kx 	      got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
    33         kx 			    - target->got_size());
    33         kx 	    }
    33         kx 	  // Add the .got.plt section address for baseless addressing.
    33         kx 	  if (baseless)
    33         kx 	    got_offset += target->got_plt_section()->address();
    33         kx 	  Relocate_functions<32, false>::rel32(view, got_offset);
    33         kx 	}
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOTOFF:
    33         kx       {
    33         kx 	elfcpp::Elf_types<32>::Elf_Addr reladdr;
    33         kx 	reladdr = target->got_plt_section()->address();
    33         kx 	Relocate_functions<32, false>::pcrel32(view, object, psymval, reladdr);
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_GOTPC:
    33         kx       {
    33         kx 	elfcpp::Elf_types<32>::Elf_Addr value;
    33         kx 	value = target->got_plt_section()->address();
    33         kx 	Relocate_functions<32, false>::pcrel32(view, value, address);
    33         kx       }
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_COPY:
    33         kx     case elfcpp::R_386_GLOB_DAT:
    33         kx     case elfcpp::R_386_JUMP_SLOT:
    33         kx     case elfcpp::R_386_RELATIVE:
    33         kx     case elfcpp::R_386_IRELATIVE:
    33         kx       // These are outstanding tls relocs, which are unexpected when
    33         kx       // linking.
    33         kx     case elfcpp::R_386_TLS_TPOFF:
    33         kx     case elfcpp::R_386_TLS_DTPMOD32:
    33         kx     case elfcpp::R_386_TLS_DTPOFF32:
    33         kx     case elfcpp::R_386_TLS_TPOFF32:
    33         kx     case elfcpp::R_386_TLS_DESC:
    33         kx       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     _("unexpected reloc %u in object file"),
    33         kx 			     r_type);
    33         kx       break;
    33         kx 
    33         kx       // These are initial tls relocs, which are expected when
    33         kx       // linking.
    33         kx     case elfcpp::R_386_TLS_GD:             // Global-dynamic
    33         kx     case elfcpp::R_386_TLS_GOTDESC:        // Global-dynamic (from ~oliva url)
    33         kx     case elfcpp::R_386_TLS_DESC_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM:            // Local-dynamic
    33         kx     case elfcpp::R_386_TLS_LDO_32:         // Alternate local-dynamic
    33         kx     case elfcpp::R_386_TLS_IE:             // Initial-exec
    33         kx     case elfcpp::R_386_TLS_IE_32:
    33         kx     case elfcpp::R_386_TLS_GOTIE:
    33         kx     case elfcpp::R_386_TLS_LE:             // Local-exec
    33         kx     case elfcpp::R_386_TLS_LE_32:
    33         kx       this->relocate_tls(relinfo, target, relnum, rel, r_type, gsym, psymval,
    33         kx 			 view, address, view_size);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_32PLT:
    33         kx     case elfcpp::R_386_TLS_GD_32:
    33         kx     case elfcpp::R_386_TLS_GD_PUSH:
    33         kx     case elfcpp::R_386_TLS_GD_CALL:
    33         kx     case elfcpp::R_386_TLS_GD_POP:
    33         kx     case elfcpp::R_386_TLS_LDM_32:
    33         kx     case elfcpp::R_386_TLS_LDM_PUSH:
    33         kx     case elfcpp::R_386_TLS_LDM_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM_POP:
    33         kx     case elfcpp::R_386_USED_BY_INTEL_200:
    33         kx     default:
    33         kx       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     _("unsupported reloc %u"),
    33         kx 			     r_type);
    33         kx       break;
    33         kx     }
    33         kx 
    33         kx   return true;
    33         kx }
    33         kx 
    33         kx // Perform a TLS relocation.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
    33         kx 				    Target_i386* target,
    33         kx 				    size_t relnum,
    33         kx 				    const elfcpp::Rel<32, false>& rel,
    33         kx 				    unsigned int r_type,
    33         kx 				    const Sized_symbol<32>* gsym,
    33         kx 				    const Symbol_value<32>* psymval,
    33         kx 				    unsigned char* view,
    33         kx 				    elfcpp::Elf_types<32>::Elf_Addr,
    33         kx 				    section_size_type view_size)
    33         kx {
    33         kx   Output_segment* tls_segment = relinfo->layout->tls_segment();
    33         kx 
    33         kx   const Sized_relobj_file<32, false>* object = relinfo->object;
    33         kx 
    33         kx   elfcpp::Elf_types<32>::Elf_Addr value = psymval->value(object, 0);
    33         kx 
    33         kx   const bool is_final = (gsym == NULL
    33         kx 			 ? !parameters->options().shared()
    33         kx 			 : gsym->final_value_is_known());
    33         kx   const tls::Tls_optimization optimized_type
    33         kx       = Target_i386::optimize_tls_reloc(is_final, r_type);
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_TLS_GD:           // Global-dynamic
    33         kx       if (optimized_type == tls::TLSOPT_TO_LE)
    33         kx 	{
    33         kx 	  if (tls_segment == NULL)
    33         kx 	    {
    33         kx 	      gold_assert(parameters->errors()->error_count() > 0
    33         kx 			  || issue_undefined_symbol_error(gsym));
    33         kx 	      return;
    33         kx 	    }
    33         kx 	  this->tls_gd_to_le(relinfo, relnum, tls_segment,
    33         kx 			     rel, r_type, value, view,
    33         kx 			     view_size);
    33         kx 	  break;
    33         kx 	}
    33         kx       else
    33         kx 	{
    33         kx 	  unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
    33         kx 				   ? GOT_TYPE_TLS_NOFFSET
    33         kx 				   : GOT_TYPE_TLS_PAIR);
    33         kx 	  unsigned int got_offset;
    33         kx 	  if (gsym != NULL)
    33         kx 	    {
    33         kx 	      gold_assert(gsym->has_got_offset(got_type));
    33         kx 	      got_offset = gsym->got_offset(got_type) - target->got_size();
    33         kx 	    }
    33         kx 	  else
    33         kx 	    {
    33         kx 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
    33         kx 	      gold_assert(object->local_has_got_offset(r_sym, got_type));
    33         kx 	      got_offset = (object->local_got_offset(r_sym, got_type)
    33         kx 			    - target->got_size());
    33         kx 	    }
    33         kx 	  if (optimized_type == tls::TLSOPT_TO_IE)
    33         kx 	    {
    33         kx 	      this->tls_gd_to_ie(relinfo, relnum, rel, r_type,
    33         kx 				 got_offset, view, view_size);
    33         kx 	      break;
    33         kx 	    }
    33         kx 	  else if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	    {
    33         kx 	      // Relocate the field with the offset of the pair of GOT
    33         kx 	      // entries.
    33         kx 	      Relocate_functions<32, false>::rel32(view, got_offset);
    33         kx 	      break;
    33         kx 	    }
    33         kx 	}
    33         kx       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     _("unsupported reloc %u"),
    33         kx 			     r_type);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_GOTDESC:      // Global-dynamic (from ~oliva url)
    33         kx     case elfcpp::R_386_TLS_DESC_CALL:
    33         kx       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
    33         kx       if (optimized_type == tls::TLSOPT_TO_LE)
    33         kx 	{
    33         kx 	  if (tls_segment == NULL)
    33         kx 	    {
    33         kx 	      gold_assert(parameters->errors()->error_count() > 0
    33         kx 			  || issue_undefined_symbol_error(gsym));
    33         kx 	      return;
    33         kx 	    }
    33         kx 	  this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
    33         kx 				  rel, r_type, value, view,
    33         kx 				  view_size);
    33         kx 	  break;
    33         kx 	}
    33         kx       else
    33         kx 	{
    33         kx 	  unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
    33         kx 				   ? GOT_TYPE_TLS_NOFFSET
    33         kx 				   : GOT_TYPE_TLS_DESC);
    33         kx 	  unsigned int got_offset = 0;
    33         kx 	  if (r_type == elfcpp::R_386_TLS_GOTDESC
    33         kx 	      && optimized_type == tls::TLSOPT_NONE)
    33         kx 	    {
    33         kx 	      // We created GOT entries in the .got.tlsdesc portion of
    33         kx 	      // the .got.plt section, but the offset stored in the
    33         kx 	      // symbol is the offset within .got.tlsdesc.
    33         kx 	      got_offset = (target->got_size()
    33         kx 			    + target->got_plt_section()->data_size());
    33         kx 	    }
    33         kx 	  if (gsym != NULL)
    33         kx 	    {
    33         kx 	      gold_assert(gsym->has_got_offset(got_type));
    33         kx 	      got_offset += gsym->got_offset(got_type) - target->got_size();
    33         kx 	    }
    33         kx 	  else
    33         kx 	    {
    33         kx 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
    33         kx 	      gold_assert(object->local_has_got_offset(r_sym, got_type));
    33         kx 	      got_offset += (object->local_got_offset(r_sym, got_type)
    33         kx 			     - target->got_size());
    33         kx 	    }
    33         kx 	  if (optimized_type == tls::TLSOPT_TO_IE)
    33         kx 	    {
    33         kx 	      this->tls_desc_gd_to_ie(relinfo, relnum, rel, r_type,
    33         kx 				      got_offset, view, view_size);
    33         kx 	      break;
    33         kx 	    }
    33         kx 	  else if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	    {
    33         kx 	      if (r_type == elfcpp::R_386_TLS_GOTDESC)
    33         kx 		{
    33         kx 		  // Relocate the field with the offset of the pair of GOT
    33         kx 		  // entries.
    33         kx 		  Relocate_functions<32, false>::rel32(view, got_offset);
    33         kx 		}
    33         kx 	      break;
    33         kx 	    }
    33         kx 	}
    33         kx       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     _("unsupported reloc %u"),
    33         kx 			     r_type);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_LDM:          // Local-dynamic
    33         kx       if (this->local_dynamic_type_ == LOCAL_DYNAMIC_SUN)
    33         kx 	{
    33         kx 	  gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 				 _("both SUN and GNU model "
    33         kx 				   "TLS relocations"));
    33         kx 	  break;
    33         kx 	}
    33         kx       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
    33         kx       if (optimized_type == tls::TLSOPT_TO_LE)
    33         kx 	{
    33         kx 	  if (tls_segment == NULL)
    33         kx 	    {
    33         kx 	      gold_assert(parameters->errors()->error_count() > 0
    33         kx 			  || issue_undefined_symbol_error(gsym));
    33         kx 	      return;
    33         kx 	    }
    33         kx 	  this->tls_ld_to_le(relinfo, relnum, tls_segment, rel, r_type,
    33         kx 			     value, view, view_size);
    33         kx 	  break;
    33         kx 	}
    33         kx       else if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	{
    33         kx 	  // Relocate the field with the offset of the GOT entry for
    33         kx 	  // the module index.
    33         kx 	  unsigned int got_offset;
    33         kx 	  got_offset = (target->got_mod_index_entry(NULL, NULL, NULL)
    33         kx 			- target->got_size());
    33         kx 	  Relocate_functions<32, false>::rel32(view, got_offset);
    33         kx 	  break;
    33         kx 	}
    33         kx       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     _("unsupported reloc %u"),
    33         kx 			     r_type);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_LDO_32:       // Alternate local-dynamic
    33         kx       if (optimized_type == tls::TLSOPT_TO_LE)
    33         kx 	{
    33         kx 	  // This reloc can appear in debugging sections, in which
    33         kx 	  // case we must not convert to local-exec.  We decide what
    33         kx 	  // to do based on whether the section is marked as
    33         kx 	  // containing executable code.  That is what the GNU linker
    33         kx 	  // does as well.
    33         kx 	  elfcpp::Shdr<32, false> shdr(relinfo->data_shdr);
    33         kx 	  if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
    33         kx 	    {
    33         kx 	      if (tls_segment == NULL)
    33         kx 		{
    33         kx 		  gold_assert(parameters->errors()->error_count() > 0
    33         kx 			      || issue_undefined_symbol_error(gsym));
    33         kx 		  return;
    33         kx 		}
    33         kx 	      value -= tls_segment->memsz();
    33         kx 	    }
    33         kx 	}
    33         kx       Relocate_functions<32, false>::rel32(view, value);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_IE:           // Initial-exec
    33         kx     case elfcpp::R_386_TLS_GOTIE:
    33         kx     case elfcpp::R_386_TLS_IE_32:
    33         kx       if (optimized_type == tls::TLSOPT_TO_LE)
    33         kx 	{
    33         kx 	  if (tls_segment == NULL)
    33         kx 	    {
    33         kx 	      gold_assert(parameters->errors()->error_count() > 0
    33         kx 			  || issue_undefined_symbol_error(gsym));
    33         kx 	      return;
    33         kx 	    }
    33         kx 	  Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
    33         kx 					      rel, r_type, value, view,
    33         kx 					      view_size);
    33         kx 	  break;
    33         kx 	}
    33         kx       else if (optimized_type == tls::TLSOPT_NONE)
    33         kx 	{
    33         kx 	  // Relocate the field with the offset of the GOT entry for
    33         kx 	  // the tp-relative offset of the symbol.
    33         kx 	  unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
    33         kx 				   ? GOT_TYPE_TLS_OFFSET
    33         kx 				   : GOT_TYPE_TLS_NOFFSET);
    33         kx 	  unsigned int got_offset;
    33         kx 	  if (gsym != NULL)
    33         kx 	    {
    33         kx 	      gold_assert(gsym->has_got_offset(got_type));
    33         kx 	      got_offset = gsym->got_offset(got_type);
    33         kx 	    }
    33         kx 	  else
    33         kx 	    {
    33         kx 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
    33         kx 	      gold_assert(object->local_has_got_offset(r_sym, got_type));
    33         kx 	      got_offset = object->local_got_offset(r_sym, got_type);
    33         kx 	    }
    33         kx 	  // For the R_386_TLS_IE relocation, we need to apply the
    33         kx 	  // absolute address of the GOT entry.
    33         kx 	  if (r_type == elfcpp::R_386_TLS_IE)
    33         kx 	    got_offset += target->got_plt_section()->address();
    33         kx 	  // All GOT offsets are relative to the end of the GOT.
    33         kx 	  got_offset -= target->got_size();
    33         kx 	  Relocate_functions<32, false>::rel32(view, got_offset);
    33         kx 	  break;
    33         kx 	}
    33         kx       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     _("unsupported reloc %u"),
    33         kx 			     r_type);
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_LE:           // Local-exec
    33         kx       // If we're creating a shared library, a dynamic relocation will
    33         kx       // have been created for this location, so do not apply it now.
    33         kx       if (!parameters->options().shared())
    33         kx 	{
    33         kx 	  if (tls_segment == NULL)
    33         kx 	    {
    33         kx 	      gold_assert(parameters->errors()->error_count() > 0
    33         kx 			  || issue_undefined_symbol_error(gsym));
    33         kx 	      return;
    33         kx 	    }
    33         kx 	  value -= tls_segment->memsz();
    33         kx 	  Relocate_functions<32, false>::rel32(view, value);
    33         kx 	}
    33         kx       break;
    33         kx 
    33         kx     case elfcpp::R_386_TLS_LE_32:
    33         kx       // If we're creating a shared library, a dynamic relocation will
    33         kx       // have been created for this location, so do not apply it now.
    33         kx       if (!parameters->options().shared())
    33         kx 	{
    33         kx 	  if (tls_segment == NULL)
    33         kx 	    {
    33         kx 	      gold_assert(parameters->errors()->error_count() > 0
    33         kx 			  || issue_undefined_symbol_error(gsym));
    33         kx 	      return;
    33         kx 	    }
    33         kx 	  value = tls_segment->memsz() - value;
    33         kx 	  Relocate_functions<32, false>::rel32(view, value);
    33         kx 	}
    33         kx       break;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Do a relocation in which we convert a TLS General-Dynamic to a
    33         kx // Local-Exec.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Relocate::tls_gd_to_le(const Relocate_info<32, false>* relinfo,
    33         kx 				    size_t relnum,
    33         kx 				    Output_segment* tls_segment,
    33         kx 				    const elfcpp::Rel<32, false>& rel,
    33         kx 				    unsigned int,
    33         kx 				    elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 				    unsigned char* view,
    33         kx 				    section_size_type view_size)
    33         kx {
    33         kx   // leal foo(,%ebx,1),%eax; call ___tls_get_addr@PLT
    33         kx   //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
    33         kx   // leal foo(%ebx),%eax; call ___tls_get_addr@PLT
    33         kx   //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
    33         kx   // leal foo(%reg),%eax; call *___tls_get_addr@GOT(%reg)
    33         kx   //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
    33         kx 
    33         kx   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
    33         kx   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9);
    33         kx 
    33         kx   unsigned char op1 = view[-1];
    33         kx   unsigned char op2 = view[-2];
    33         kx   unsigned char op3 = view[4];
    33         kx 
    33         kx   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		 op2 == 0x8d || op2 == 0x04);
    33         kx   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		 op3 == 0xe8 || op3 == 0xff);
    33         kx 
    33         kx   int roff = 5;
    33         kx 
    33         kx   if (op2 == 0x04)
    33         kx     {
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -3);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     ((op1 & 0xc7) == 0x05 && op1 != (4 << 3)));
    33         kx       memcpy(view - 3, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       unsigned char reg = op1 & 7;
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     ((op1 & 0xf8) == 0x80
    33         kx 		      && reg != 4
    33         kx 		      && reg != 0
    33         kx 		      && (op3 == 0xe8 || (view[5] & 0x7) == reg)));
    33         kx       if (op3 == 0xff
    33         kx 	  || (rel.get_r_offset() + 9 < view_size
    33         kx 	      && view[9] == 0x90))
    33         kx 	{
    33         kx 	  // There is an indirect call or a trailing nop.  Use the size
    33         kx 	  // byte subl.
    33         kx 	  memcpy(view - 2, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
    33         kx 	  roff = 6;
    33         kx 	}
    33         kx       else
    33         kx 	{
    33         kx 	  // Use the five byte subl.
    33         kx 	  memcpy(view - 2, "\x65\xa1\0\0\0\0\x2d\0\0\0", 11);
    33         kx 	}
    33         kx     }
    33         kx 
    33         kx   value = tls_segment->memsz() - value;
    33         kx   Relocate_functions<32, false>::rel32(view + roff, value);
    33         kx 
    33         kx   // The next reloc should be a PLT32 reloc against __tls_get_addr.
    33         kx   // We can skip it.
    33         kx   this->skip_call_tls_get_addr_ = true;
    33         kx }
    33         kx 
    33         kx // Do a relocation in which we convert a TLS General-Dynamic to an
    33         kx // Initial-Exec.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
    33         kx 				    size_t relnum,
    33         kx 				    const elfcpp::Rel<32, false>& rel,
    33         kx 				    unsigned int,
    33         kx 				    elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 				    unsigned char* view,
    33         kx 				    section_size_type view_size)
    33         kx {
    33         kx   // leal foo(,%ebx,1),%eax; call ___tls_get_addr@PLT
    33         kx   //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
    33         kx   // leal foo(%ebx),%eax; call ___tls_get_addr@PLT; nop
    33         kx   //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
    33         kx   // leal foo(%reg),%eax; call *___tls_get_addr@GOT(%reg)
    33         kx   //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%reg),%eax
    33         kx 
    33         kx   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
    33         kx   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9);
    33         kx 
    33         kx   unsigned char op1 = view[-1];
    33         kx   unsigned char op2 = view[-2];
    33         kx   unsigned char op3 = view[4];
    33         kx 
    33         kx   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		 op2 == 0x8d || op2 == 0x04);
    33         kx   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		 op3 == 0xe8 || op3 == 0xff);
    33         kx 
    33         kx   int roff;
    33         kx 
    33         kx   if (op2 == 0x04)
    33         kx     {
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -3);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     ((op1 & 0xc7) == 0x05 && op1 != (4 << 3)));
    33         kx       roff = 5;
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       unsigned char reg = op1 & 7;
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 10);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     ((op1 & 0xf8) == 0x80
    33         kx 		      && reg != 4
    33         kx 		      && reg != 0
    33         kx 		      && ((op3 == 0xe8 && view[9] == 0x90)
    33         kx 			   || (view[5] & 0x7) == reg)));
    33         kx       roff = 6;
    33         kx     }
    33         kx 
    33         kx   memcpy(view + roff - 8, "\x65\xa1\0\0\0\0\x03\x83\0\0\0", 12);
    33         kx   Relocate_functions<32, false>::rel32(view + roff, value);
    33         kx 
    33         kx   // The next reloc should be a PLT32 reloc against __tls_get_addr.
    33         kx   // We can skip it.
    33         kx   this->skip_call_tls_get_addr_ = true;
    33         kx }
    33         kx 
    33         kx // Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
    33         kx // General-Dynamic to a Local-Exec.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Relocate::tls_desc_gd_to_le(
    33         kx     const Relocate_info<32, false>* relinfo,
    33         kx     size_t relnum,
    33         kx     Output_segment* tls_segment,
    33         kx     const elfcpp::Rel<32, false>& rel,
    33         kx     unsigned int r_type,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx     unsigned char* view,
    33         kx     section_size_type view_size)
    33         kx {
    33         kx   if (r_type == elfcpp::R_386_TLS_GOTDESC)
    33         kx     {
    33         kx       // leal foo@TLSDESC(%ebx), %eax
    33         kx       // ==> leal foo@NTPOFF, %eax
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     view[-2] == 0x8d && view[-1] == 0x83);
    33         kx       view[-1] = 0x05;
    33         kx       value -= tls_segment->memsz();
    33         kx       Relocate_functions<32, false>::rel32(view, value);
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       // call *foo@TLSCALL(%eax)
    33         kx       // ==> nop; nop
    33         kx       gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     view[0] == 0xff && view[1] == 0x10);
    33         kx       view[0] = 0x66;
    33         kx       view[1] = 0x90;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
    33         kx // General-Dynamic to an Initial-Exec.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Relocate::tls_desc_gd_to_ie(
    33         kx     const Relocate_info<32, false>* relinfo,
    33         kx     size_t relnum,
    33         kx     const elfcpp::Rel<32, false>& rel,
    33         kx     unsigned int r_type,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx     unsigned char* view,
    33         kx     section_size_type view_size)
    33         kx {
    33         kx   if (r_type == elfcpp::R_386_TLS_GOTDESC)
    33         kx     {
    33         kx       // leal foo@TLSDESC(%ebx), %eax
    33         kx       // ==> movl foo@GOTNTPOFF(%ebx), %eax
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     view[-2] == 0x8d && view[-1] == 0x83);
    33         kx       view[-2] = 0x8b;
    33         kx       Relocate_functions<32, false>::rel32(view, value);
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       // call *foo@TLSCALL(%eax)
    33         kx       // ==> nop; nop
    33         kx       gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     view[0] == 0xff && view[1] == 0x10);
    33         kx       view[0] = 0x66;
    33         kx       view[1] = 0x90;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Do a relocation in which we convert a TLS Local-Dynamic to a
    33         kx // Local-Exec.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Relocate::tls_ld_to_le(const Relocate_info<32, false>* relinfo,
    33         kx 				    size_t relnum,
    33         kx 				    Output_segment*,
    33         kx 				    const elfcpp::Rel<32, false>& rel,
    33         kx 				    unsigned int,
    33         kx 				    elfcpp::Elf_types<32>::Elf_Addr,
    33         kx 				    unsigned char* view,
    33         kx 				    section_size_type view_size)
    33         kx {
    33         kx   // leal foo(%ebx), %eax; call ___tls_get_addr@PLT
    33         kx   // ==> movl %gs:0,%eax; nop; leal 0(%esi,1),%esi
    33         kx   // leal foo(%reg), %eax; call call *___tls_get_addr@GOT(%reg)
    33         kx   // ==> movl %gs:0,%eax; leal (%esi),%esi
    33         kx 
    33         kx   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
    33         kx 
    33         kx   unsigned char op1 = view[-1];
    33         kx   unsigned char op2 = view[-2];
    33         kx   unsigned char op3 = view[4];
    33         kx 
    33         kx   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		 op3 == 0xe8 || op3 == 0xff);
    33         kx   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size,
    33         kx 		   op3 == 0xe8 ? 9 : 10);
    33         kx 
    33         kx   // FIXME: Does this test really always pass?
    33         kx   tls::check_tls(relinfo, relnum, rel.get_r_offset(), op2 == 0x8d);
    33         kx 
    33         kx   unsigned char reg = op1 & 7;
    33         kx   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		 ((op1 & 0xf8) == 0x80
    33         kx 		  && reg != 4
    33         kx 		  && reg != 0
    33         kx 		  && (op3 == 0xe8 || (view[5] & 0x7) == reg)));
    33         kx 
    33         kx   if (op3 == 0xe8)
    33         kx     memcpy(view - 2, "\x65\xa1\0\0\0\0\x90\x8d\x74\x26\0", 11);
    33         kx   else
    33         kx     memcpy(view - 2, "\x65\xa1\0\0\0\0\x8d\xb6\0\0\0\0", 12);
    33         kx 
    33         kx   // The next reloc should be a PLT32 reloc against __tls_get_addr.
    33         kx   // We can skip it.
    33         kx   this->skip_call_tls_get_addr_ = true;
    33         kx }
    33         kx 
    33         kx // Do a relocation in which we convert a TLS Initial-Exec to a
    33         kx // Local-Exec.
    33         kx 
    33         kx inline void
    33         kx Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
    33         kx 				    size_t relnum,
    33         kx 				    Output_segment* tls_segment,
    33         kx 				    const elfcpp::Rel<32, false>& rel,
    33         kx 				    unsigned int r_type,
    33         kx 				    elfcpp::Elf_types<32>::Elf_Addr value,
    33         kx 				    unsigned char* view,
    33         kx 				    section_size_type view_size)
    33         kx {
    33         kx   // We have to actually change the instructions, which means that we
    33         kx   // need to examine the opcodes to figure out which instruction we
    33         kx   // are looking at.
    33         kx   if (r_type == elfcpp::R_386_TLS_IE)
    33         kx     {
    33         kx       // movl %gs:XX,%eax  ==>  movl $YY,%eax
    33         kx       // movl %gs:XX,%reg  ==>  movl $YY,%reg
    33         kx       // addl %gs:XX,%reg  ==>  addl $YY,%reg
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -1);
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
    33         kx 
    33         kx       unsigned char op1 = view[-1];
    33         kx       if (op1 == 0xa1)
    33         kx 	{
    33         kx 	  // movl XX,%eax  ==>  movl $YY,%eax
    33         kx 	  view[-1] = 0xb8;
    33         kx 	}
    33         kx       else
    33         kx 	{
    33         kx 	  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
    33         kx 
    33         kx 	  unsigned char op2 = view[-2];
    33         kx 	  if (op2 == 0x8b)
    33         kx 	    {
    33         kx 	      // movl XX,%reg  ==>  movl $YY,%reg
    33         kx 	      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     (op1 & 0xc7) == 0x05);
    33         kx 	      view[-2] = 0xc7;
    33         kx 	      view[-1] = 0xc0 | ((op1 >> 3) & 7);
    33         kx 	    }
    33         kx 	  else if (op2 == 0x03)
    33         kx 	    {
    33         kx 	      // addl XX,%reg  ==>  addl $YY,%reg
    33         kx 	      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 			     (op1 & 0xc7) == 0x05);
    33         kx 	      view[-2] = 0x81;
    33         kx 	      view[-1] = 0xc0 | ((op1 >> 3) & 7);
    33         kx 	    }
    33         kx 	  else
    33         kx 	    tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0);
    33         kx 	}
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
    33         kx       // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
    33         kx       // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
    33         kx       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
    33         kx 
    33         kx       unsigned char op1 = view[-1];
    33         kx       unsigned char op2 = view[-2];
    33         kx       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
    33         kx 		     (op1 & 0xc0) == 0x80 && (op1 & 7) != 4);
    33         kx       if (op2 == 0x8b)
    33         kx 	{
    33         kx 	  // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
    33         kx 	  view[-2] = 0xc7;
    33         kx 	  view[-1] = 0xc0 | ((op1 >> 3) & 7);
    33         kx 	}
    33         kx       else if (op2 == 0x2b)
    33         kx 	{
    33         kx 	  // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
    33         kx 	  view[-2] = 0x81;
    33         kx 	  view[-1] = 0xe8 | ((op1 >> 3) & 7);
    33         kx 	}
    33         kx       else if (op2 == 0x03)
    33         kx 	{
    33         kx 	  // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
    33         kx 	  view[-2] = 0x81;
    33         kx 	  view[-1] = 0xc0 | ((op1 >> 3) & 7);
    33         kx 	}
    33         kx       else
    33         kx 	tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0);
    33         kx     }
    33         kx 
    33         kx   value = tls_segment->memsz() - value;
    33         kx   if (r_type == elfcpp::R_386_TLS_IE || r_type == elfcpp::R_386_TLS_GOTIE)
    33         kx     value = - value;
    33         kx 
    33         kx   Relocate_functions<32, false>::rel32(view, value);
    33         kx }
    33         kx 
    33         kx // Relocate section data.
    33         kx 
    33         kx void
    33         kx Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
    33         kx 			      unsigned int sh_type,
    33         kx 			      const unsigned char* prelocs,
    33         kx 			      size_t reloc_count,
    33         kx 			      Output_section* output_section,
    33         kx 			      bool needs_special_offset_handling,
    33         kx 			      unsigned char* view,
    33         kx 			      elfcpp::Elf_types<32>::Elf_Addr address,
    33         kx 			      section_size_type view_size,
    33         kx 			      const Reloc_symbol_changes* reloc_symbol_changes)
    33         kx {
    33         kx   gold_assert(sh_type == elfcpp::SHT_REL);
    33         kx 
    33         kx   gold::relocate_section<32, false, Target_i386, Relocate,
    33         kx 			 gold::Default_comdat_behavior, Classify_reloc>(
    33         kx     relinfo,
    33         kx     this,
    33         kx     prelocs,
    33         kx     reloc_count,
    33         kx     output_section,
    33         kx     needs_special_offset_handling,
    33         kx     view,
    33         kx     address,
    33         kx     view_size,
    33         kx     reloc_symbol_changes);
    33         kx }
    33         kx 
    33         kx // Return the size of a relocation while scanning during a relocatable
    33         kx // link.
    33         kx 
    33         kx unsigned int
    33         kx Target_i386::Classify_reloc::get_size_for_reloc(
    33         kx     unsigned int r_type,
    33         kx     Relobj* object)
    33         kx {
    33         kx   switch (r_type)
    33         kx     {
    33         kx     case elfcpp::R_386_NONE:
    33         kx     case elfcpp::R_386_GNU_VTINHERIT:
    33         kx     case elfcpp::R_386_GNU_VTENTRY:
    33         kx     case elfcpp::R_386_TLS_GD:            // Global-dynamic
    33         kx     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
    33         kx     case elfcpp::R_386_TLS_DESC_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
    33         kx     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
    33         kx     case elfcpp::R_386_TLS_IE:            // Initial-exec
    33         kx     case elfcpp::R_386_TLS_IE_32:
    33         kx     case elfcpp::R_386_TLS_GOTIE:
    33         kx     case elfcpp::R_386_TLS_LE:            // Local-exec
    33         kx     case elfcpp::R_386_TLS_LE_32:
    33         kx       return 0;
    33         kx 
    33         kx     case elfcpp::R_386_32:
    33         kx     case elfcpp::R_386_PC32:
    33         kx     case elfcpp::R_386_GOT32:
    33         kx     case elfcpp::R_386_GOT32X:
    33         kx     case elfcpp::R_386_PLT32:
    33         kx     case elfcpp::R_386_GOTOFF:
    33         kx     case elfcpp::R_386_GOTPC:
    33         kx      return 4;
    33         kx 
    33         kx     case elfcpp::R_386_16:
    33         kx     case elfcpp::R_386_PC16:
    33         kx       return 2;
    33         kx 
    33         kx     case elfcpp::R_386_8:
    33         kx     case elfcpp::R_386_PC8:
    33         kx       return 1;
    33         kx 
    33         kx       // These are relocations which should only be seen by the
    33         kx       // dynamic linker, and should never be seen here.
    33         kx     case elfcpp::R_386_COPY:
    33         kx     case elfcpp::R_386_GLOB_DAT:
    33         kx     case elfcpp::R_386_JUMP_SLOT:
    33         kx     case elfcpp::R_386_RELATIVE:
    33         kx     case elfcpp::R_386_IRELATIVE:
    33         kx     case elfcpp::R_386_TLS_TPOFF:
    33         kx     case elfcpp::R_386_TLS_DTPMOD32:
    33         kx     case elfcpp::R_386_TLS_DTPOFF32:
    33         kx     case elfcpp::R_386_TLS_TPOFF32:
    33         kx     case elfcpp::R_386_TLS_DESC:
    33         kx       object->error(_("unexpected reloc %u in object file"), r_type);
    33         kx       return 0;
    33         kx 
    33         kx     case elfcpp::R_386_32PLT:
    33         kx     case elfcpp::R_386_TLS_GD_32:
    33         kx     case elfcpp::R_386_TLS_GD_PUSH:
    33         kx     case elfcpp::R_386_TLS_GD_CALL:
    33         kx     case elfcpp::R_386_TLS_GD_POP:
    33         kx     case elfcpp::R_386_TLS_LDM_32:
    33         kx     case elfcpp::R_386_TLS_LDM_PUSH:
    33         kx     case elfcpp::R_386_TLS_LDM_CALL:
    33         kx     case elfcpp::R_386_TLS_LDM_POP:
    33         kx     case elfcpp::R_386_USED_BY_INTEL_200:
    33         kx     default:
    33         kx       object->error(_("unsupported reloc %u in object file"), r_type);
    33         kx       return 0;
    33         kx     }
    33         kx }
    33         kx 
    33         kx // Scan the relocs during a relocatable link.
    33         kx 
    33         kx void
    33         kx Target_i386::scan_relocatable_relocs(Symbol_table* symtab,
    33         kx 				     Layout* layout,
    33         kx 				     Sized_relobj_file<32, false>* object,
    33         kx 				     unsigned int data_shndx,
    33         kx 				     unsigned int sh_type,
    33         kx 				     const unsigned char* prelocs,
    33         kx 				     size_t reloc_count,
    33         kx 				     Output_section* output_section,
    33         kx 				     bool needs_special_offset_handling,
    33         kx 				     size_t local_symbol_count,
    33         kx 				     const unsigned char* plocal_symbols,
    33         kx 				     Relocatable_relocs* rr)
    33         kx {
    33         kx   typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
    33         kx       Scan_relocatable_relocs;
    33         kx 
    33         kx   gold_assert(sh_type == elfcpp::SHT_REL);
    33         kx 
    33         kx   gold::scan_relocatable_relocs<32, false, Scan_relocatable_relocs>(
    33         kx     symtab,
    33         kx     layout,
    33         kx     object,
    33         kx     data_shndx,
    33         kx     prelocs,
    33         kx     reloc_count,
    33         kx     output_section,
    33         kx     needs_special_offset_handling,
    33         kx     local_symbol_count,
    33         kx     plocal_symbols,
    33         kx     rr);
    33         kx }
    33         kx 
    33         kx // Scan the relocs for --emit-relocs.
    33         kx 
    33         kx void
    33         kx Target_i386::emit_relocs_scan(Symbol_table* symtab,
    33         kx 			      Layout* layout,
    33         kx 			      Sized_relobj_file<32, false>* object,
    33         kx 			      unsigned int data_shndx,
    33         kx 			      unsigned int sh_type,
    33         kx 			      const unsigned char* prelocs,
    33         kx 			      size_t reloc_count,
    33         kx 			      Output_section* output_section,
    33         kx 			      bool needs_special_offset_handling,
    33         kx 			      size_t local_symbol_count,
    33         kx 			      const unsigned char* plocal_syms,
    33         kx 			      Relocatable_relocs* rr)
    33         kx {
    33         kx   typedef gold::Default_classify_reloc<elfcpp::SHT_REL, 32, false>
    33         kx       Classify_reloc;
    33         kx   typedef gold::Default_emit_relocs_strategy<Classify_reloc>
    33         kx       Emit_relocs_strategy;
    33         kx 
    33         kx   gold_assert(sh_type == elfcpp::SHT_REL);
    33         kx 
    33         kx   gold::scan_relocatable_relocs<32, false, Emit_relocs_strategy>(
    33         kx     symtab,
    33         kx     layout,
    33         kx     object,
    33         kx     data_shndx,
    33         kx     prelocs,
    33         kx     reloc_count,
    33         kx     output_section,
    33         kx     needs_special_offset_handling,
    33         kx     local_symbol_count,
    33         kx     plocal_syms,
    33         kx     rr);
    33         kx }
    33         kx 
    33         kx // Emit relocations for a section.
    33         kx 
    33         kx void
    33         kx Target_i386::relocate_relocs(
    33         kx     const Relocate_info<32, false>* relinfo,
    33         kx     unsigned int sh_type,
    33         kx     const unsigned char* prelocs,
    33         kx     size_t reloc_count,
    33         kx     Output_section* output_section,
    33         kx     elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
    33         kx     unsigned char* view,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr view_address,
    33         kx     section_size_type view_size,
    33         kx     unsigned char* reloc_view,
    33         kx     section_size_type reloc_view_size)
    33         kx {
    33         kx   gold_assert(sh_type == elfcpp::SHT_REL);
    33         kx 
    33         kx   gold::relocate_relocs<32, false, Classify_reloc>(
    33         kx     relinfo,
    33         kx     prelocs,
    33         kx     reloc_count,
    33         kx     output_section,
    33         kx     offset_in_output_section,
    33         kx     view,
    33         kx     view_address,
    33         kx     view_size,
    33         kx     reloc_view,
    33         kx     reloc_view_size);
    33         kx }
    33         kx 
    33         kx // Return the value to use for a dynamic which requires special
    33         kx // treatment.  This is how we support equality comparisons of function
    33         kx // pointers across shared library boundaries, as described in the
    33         kx // processor specific ABI supplement.
    33         kx 
    33         kx uint64_t
    33         kx Target_i386::do_dynsym_value(const Symbol* gsym) const
    33         kx {
    33         kx   gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
    33         kx   return this->plt_address_for_global(gsym);
    33         kx }
    33         kx 
    33         kx // Return a string used to fill a code section with nops to take up
    33         kx // the specified length.
    33         kx 
    33         kx std::string
    33         kx Target_i386::do_code_fill(section_size_type length) const
    33         kx {
    33         kx   if (length >= 16)
    33         kx     {
    33         kx       // Build a jmp instruction to skip over the bytes.
    33         kx       unsigned char jmp[5];
    33         kx       jmp[0] = 0xe9;
    33         kx       elfcpp::Swap_unaligned<32, false>::writeval(jmp + 1, length - 5);
    33         kx       return (std::string(reinterpret_cast<char*>(&jmp[0]), 5)
    33         kx 	      + std::string(length - 5, static_cast<char>(0x90)));
    33         kx     }
    33         kx 
    33         kx   // Nop sequences of various lengths.
    33         kx   const char nop1[1] = { '\x90' };                   // nop
    33         kx   const char nop2[2] = { '\x66', '\x90' };           // xchg %ax %ax
    33         kx   const char nop3[3] = { '\x8d', '\x76', '\x00' };   // leal 0(%esi),%esi
    33         kx   const char nop4[4] = { '\x8d', '\x74', '\x26',     // leal 0(%esi,1),%esi
    33         kx 			 '\x00'};
    33         kx   const char nop5[5] = { '\x90', '\x8d', '\x74',     // nop
    33         kx 			 '\x26', '\x00' };           // leal 0(%esi,1),%esi
    33         kx   const char nop6[6] = { '\x8d', '\xb6', '\x00',     // leal 0L(%esi),%esi
    33         kx 			 '\x00', '\x00', '\x00' };
    33         kx   const char nop7[7] = { '\x8d', '\xb4', '\x26',     // leal 0L(%esi,1),%esi
    33         kx 			 '\x00', '\x00', '\x00',
    33         kx 			 '\x00' };
    33         kx   const char nop8[8] = { '\x90', '\x8d', '\xb4',     // nop
    33         kx 			 '\x26', '\x00', '\x00',     // leal 0L(%esi,1),%esi
    33         kx 			 '\x00', '\x00' };
    33         kx   const char nop9[9] = { '\x89', '\xf6', '\x8d',     // movl %esi,%esi
    33         kx 			 '\xbc', '\x27', '\x00',     // leal 0L(%edi,1),%edi
    33         kx 			 '\x00', '\x00', '\x00' };
    33         kx   const char nop10[10] = { '\x8d', '\x76', '\x00',   // leal 0(%esi),%esi
    33         kx 			   '\x8d', '\xbc', '\x27',   // leal 0L(%edi,1),%edi
    33         kx 			   '\x00', '\x00', '\x00',
    33         kx 			   '\x00' };
    33         kx   const char nop11[11] = { '\x8d', '\x74', '\x26',   // leal 0(%esi,1),%esi
    33         kx 			   '\x00', '\x8d', '\xbc',   // leal 0L(%edi,1),%edi
    33         kx 			   '\x27', '\x00', '\x00',
    33         kx 			   '\x00', '\x00' };
    33         kx   const char nop12[12] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
    33         kx 			   '\x00', '\x00', '\x00',   // leal 0L(%edi),%edi
    33         kx 			   '\x8d', '\xbf', '\x00',
    33         kx 			   '\x00', '\x00', '\x00' };
    33         kx   const char nop13[13] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
    33         kx 			   '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
    33         kx 			   '\x8d', '\xbc', '\x27',
    33         kx 			   '\x00', '\x00', '\x00',
    33         kx 			   '\x00' };
    33         kx   const char nop14[14] = { '\x8d', '\xb4', '\x26',   // leal 0L(%esi,1),%esi
    33         kx 			   '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
    33         kx 			   '\x00', '\x8d', '\xbc',
    33         kx 			   '\x27', '\x00', '\x00',
    33         kx 			   '\x00', '\x00' };
    33         kx   const char nop15[15] = { '\xeb', '\x0d', '\x90',   // jmp .+15
    33         kx 			   '\x90', '\x90', '\x90',   // nop,nop,nop,...
    33         kx 			   '\x90', '\x90', '\x90',
    33         kx 			   '\x90', '\x90', '\x90',
    33         kx 			   '\x90', '\x90', '\x90' };
    33         kx 
    33         kx   const char* nops[16] = {
    33         kx     NULL,
    33         kx     nop1, nop2, nop3, nop4, nop5, nop6, nop7,
    33         kx     nop8, nop9, nop10, nop11, nop12, nop13, nop14, nop15
    33         kx   };
    33         kx 
    33         kx   return std::string(nops[length], length);
    33         kx }
    33         kx 
    33         kx // Return the value to use for the base of a DW_EH_PE_datarel offset
    33         kx // in an FDE.  Solaris and SVR4 use DW_EH_PE_datarel because their
    33         kx // assembler can not write out the difference between two labels in
    33         kx // different sections, so instead of using a pc-relative value they
    33         kx // use an offset from the GOT.
    33         kx 
    33         kx uint64_t
    33         kx Target_i386::do_ehframe_datarel_base() const
    33         kx {
    33         kx   gold_assert(this->global_offset_table_ != NULL);
    33         kx   Symbol* sym = this->global_offset_table_;
    33         kx   Sized_symbol<32>* ssym = static_cast<Sized_symbol<32>*>(sym);
    33         kx   return ssym->value();
    33         kx }
    33         kx 
    33         kx // Return whether SYM should be treated as a call to a non-split
    33         kx // function.  We don't want that to be true of a call to a
    33         kx // get_pc_thunk function.
    33         kx 
    33         kx bool
    33         kx Target_i386::do_is_call_to_non_split(const Symbol* sym,
    33         kx 				     const unsigned char*,
    33         kx 				     const unsigned char*,
    33         kx 				     section_size_type) const
    33         kx {
    33         kx   return (sym->type() == elfcpp::STT_FUNC
    33         kx 	  && !is_prefix_of("__i686.get_pc_thunk.", sym->name()));
    33         kx }
    33         kx 
    33         kx // FNOFFSET in section SHNDX in OBJECT is the start of a function
    33         kx // compiled with -fsplit-stack.  The function calls non-split-stack
    33         kx // code.  We have to change the function so that it always ensures
    33         kx // that it has enough stack space to run some random function.
    33         kx 
    33         kx void
    33         kx Target_i386::do_calls_non_split(Relobj* object, unsigned int shndx,
    33         kx 				       section_offset_type fnoffset,
    33         kx 				       section_size_type fnsize,
    33         kx 				       const unsigned char*,
    33         kx 				       size_t,
    33         kx 				       unsigned char* view,
    33         kx 				       section_size_type view_size,
    33         kx 				       std::string* from,
    33         kx 				       std::string* to) const
    33         kx {
    33         kx   // The function starts with a comparison of the stack pointer and a
    33         kx   // field in the TCB.  This is followed by a jump.
    33         kx 
    33         kx   // cmp %gs:NN,%esp
    33         kx   if (this->match_view(view, view_size, fnoffset, "\x65\x3b\x25", 3)
    33         kx       && fnsize > 7)
    33         kx     {
    33         kx       // We will call __morestack if the carry flag is set after this
    33         kx       // comparison.  We turn the comparison into an stc instruction
    33         kx       // and some nops.
    33         kx       view[fnoffset] = '\xf9';
    33         kx       this->set_view_to_nop(view, view_size, fnoffset + 1, 6);
    33         kx     }
    33         kx   // lea NN(%esp),%ecx
    33         kx   // lea NN(%esp),%edx
    33         kx   else if ((this->match_view(view, view_size, fnoffset, "\x8d\x8c\x24", 3)
    33         kx 	    || this->match_view(view, view_size, fnoffset, "\x8d\x94\x24", 3))
    33         kx 	   && fnsize > 7)
    33         kx     {
    33         kx       // This is loading an offset from the stack pointer for a
    33         kx       // comparison.  The offset is negative, so we decrease the
    33         kx       // offset by the amount of space we need for the stack.  This
    33         kx       // means we will avoid calling __morestack if there happens to
    33         kx       // be plenty of space on the stack already.
    33         kx       unsigned char* pval = view + fnoffset + 3;
    33         kx       uint32_t val = elfcpp::Swap_unaligned<32, false>::readval(pval);
    33         kx       val -= parameters->options().split_stack_adjust_size();
    33         kx       elfcpp::Swap_unaligned<32, false>::writeval(pval, val);
    33         kx     }
    33         kx   else
    33         kx     {
    33         kx       if (!object->has_no_split_stack())
    33         kx 	object->error(_("failed to match split-stack sequence at "
    33         kx 			"section %u offset %0zx"),
    33         kx 		      shndx, static_cast<size_t>(fnoffset));
    33         kx       return;
    33         kx     }
    33         kx 
    33         kx   // We have to change the function so that it calls
    33         kx   // __morestack_non_split instead of __morestack.  The former will
    33         kx   // allocate additional stack space.
    33         kx   *from = "__morestack";
    33         kx   *to = "__morestack_non_split";
    33         kx }
    33         kx 
    33         kx // The selector for i386 object files.  Note this is never instantiated
    33         kx // directly.  It's only used in Target_selector_i386_nacl, below.
    33         kx 
    33         kx class Target_selector_i386 : public Target_selector_freebsd
    33         kx {
    33         kx public:
    33         kx   Target_selector_i386()
    33         kx     : Target_selector_freebsd(elfcpp::EM_386, 32, false,
    33         kx 			      "elf32-i386", "elf32-i386-freebsd",
    33         kx 			      "elf_i386")
    33         kx   { }
    33         kx 
    33         kx   Target*
    33         kx   do_instantiate_target()
    33         kx   { return new Target_i386(); }
    33         kx };
    33         kx 
    33         kx // NaCl variant.  It uses different PLT contents.
    33         kx 
    33         kx class Output_data_plt_i386_nacl : public Output_data_plt_i386
    33         kx {
    33         kx  public:
    33         kx   Output_data_plt_i386_nacl(Layout* layout,
    33         kx 			    Output_data_got_plt_i386* got_plt,
    33         kx 			    Output_data_space* got_irelative)
    33         kx     : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   virtual unsigned int
    33         kx   do_get_plt_entry_size() const
    33         kx   { return plt_entry_size; }
    33         kx 
    33         kx   virtual void
    33         kx   do_add_eh_frame(Layout* layout)
    33         kx   {
    33         kx     layout->add_eh_frame_for_plt(this, plt_eh_frame_cie, plt_eh_frame_cie_size,
    33         kx 				 plt_eh_frame_fde, plt_eh_frame_fde_size);
    33         kx   }
    33         kx 
    33         kx   // The size of an entry in the PLT.
    33         kx   static const int plt_entry_size = 64;
    33         kx 
    33         kx   // The .eh_frame unwind information for the PLT.
    33         kx   static const int plt_eh_frame_fde_size = 32;
    33         kx   static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size];
    33         kx };
    33         kx 
    33         kx class Output_data_plt_i386_nacl_exec : public Output_data_plt_i386_nacl
    33         kx {
    33         kx public:
    33         kx   Output_data_plt_i386_nacl_exec(Layout* layout,
    33         kx 				 Output_data_got_plt_i386* got_plt,
    33         kx 				 Output_data_space* got_irelative)
    33         kx     : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   virtual void
    33         kx   do_fill_first_plt_entry(unsigned char* pov,
    33         kx 			  elfcpp::Elf_types<32>::Elf_Addr got_address);
    33         kx 
    33         kx   virtual unsigned int
    33         kx   do_fill_plt_entry(unsigned char* pov,
    33         kx 		    elfcpp::Elf_types<32>::Elf_Addr got_address,
    33         kx 		    unsigned int got_offset,
    33         kx 		    unsigned int plt_offset,
    33         kx 		    unsigned int plt_rel_offset);
    33         kx 
    33         kx  private:
    33         kx   // The first entry in the PLT for an executable.
    33         kx   static const unsigned char first_plt_entry[plt_entry_size];
    33         kx 
    33         kx   // Other entries in the PLT for an executable.
    33         kx   static const unsigned char plt_entry[plt_entry_size];
    33         kx };
    33         kx 
    33         kx class Output_data_plt_i386_nacl_dyn : public Output_data_plt_i386_nacl
    33         kx {
    33         kx  public:
    33         kx   Output_data_plt_i386_nacl_dyn(Layout* layout,
    33         kx 				Output_data_got_plt_i386* got_plt,
    33         kx 				Output_data_space* got_irelative)
    33         kx     : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   virtual void
    33         kx   do_fill_first_plt_entry(unsigned char* pov, elfcpp::Elf_types<32>::Elf_Addr);
    33         kx 
    33         kx   virtual unsigned int
    33         kx   do_fill_plt_entry(unsigned char* pov,
    33         kx 		    elfcpp::Elf_types<32>::Elf_Addr,
    33         kx 		    unsigned int got_offset,
    33         kx 		    unsigned int plt_offset,
    33         kx 		    unsigned int plt_rel_offset);
    33         kx 
    33         kx  private:
    33         kx   // The first entry in the PLT for a shared object.
    33         kx   static const unsigned char first_plt_entry[plt_entry_size];
    33         kx 
    33         kx   // Other entries in the PLT for a shared object.
    33         kx   static const unsigned char plt_entry[plt_entry_size];
    33         kx };
    33         kx 
    33         kx class Target_i386_nacl : public Target_i386
    33         kx {
    33         kx  public:
    33         kx   Target_i386_nacl()
    33         kx     : Target_i386(&i386_nacl_info)
    33         kx   { }
    33         kx 
    33         kx  protected:
    33         kx   virtual Output_data_plt_i386*
    33         kx   do_make_data_plt(Layout* layout,
    33         kx 		   Output_data_got_plt_i386* got_plt,
    33         kx 		   Output_data_space* got_irelative,
    33         kx 		   bool dyn)
    33         kx   {
    33         kx     if (dyn)
    33         kx       return new Output_data_plt_i386_nacl_dyn(layout, got_plt, got_irelative);
    33         kx     else
    33         kx       return new Output_data_plt_i386_nacl_exec(layout, got_plt, got_irelative);
    33         kx   }
    33         kx 
    33         kx   virtual std::string
    33         kx   do_code_fill(section_size_type length) const;
    33         kx 
    33         kx  private:
    33         kx   static const Target::Target_info i386_nacl_info;
    33         kx };
    33         kx 
    33         kx const Target::Target_info Target_i386_nacl::i386_nacl_info =
    33         kx {
    33         kx   32,			// size
    33         kx   false,		// is_big_endian
    33         kx   elfcpp::EM_386,	// machine_code
    33         kx   false,		// has_make_symbol
    33         kx   false,		// has_resolve
    33         kx   true,			// has_code_fill
    33         kx   true,			// is_default_stack_executable
    33         kx   true,			// can_icf_inline_merge_sections
    33         kx   '\0',			// wrap_char
    33         kx   "/lib/ld-nacl-x86-32.so.1", // dynamic_linker
    33         kx   0x20000,		// default_text_segment_address
    33         kx   0x10000,		// abi_pagesize (overridable by -z max-page-size)
    33         kx   0x10000,		// common_pagesize (overridable by -z common-page-size)
    33         kx   true,                 // isolate_execinstr
    33         kx   0x10000000,           // rosegment_gap
    33         kx   elfcpp::SHN_UNDEF,	// small_common_shndx
    33         kx   elfcpp::SHN_UNDEF,	// large_common_shndx
    33         kx   0,			// small_common_section_flags
    33         kx   0,			// large_common_section_flags
    33         kx   NULL,			// attributes_section
    33         kx   NULL,			// attributes_vendor
    33         kx   "_start",		// entry_symbol_name
    33         kx   32,			// hash_entry_size
    33         kx   elfcpp::SHT_PROGBITS,	// unwind_section_type
    33         kx };
    33         kx 
    33         kx #define	NACLMASK	0xe0            // 32-byte alignment mask
    33         kx 
    33         kx const unsigned char
    33         kx Output_data_plt_i386_nacl_exec::first_plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0xff, 0x35,                          // pushl contents of memory address
    33         kx   0, 0, 0, 0,                          // replaced with address of .got + 4
    33         kx   0x8b, 0x0d,                          // movl contents of address, %ecx
    33         kx   0, 0, 0, 0,                          // replaced with address of .got + 8
    33         kx   0x83, 0xe1, NACLMASK,                // andl $NACLMASK, %ecx
    33         kx   0xff, 0xe1,                          // jmp *%ecx
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90
    33         kx };
    33         kx 
    33         kx void
    33         kx Output_data_plt_i386_nacl_exec::do_fill_first_plt_entry(
    33         kx     unsigned char* pov,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr got_address)
    33         kx {
    33         kx   memcpy(pov, first_plt_entry, plt_entry_size);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_address + 4);
    33         kx   elfcpp::Swap<32, false>::writeval(pov + 8, got_address + 8);
    33         kx }
    33         kx 
    33         kx // The first entry in the PLT for a shared object.
    33         kx 
    33         kx const unsigned char
    33         kx Output_data_plt_i386_nacl_dyn::first_plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0xff, 0xb3, 4, 0, 0, 0,	// pushl 4(%ebx)
    33         kx   0x8b, 0x4b, 0x08,		// mov 0x8(%ebx), %ecx
    33         kx   0x83, 0xe1, NACLMASK,         // andl $NACLMASK, %ecx
    33         kx   0xff, 0xe1,                   // jmp *%ecx
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90   // nops
    33         kx };
    33         kx 
    33         kx void
    33         kx Output_data_plt_i386_nacl_dyn::do_fill_first_plt_entry(
    33         kx     unsigned char* pov,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr)
    33         kx {
    33         kx   memcpy(pov, first_plt_entry, plt_entry_size);
    33         kx }
    33         kx 
    33         kx // Subsequent entries in the PLT for an executable.
    33         kx 
    33         kx const unsigned char
    33         kx Output_data_plt_i386_nacl_exec::plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0x8b, 0x0d,                    // movl contents of address, %ecx */
    33         kx   0, 0, 0, 0,                    // replaced with address of symbol in .got
    33         kx   0x83, 0xe1, NACLMASK,          // andl $NACLMASK, %ecx
    33         kx   0xff, 0xe1,                    // jmp *%ecx
    33         kx 
    33         kx   // Pad to the next 32-byte boundary with nop instructions.
    33         kx   0x90,
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx 
    33         kx   // Lazy GOT entries point here (32-byte aligned).
    33         kx   0x68,                       // pushl immediate
    33         kx   0, 0, 0, 0,                 // replaced with offset into relocation table
    33         kx   0xe9,                       // jmp relative
    33         kx   0, 0, 0, 0,                 // replaced with offset to start of .plt
    33         kx 
    33         kx   // Pad to the next 32-byte boundary with nop instructions.
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx   0x90, 0x90
    33         kx };
    33         kx 
    33         kx unsigned int
    33         kx Output_data_plt_i386_nacl_exec::do_fill_plt_entry(
    33         kx     unsigned char* pov,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr got_address,
    33         kx     unsigned int got_offset,
    33         kx     unsigned int plt_offset,
    33         kx     unsigned int plt_rel_offset)
    33         kx {
    33         kx   memcpy(pov, plt_entry, plt_entry_size);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2,
    33         kx 					      got_address + got_offset);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset);
    33         kx   elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4));
    33         kx   return 32;
    33         kx }
    33         kx 
    33         kx // Subsequent entries in the PLT for a shared object.
    33         kx 
    33         kx const unsigned char
    33         kx Output_data_plt_i386_nacl_dyn::plt_entry[plt_entry_size] =
    33         kx {
    33         kx   0x8b, 0x8b,          // movl offset(%ebx), %ecx
    33         kx   0, 0, 0, 0,          // replaced with offset of symbol in .got
    33         kx   0x83, 0xe1, 0xe0,    // andl $NACLMASK, %ecx
    33         kx   0xff, 0xe1,          // jmp *%ecx
    33         kx 
    33         kx   // Pad to the next 32-byte boundary with nop instructions.
    33         kx   0x90,
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx 
    33         kx   // Lazy GOT entries point here (32-byte aligned).
    33         kx   0x68,                // pushl immediate
    33         kx   0, 0, 0, 0,          // replaced with offset into relocation table.
    33         kx   0xe9,                // jmp relative
    33         kx   0, 0, 0, 0,          // replaced with offset to start of .plt.
    33         kx 
    33         kx   // Pad to the next 32-byte boundary with nop instructions.
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
    33         kx   0x90, 0x90
    33         kx };
    33         kx 
    33         kx unsigned int
    33         kx Output_data_plt_i386_nacl_dyn::do_fill_plt_entry(
    33         kx     unsigned char* pov,
    33         kx     elfcpp::Elf_types<32>::Elf_Addr,
    33         kx     unsigned int got_offset,
    33         kx     unsigned int plt_offset,
    33         kx     unsigned int plt_rel_offset)
    33         kx {
    33         kx   memcpy(pov, plt_entry, plt_entry_size);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset);
    33         kx   elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset);
    33         kx   elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4));
    33         kx   return 32;
    33         kx }
    33         kx 
    33         kx const unsigned char
    33         kx Output_data_plt_i386_nacl::plt_eh_frame_fde[plt_eh_frame_fde_size] =
    33         kx {
    33         kx   0, 0, 0, 0,				// Replaced with offset to .plt.
    33         kx   0, 0, 0, 0,				// Replaced with size of .plt.
    33         kx   0,					// Augmentation size.
    33         kx   elfcpp::DW_CFA_def_cfa_offset, 8,	// DW_CFA_def_cfa_offset: 8.
    33         kx   elfcpp::DW_CFA_advance_loc + 6,	// Advance 6 to __PLT__ + 6.
    33         kx   elfcpp::DW_CFA_def_cfa_offset, 12,	// DW_CFA_def_cfa_offset: 12.
    33         kx   elfcpp::DW_CFA_advance_loc + 58,	// Advance 58 to __PLT__ + 64.
    33         kx   elfcpp::DW_CFA_def_cfa_expression,	// DW_CFA_def_cfa_expression.
    33         kx   13,					// Block length.
    33         kx   elfcpp::DW_OP_breg4, 4,		// Push %esp + 4.
    33         kx   elfcpp::DW_OP_breg8, 0,		// Push %eip.
    33         kx   elfcpp::DW_OP_const1u, 63,            // Push 0x3f.
    33         kx   elfcpp::DW_OP_and,			// & (%eip & 0x3f).
    33         kx   elfcpp::DW_OP_const1u, 37,            // Push 0x25.
    33         kx   elfcpp::DW_OP_ge,			// >= ((%eip & 0x3f) >= 0x25)
    33         kx   elfcpp::DW_OP_lit2,			// Push 2.
    33         kx   elfcpp::DW_OP_shl,			// << (((%eip & 0x3f) >= 0x25) << 2)
    33         kx   elfcpp::DW_OP_plus,			// + ((((%eip&0x3f)>=0x25)<<2)+%esp+4
    33         kx   elfcpp::DW_CFA_nop,			// Align to 32 bytes.
    33         kx   elfcpp::DW_CFA_nop
    33         kx };
    33         kx 
    33         kx // Return a string used to fill a code section with nops.
    33         kx // For NaCl, long NOPs are only valid if they do not cross
    33         kx // bundle alignment boundaries, so keep it simple with one-byte NOPs.
    33         kx std::string
    33         kx Target_i386_nacl::do_code_fill(section_size_type length) const
    33         kx {
    33         kx   return std::string(length, static_cast<char>(0x90));
    33         kx }
    33         kx 
    33         kx // The selector for i386-nacl object files.
    33         kx 
    33         kx class Target_selector_i386_nacl
    33         kx   : public Target_selector_nacl<Target_selector_i386, Target_i386_nacl>
    33         kx {
    33         kx  public:
    33         kx   Target_selector_i386_nacl()
    33         kx     : Target_selector_nacl<Target_selector_i386,
    33         kx 			   Target_i386_nacl>("x86-32",
    33         kx 					     "elf32-i386-nacl",
    33         kx 					     "elf_i386_nacl")
    33         kx   { }
    33         kx };
    33         kx 
    33         kx Target_selector_i386_nacl target_selector_i386;
    33         kx 
    33         kx // IAMCU variant.  It uses EM_IAMCU, not EM_386.
    33         kx 
    33         kx class Target_iamcu : public Target_i386
    33         kx {
    33         kx  public:
    33         kx   Target_iamcu()
    33         kx     : Target_i386(&iamcu_info)
    33         kx   { }
    33         kx 
    33         kx  private:
    33         kx   // Information about this specific target which we pass to the
    33         kx   // general Target structure.
    33         kx   static const Target::Target_info iamcu_info;
    33         kx };
    33         kx 
    33         kx const Target::Target_info Target_iamcu::iamcu_info =
    33         kx {
    33         kx   32,			// size
    33         kx   false,		// is_big_endian
    33         kx   elfcpp::EM_IAMCU,	// machine_code
    33         kx   false,		// has_make_symbol
    33         kx   false,		// has_resolve
    33         kx   true,			// has_code_fill
    33         kx   true,			// is_default_stack_executable
    33         kx   true,			// can_icf_inline_merge_sections
    33         kx   '\0',			// wrap_char
    33         kx   "/usr/lib/libc.so.1",	// dynamic_linker
    33         kx   0x08048000,		// default_text_segment_address
    33         kx   0x1000,		// abi_pagesize (overridable by -z max-page-size)
    33         kx   0x1000,		// common_pagesize (overridable by -z common-page-size)
    33         kx   false,                // isolate_execinstr
    33         kx   0,                    // rosegment_gap
    33         kx   elfcpp::SHN_UNDEF,	// small_common_shndx
    33         kx   elfcpp::SHN_UNDEF,	// large_common_shndx
    33         kx   0,			// small_common_section_flags
    33         kx   0,			// large_common_section_flags
    33         kx   NULL,			// attributes_section
    33         kx   NULL,			// attributes_vendor
    33         kx   "_start",		// entry_symbol_name
    33         kx   32,			// hash_entry_size
    33         kx   elfcpp::SHT_PROGBITS,	// unwind_section_type
    33         kx };
    33         kx 
    33         kx class Target_selector_iamcu : public Target_selector
    33         kx {
    33         kx public:
    33         kx   Target_selector_iamcu()
    33         kx     : Target_selector(elfcpp::EM_IAMCU, 32, false, "elf32-iamcu",
    33         kx 		      "elf_iamcu")
    33         kx   { }
    33         kx 
    33         kx   Target*
    33         kx   do_instantiate_target()
    33         kx   { return new Target_iamcu(); }
    33         kx };
    33         kx 
    33         kx Target_selector_iamcu target_selector_iamcu;
    33         kx 
    33         kx } // End anonymous namespace.