1ed0d50c3Schristos // i386.cc -- i386 target support for gold.
2ed0d50c3Schristos 
3*b88e3e88Schristos // Copyright (C) 2006-2020 Free Software Foundation, Inc.
4ed0d50c3Schristos // Written by Ian Lance Taylor <iant@google.com>.
5ed0d50c3Schristos 
6ed0d50c3Schristos // This file is part of gold.
7ed0d50c3Schristos 
8ed0d50c3Schristos // This program is free software; you can redistribute it and/or modify
9ed0d50c3Schristos // it under the terms of the GNU General Public License as published by
10ed0d50c3Schristos // the Free Software Foundation; either version 3 of the License, or
11ed0d50c3Schristos // (at your option) any later version.
12ed0d50c3Schristos 
13ed0d50c3Schristos // This program is distributed in the hope that it will be useful,
14ed0d50c3Schristos // but WITHOUT ANY WARRANTY; without even the implied warranty of
15ed0d50c3Schristos // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ed0d50c3Schristos // GNU General Public License for more details.
17ed0d50c3Schristos 
18ed0d50c3Schristos // You should have received a copy of the GNU General Public License
19ed0d50c3Schristos // along with this program; if not, write to the Free Software
20ed0d50c3Schristos // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21ed0d50c3Schristos // MA 02110-1301, USA.
22ed0d50c3Schristos 
23ed0d50c3Schristos #include "gold.h"
24ed0d50c3Schristos 
25ed0d50c3Schristos #include <cstring>
26ed0d50c3Schristos 
27ed0d50c3Schristos #include "elfcpp.h"
28ed0d50c3Schristos #include "dwarf.h"
29ed0d50c3Schristos #include "parameters.h"
30ed0d50c3Schristos #include "reloc.h"
31ed0d50c3Schristos #include "i386.h"
32ed0d50c3Schristos #include "object.h"
33ed0d50c3Schristos #include "symtab.h"
34ed0d50c3Schristos #include "layout.h"
35ed0d50c3Schristos #include "output.h"
36ed0d50c3Schristos #include "copy-relocs.h"
37ed0d50c3Schristos #include "target.h"
38ed0d50c3Schristos #include "target-reloc.h"
39ed0d50c3Schristos #include "target-select.h"
40ed0d50c3Schristos #include "tls.h"
41ed0d50c3Schristos #include "freebsd.h"
42ed0d50c3Schristos #include "nacl.h"
43ed0d50c3Schristos #include "gc.h"
44ed0d50c3Schristos 
45ed0d50c3Schristos namespace
46ed0d50c3Schristos {
47ed0d50c3Schristos 
48ed0d50c3Schristos using namespace gold;
49ed0d50c3Schristos 
50ed0d50c3Schristos // A class to handle the .got.plt section.
51ed0d50c3Schristos 
52ed0d50c3Schristos class Output_data_got_plt_i386 : public Output_section_data_build
53ed0d50c3Schristos {
54ed0d50c3Schristos  public:
Output_data_got_plt_i386(Layout * layout)55ed0d50c3Schristos   Output_data_got_plt_i386(Layout* layout)
56ed0d50c3Schristos     : Output_section_data_build(4),
57ed0d50c3Schristos       layout_(layout)
58ed0d50c3Schristos   { }
59ed0d50c3Schristos 
60ed0d50c3Schristos  protected:
61ed0d50c3Schristos   // Write out the PLT data.
62ed0d50c3Schristos   void
63ed0d50c3Schristos   do_write(Output_file*);
64ed0d50c3Schristos 
65ed0d50c3Schristos   // Write to a map file.
66ed0d50c3Schristos   void
do_print_to_mapfile(Mapfile * mapfile) const67ed0d50c3Schristos   do_print_to_mapfile(Mapfile* mapfile) const
68ed0d50c3Schristos   { mapfile->print_output_data(this, "** GOT PLT"); }
69ed0d50c3Schristos 
70ed0d50c3Schristos  private:
71ed0d50c3Schristos   // A pointer to the Layout class, so that we can find the .dynamic
72ed0d50c3Schristos   // section when we write out the GOT PLT section.
73ed0d50c3Schristos   Layout* layout_;
74ed0d50c3Schristos };
75ed0d50c3Schristos 
76ed0d50c3Schristos // A class to handle the PLT data.
77ed0d50c3Schristos // This is an abstract base class that handles most of the linker details
78ed0d50c3Schristos // but does not know the actual contents of PLT entries.  The derived
79ed0d50c3Schristos // classes below fill in those details.
80ed0d50c3Schristos 
81ed0d50c3Schristos class Output_data_plt_i386 : public Output_section_data
82ed0d50c3Schristos {
83ed0d50c3Schristos  public:
84ed0d50c3Schristos   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
85ed0d50c3Schristos 
86ed0d50c3Schristos   Output_data_plt_i386(Layout*, uint64_t addralign,
87ed0d50c3Schristos 		       Output_data_got_plt_i386*, Output_data_space*);
88ed0d50c3Schristos 
89ed0d50c3Schristos   // Add an entry to the PLT.
90ed0d50c3Schristos   void
91ed0d50c3Schristos   add_entry(Symbol_table*, Layout*, Symbol* gsym);
92ed0d50c3Schristos 
93ed0d50c3Schristos   // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
94ed0d50c3Schristos   unsigned int
95ed0d50c3Schristos   add_local_ifunc_entry(Symbol_table*, Layout*,
96ed0d50c3Schristos 			Sized_relobj_file<32, false>* relobj,
97ed0d50c3Schristos 			unsigned int local_sym_index);
98ed0d50c3Schristos 
99ed0d50c3Schristos   // Return the .rel.plt section data.
100ed0d50c3Schristos   Reloc_section*
rel_plt() const101ed0d50c3Schristos   rel_plt() const
102ed0d50c3Schristos   { return this->rel_; }
103ed0d50c3Schristos 
104ed0d50c3Schristos   // Return where the TLS_DESC relocations should go.
105ed0d50c3Schristos   Reloc_section*
106ed0d50c3Schristos   rel_tls_desc(Layout*);
107ed0d50c3Schristos 
108ed0d50c3Schristos   // Return where the IRELATIVE relocations should go.
109ed0d50c3Schristos   Reloc_section*
110ed0d50c3Schristos   rel_irelative(Symbol_table*, Layout*);
111ed0d50c3Schristos 
112ed0d50c3Schristos   // Return whether we created a section for IRELATIVE relocations.
113ed0d50c3Schristos   bool
has_irelative_section() const114ed0d50c3Schristos   has_irelative_section() const
115ed0d50c3Schristos   { return this->irelative_rel_ != NULL; }
116ed0d50c3Schristos 
117ed0d50c3Schristos   // Return the number of PLT entries.
118ed0d50c3Schristos   unsigned int
entry_count() const119ed0d50c3Schristos   entry_count() const
120ed0d50c3Schristos   { return this->count_ + this->irelative_count_; }
121ed0d50c3Schristos 
122ed0d50c3Schristos   // Return the offset of the first non-reserved PLT entry.
123ed0d50c3Schristos   unsigned int
first_plt_entry_offset()124ed0d50c3Schristos   first_plt_entry_offset()
125ed0d50c3Schristos   { return this->get_plt_entry_size(); }
126ed0d50c3Schristos 
127ed0d50c3Schristos   // Return the size of a PLT entry.
128ed0d50c3Schristos   unsigned int
get_plt_entry_size() const129ed0d50c3Schristos   get_plt_entry_size() const
130ed0d50c3Schristos   { return this->do_get_plt_entry_size(); }
131ed0d50c3Schristos 
132ed0d50c3Schristos   // Return the PLT address to use for a global symbol.
133ed0d50c3Schristos   uint64_t
134ed0d50c3Schristos   address_for_global(const Symbol*);
135ed0d50c3Schristos 
136ed0d50c3Schristos   // Return the PLT address to use for a local symbol.
137ed0d50c3Schristos   uint64_t
138ed0d50c3Schristos   address_for_local(const Relobj*, unsigned int symndx);
139ed0d50c3Schristos 
140ed0d50c3Schristos   // Add .eh_frame information for the PLT.
141ed0d50c3Schristos   void
add_eh_frame(Layout * layout)142ed0d50c3Schristos   add_eh_frame(Layout* layout)
143ed0d50c3Schristos   { this->do_add_eh_frame(layout); }
144ed0d50c3Schristos 
145ed0d50c3Schristos  protected:
146ed0d50c3Schristos   // Fill the first PLT entry, given the pointer to the PLT section data
147ed0d50c3Schristos   // and the runtime address of the GOT.
148ed0d50c3Schristos   void
fill_first_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr got_address)149ed0d50c3Schristos   fill_first_plt_entry(unsigned char* pov,
150ed0d50c3Schristos 		       elfcpp::Elf_types<32>::Elf_Addr got_address)
151ed0d50c3Schristos   { this->do_fill_first_plt_entry(pov, got_address); }
152ed0d50c3Schristos 
153ed0d50c3Schristos   // Fill a normal PLT entry, given the pointer to the entry's data in the
154ed0d50c3Schristos   // section, the runtime address of the GOT, the offset into the GOT of
155ed0d50c3Schristos   // the corresponding slot, the offset into the relocation section of the
156ed0d50c3Schristos   // corresponding reloc, and the offset of this entry within the whole
157ed0d50c3Schristos   // PLT.  Return the offset from this PLT entry's runtime address that
158ed0d50c3Schristos   // should be used to compute the initial value of the GOT slot.
159ed0d50c3Schristos   unsigned int
fill_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr got_address,unsigned int got_offset,unsigned int plt_offset,unsigned int plt_rel_offset)160ed0d50c3Schristos   fill_plt_entry(unsigned char* pov,
161ed0d50c3Schristos 		 elfcpp::Elf_types<32>::Elf_Addr got_address,
162ed0d50c3Schristos 		 unsigned int got_offset,
163ed0d50c3Schristos 		 unsigned int plt_offset,
164ed0d50c3Schristos 		 unsigned int plt_rel_offset)
165ed0d50c3Schristos   {
166ed0d50c3Schristos     return this->do_fill_plt_entry(pov, got_address, got_offset,
167ed0d50c3Schristos 				   plt_offset, plt_rel_offset);
168ed0d50c3Schristos   }
169ed0d50c3Schristos 
170ed0d50c3Schristos   virtual unsigned int
171ed0d50c3Schristos   do_get_plt_entry_size() const = 0;
172ed0d50c3Schristos 
173ed0d50c3Schristos   virtual void
174ed0d50c3Schristos   do_fill_first_plt_entry(unsigned char* pov,
175ed0d50c3Schristos 			  elfcpp::Elf_types<32>::Elf_Addr got_address) = 0;
176ed0d50c3Schristos 
177ed0d50c3Schristos   virtual unsigned int
178ed0d50c3Schristos   do_fill_plt_entry(unsigned char* pov,
179ed0d50c3Schristos 		    elfcpp::Elf_types<32>::Elf_Addr got_address,
180ed0d50c3Schristos 		    unsigned int got_offset,
181ed0d50c3Schristos 		    unsigned int plt_offset,
182ed0d50c3Schristos 		    unsigned int plt_rel_offset) = 0;
183ed0d50c3Schristos 
184ed0d50c3Schristos   virtual void
185ed0d50c3Schristos   do_add_eh_frame(Layout*) = 0;
186ed0d50c3Schristos 
187ed0d50c3Schristos   void
188ed0d50c3Schristos   do_adjust_output_section(Output_section* os);
189ed0d50c3Schristos 
190ed0d50c3Schristos   // Write to a map file.
191ed0d50c3Schristos   void
do_print_to_mapfile(Mapfile * mapfile) const192ed0d50c3Schristos   do_print_to_mapfile(Mapfile* mapfile) const
193ed0d50c3Schristos   { mapfile->print_output_data(this, _("** PLT")); }
194ed0d50c3Schristos 
195ed0d50c3Schristos   // The .eh_frame unwind information for the PLT.
196ed0d50c3Schristos   // The CIE is common across variants of the PLT format.
197ed0d50c3Schristos   static const int plt_eh_frame_cie_size = 16;
198ed0d50c3Schristos   static const unsigned char plt_eh_frame_cie[plt_eh_frame_cie_size];
199ed0d50c3Schristos 
200ed0d50c3Schristos  private:
201ed0d50c3Schristos   // Set the final size.
202ed0d50c3Schristos   void
set_final_data_size()203ed0d50c3Schristos   set_final_data_size()
204ed0d50c3Schristos   {
205ed0d50c3Schristos     this->set_data_size((this->count_ + this->irelative_count_ + 1)
206ed0d50c3Schristos 			* this->get_plt_entry_size());
207ed0d50c3Schristos   }
208ed0d50c3Schristos 
209ed0d50c3Schristos   // Write out the PLT data.
210ed0d50c3Schristos   void
211ed0d50c3Schristos   do_write(Output_file*);
212ed0d50c3Schristos 
213ed0d50c3Schristos   // We keep a list of global STT_GNU_IFUNC symbols, each with its
214ed0d50c3Schristos   // offset in the GOT.
215ed0d50c3Schristos   struct Global_ifunc
216ed0d50c3Schristos   {
217ed0d50c3Schristos     Symbol* sym;
218ed0d50c3Schristos     unsigned int got_offset;
219ed0d50c3Schristos   };
220ed0d50c3Schristos 
221ed0d50c3Schristos   // We keep a list of local STT_GNU_IFUNC symbols, each with its
222ed0d50c3Schristos   // offset in the GOT.
223ed0d50c3Schristos   struct Local_ifunc
224ed0d50c3Schristos   {
225ed0d50c3Schristos     Sized_relobj_file<32, false>* object;
226ed0d50c3Schristos     unsigned int local_sym_index;
227ed0d50c3Schristos     unsigned int got_offset;
228ed0d50c3Schristos   };
229ed0d50c3Schristos 
230ed0d50c3Schristos   // The reloc section.
231ed0d50c3Schristos   Reloc_section* rel_;
232ed0d50c3Schristos   // The TLS_DESC relocations, if necessary.  These must follow the
233ed0d50c3Schristos   // regular PLT relocs.
234ed0d50c3Schristos   Reloc_section* tls_desc_rel_;
235ed0d50c3Schristos   // The IRELATIVE relocations, if necessary.  These must follow the
236ed0d50c3Schristos   // regular relocatoins and the TLS_DESC relocations.
237ed0d50c3Schristos   Reloc_section* irelative_rel_;
238ed0d50c3Schristos   // The .got.plt section.
239ed0d50c3Schristos   Output_data_got_plt_i386* got_plt_;
240ed0d50c3Schristos   // The part of the .got.plt section used for IRELATIVE relocs.
241ed0d50c3Schristos   Output_data_space* got_irelative_;
242ed0d50c3Schristos   // The number of PLT entries.
243ed0d50c3Schristos   unsigned int count_;
244ed0d50c3Schristos   // Number of PLT entries with R_386_IRELATIVE relocs.  These follow
245ed0d50c3Schristos   // the regular PLT entries.
246ed0d50c3Schristos   unsigned int irelative_count_;
247ed0d50c3Schristos   // Global STT_GNU_IFUNC symbols.
248ed0d50c3Schristos   std::vector<Global_ifunc> global_ifuncs_;
249ed0d50c3Schristos   // Local STT_GNU_IFUNC symbols.
250ed0d50c3Schristos   std::vector<Local_ifunc> local_ifuncs_;
251ed0d50c3Schristos };
252ed0d50c3Schristos 
253ed0d50c3Schristos // This is an abstract class for the standard PLT layout.
254ed0d50c3Schristos // The derived classes below handle the actual PLT contents
255ed0d50c3Schristos // for the executable (non-PIC) and shared-library (PIC) cases.
256ed0d50c3Schristos // The unwind information is uniform across those two, so it's here.
257ed0d50c3Schristos 
258ed0d50c3Schristos class Output_data_plt_i386_standard : public Output_data_plt_i386
259ed0d50c3Schristos {
260ed0d50c3Schristos  public:
Output_data_plt_i386_standard(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative)261ed0d50c3Schristos   Output_data_plt_i386_standard(Layout* layout,
262ed0d50c3Schristos 				Output_data_got_plt_i386* got_plt,
263ed0d50c3Schristos 				Output_data_space* got_irelative)
264ed0d50c3Schristos     : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
265ed0d50c3Schristos   { }
266ed0d50c3Schristos 
267ed0d50c3Schristos  protected:
268ed0d50c3Schristos   virtual unsigned int
do_get_plt_entry_size() const269ed0d50c3Schristos   do_get_plt_entry_size() const
270ed0d50c3Schristos   { return plt_entry_size; }
271ed0d50c3Schristos 
272ed0d50c3Schristos   virtual void
do_add_eh_frame(Layout * layout)273ed0d50c3Schristos   do_add_eh_frame(Layout* layout)
274ed0d50c3Schristos   {
275ed0d50c3Schristos     layout->add_eh_frame_for_plt(this, plt_eh_frame_cie, plt_eh_frame_cie_size,
276ed0d50c3Schristos 				 plt_eh_frame_fde, plt_eh_frame_fde_size);
277ed0d50c3Schristos   }
278ed0d50c3Schristos 
279ed0d50c3Schristos   // The size of an entry in the PLT.
280ed0d50c3Schristos   static const int plt_entry_size = 16;
281ed0d50c3Schristos 
282ed0d50c3Schristos   // The .eh_frame unwind information for the PLT.
283ed0d50c3Schristos   static const int plt_eh_frame_fde_size = 32;
284ed0d50c3Schristos   static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size];
285ed0d50c3Schristos };
286ed0d50c3Schristos 
287ed0d50c3Schristos // Actually fill the PLT contents for an executable (non-PIC).
288ed0d50c3Schristos 
289ed0d50c3Schristos class Output_data_plt_i386_exec : public Output_data_plt_i386_standard
290ed0d50c3Schristos {
291ed0d50c3Schristos public:
Output_data_plt_i386_exec(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative)292ed0d50c3Schristos   Output_data_plt_i386_exec(Layout* layout,
293ed0d50c3Schristos 			    Output_data_got_plt_i386* got_plt,
294ed0d50c3Schristos 			    Output_data_space* got_irelative)
295ed0d50c3Schristos     : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
296ed0d50c3Schristos   { }
297ed0d50c3Schristos 
298ed0d50c3Schristos  protected:
299ed0d50c3Schristos   virtual void
300ed0d50c3Schristos   do_fill_first_plt_entry(unsigned char* pov,
301ed0d50c3Schristos 			  elfcpp::Elf_types<32>::Elf_Addr got_address);
302ed0d50c3Schristos 
303ed0d50c3Schristos   virtual unsigned int
304ed0d50c3Schristos   do_fill_plt_entry(unsigned char* pov,
305ed0d50c3Schristos 		    elfcpp::Elf_types<32>::Elf_Addr got_address,
306ed0d50c3Schristos 		    unsigned int got_offset,
307ed0d50c3Schristos 		    unsigned int plt_offset,
308ed0d50c3Schristos 		    unsigned int plt_rel_offset);
309ed0d50c3Schristos 
310ed0d50c3Schristos  private:
311ed0d50c3Schristos   // The first entry in the PLT for an executable.
312ed0d50c3Schristos   static const unsigned char first_plt_entry[plt_entry_size];
313ed0d50c3Schristos 
314ed0d50c3Schristos   // Other entries in the PLT for an executable.
315ed0d50c3Schristos   static const unsigned char plt_entry[plt_entry_size];
316ed0d50c3Schristos };
317ed0d50c3Schristos 
318ed0d50c3Schristos // Actually fill the PLT contents for a shared library (PIC).
319ed0d50c3Schristos 
320ed0d50c3Schristos class Output_data_plt_i386_dyn : public Output_data_plt_i386_standard
321ed0d50c3Schristos {
322ed0d50c3Schristos  public:
Output_data_plt_i386_dyn(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative)323ed0d50c3Schristos   Output_data_plt_i386_dyn(Layout* layout,
324ed0d50c3Schristos 			   Output_data_got_plt_i386* got_plt,
325ed0d50c3Schristos 			   Output_data_space* got_irelative)
326ed0d50c3Schristos     : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
327ed0d50c3Schristos   { }
328ed0d50c3Schristos 
329ed0d50c3Schristos  protected:
330ed0d50c3Schristos   virtual void
331ed0d50c3Schristos   do_fill_first_plt_entry(unsigned char* pov, elfcpp::Elf_types<32>::Elf_Addr);
332ed0d50c3Schristos 
333ed0d50c3Schristos   virtual unsigned int
334ed0d50c3Schristos   do_fill_plt_entry(unsigned char* pov,
335ed0d50c3Schristos 		    elfcpp::Elf_types<32>::Elf_Addr,
336ed0d50c3Schristos 		    unsigned int got_offset,
337ed0d50c3Schristos 		    unsigned int plt_offset,
338ed0d50c3Schristos 		    unsigned int plt_rel_offset);
339ed0d50c3Schristos 
340ed0d50c3Schristos  private:
341ed0d50c3Schristos   // The first entry in the PLT for a shared object.
342ed0d50c3Schristos   static const unsigned char first_plt_entry[plt_entry_size];
343ed0d50c3Schristos 
344ed0d50c3Schristos   // Other entries in the PLT for a shared object.
345ed0d50c3Schristos   static const unsigned char plt_entry[plt_entry_size];
346ed0d50c3Schristos };
347ed0d50c3Schristos 
348ed0d50c3Schristos // The i386 target class.
349ed0d50c3Schristos // TLS info comes from
350ed0d50c3Schristos //   http://people.redhat.com/drepper/tls.pdf
351ed0d50c3Schristos //   http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt
352ed0d50c3Schristos 
353ed0d50c3Schristos class Target_i386 : public Sized_target<32, false>
354ed0d50c3Schristos {
355ed0d50c3Schristos  public:
356ed0d50c3Schristos   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
357ed0d50c3Schristos 
Target_i386(const Target::Target_info * info=& i386_info)358ed0d50c3Schristos   Target_i386(const Target::Target_info* info = &i386_info)
359ed0d50c3Schristos     : Sized_target<32, false>(info),
360ed0d50c3Schristos       got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
361ed0d50c3Schristos       got_tlsdesc_(NULL), global_offset_table_(NULL), rel_dyn_(NULL),
362ed0d50c3Schristos       rel_irelative_(NULL), copy_relocs_(elfcpp::R_386_COPY),
363ed0d50c3Schristos       got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
364ed0d50c3Schristos   { }
365ed0d50c3Schristos 
366ed0d50c3Schristos   // Process the relocations to determine unreferenced sections for
367ed0d50c3Schristos   // garbage collection.
368ed0d50c3Schristos   void
369ed0d50c3Schristos   gc_process_relocs(Symbol_table* symtab,
370ed0d50c3Schristos 		    Layout* layout,
371ed0d50c3Schristos 		    Sized_relobj_file<32, false>* object,
372ed0d50c3Schristos 		    unsigned int data_shndx,
373ed0d50c3Schristos 		    unsigned int sh_type,
374ed0d50c3Schristos 		    const unsigned char* prelocs,
375ed0d50c3Schristos 		    size_t reloc_count,
376ed0d50c3Schristos 		    Output_section* output_section,
377ed0d50c3Schristos 		    bool needs_special_offset_handling,
378ed0d50c3Schristos 		    size_t local_symbol_count,
379ed0d50c3Schristos 		    const unsigned char* plocal_symbols);
380ed0d50c3Schristos 
381ed0d50c3Schristos   // Scan the relocations to look for symbol adjustments.
382ed0d50c3Schristos   void
383ed0d50c3Schristos   scan_relocs(Symbol_table* symtab,
384ed0d50c3Schristos 	      Layout* layout,
385ed0d50c3Schristos 	      Sized_relobj_file<32, false>* object,
386ed0d50c3Schristos 	      unsigned int data_shndx,
387ed0d50c3Schristos 	      unsigned int sh_type,
388ed0d50c3Schristos 	      const unsigned char* prelocs,
389ed0d50c3Schristos 	      size_t reloc_count,
390ed0d50c3Schristos 	      Output_section* output_section,
391ed0d50c3Schristos 	      bool needs_special_offset_handling,
392ed0d50c3Schristos 	      size_t local_symbol_count,
393ed0d50c3Schristos 	      const unsigned char* plocal_symbols);
394ed0d50c3Schristos 
395ed0d50c3Schristos   // Finalize the sections.
396ed0d50c3Schristos   void
397ed0d50c3Schristos   do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
398ed0d50c3Schristos 
399ed0d50c3Schristos   // Return the value to use for a dynamic which requires special
400ed0d50c3Schristos   // treatment.
401ed0d50c3Schristos   uint64_t
402ed0d50c3Schristos   do_dynsym_value(const Symbol*) const;
403ed0d50c3Schristos 
404ed0d50c3Schristos   // Relocate a section.
405ed0d50c3Schristos   void
406ed0d50c3Schristos   relocate_section(const Relocate_info<32, false>*,
407ed0d50c3Schristos 		   unsigned int sh_type,
408ed0d50c3Schristos 		   const unsigned char* prelocs,
409ed0d50c3Schristos 		   size_t reloc_count,
410ed0d50c3Schristos 		   Output_section* output_section,
411ed0d50c3Schristos 		   bool needs_special_offset_handling,
412ed0d50c3Schristos 		   unsigned char* view,
413ed0d50c3Schristos 		   elfcpp::Elf_types<32>::Elf_Addr view_address,
414ed0d50c3Schristos 		   section_size_type view_size,
415ed0d50c3Schristos 		   const Reloc_symbol_changes*);
416ed0d50c3Schristos 
417ed0d50c3Schristos   // Scan the relocs during a relocatable link.
418ed0d50c3Schristos   void
419ed0d50c3Schristos   scan_relocatable_relocs(Symbol_table* symtab,
420ed0d50c3Schristos 			  Layout* layout,
421ed0d50c3Schristos 			  Sized_relobj_file<32, false>* object,
422ed0d50c3Schristos 			  unsigned int data_shndx,
423ed0d50c3Schristos 			  unsigned int sh_type,
424ed0d50c3Schristos 			  const unsigned char* prelocs,
425ed0d50c3Schristos 			  size_t reloc_count,
426ed0d50c3Schristos 			  Output_section* output_section,
427ed0d50c3Schristos 			  bool needs_special_offset_handling,
428ed0d50c3Schristos 			  size_t local_symbol_count,
429ed0d50c3Schristos 			  const unsigned char* plocal_symbols,
430ed0d50c3Schristos 			  Relocatable_relocs*);
431ed0d50c3Schristos 
432ed0d50c3Schristos   // Scan the relocs for --emit-relocs.
433ed0d50c3Schristos   void
434ed0d50c3Schristos   emit_relocs_scan(Symbol_table* symtab,
435ed0d50c3Schristos 		   Layout* layout,
436ed0d50c3Schristos 		   Sized_relobj_file<32, false>* object,
437ed0d50c3Schristos 		   unsigned int data_shndx,
438ed0d50c3Schristos 		   unsigned int sh_type,
439ed0d50c3Schristos 		   const unsigned char* prelocs,
440ed0d50c3Schristos 		   size_t reloc_count,
441ed0d50c3Schristos 		   Output_section* output_section,
442ed0d50c3Schristos 		   bool needs_special_offset_handling,
443ed0d50c3Schristos 		   size_t local_symbol_count,
444ed0d50c3Schristos 		   const unsigned char* plocal_syms,
445ed0d50c3Schristos 		   Relocatable_relocs* rr);
446ed0d50c3Schristos 
447ed0d50c3Schristos   // Emit relocations for a section.
448ed0d50c3Schristos   void
449ed0d50c3Schristos   relocate_relocs(const Relocate_info<32, false>*,
450ed0d50c3Schristos 		  unsigned int sh_type,
451ed0d50c3Schristos 		  const unsigned char* prelocs,
452ed0d50c3Schristos 		  size_t reloc_count,
453ed0d50c3Schristos 		  Output_section* output_section,
454ed0d50c3Schristos 		  elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
455ed0d50c3Schristos 		  unsigned char* view,
456ed0d50c3Schristos 		  elfcpp::Elf_types<32>::Elf_Addr view_address,
457ed0d50c3Schristos 		  section_size_type view_size,
458ed0d50c3Schristos 		  unsigned char* reloc_view,
459ed0d50c3Schristos 		  section_size_type reloc_view_size);
460ed0d50c3Schristos 
461ed0d50c3Schristos   // Return a string used to fill a code section with nops.
462ed0d50c3Schristos   std::string
463ed0d50c3Schristos   do_code_fill(section_size_type length) const;
464ed0d50c3Schristos 
465ed0d50c3Schristos   // Return whether SYM is defined by the ABI.
466ed0d50c3Schristos   bool
do_is_defined_by_abi(const Symbol * sym) const467ed0d50c3Schristos   do_is_defined_by_abi(const Symbol* sym) const
468ed0d50c3Schristos   { return strcmp(sym->name(), "___tls_get_addr") == 0; }
469ed0d50c3Schristos 
470ed0d50c3Schristos   // Return whether a symbol name implies a local label.  The UnixWare
471ed0d50c3Schristos   // 2.1 cc generates temporary symbols that start with .X, so we
472ed0d50c3Schristos   // recognize them here.  FIXME: do other SVR4 compilers also use .X?.
473ed0d50c3Schristos   // If so, we should move the .X recognition into
474ed0d50c3Schristos   // Target::do_is_local_label_name.
475ed0d50c3Schristos   bool
do_is_local_label_name(const char * name) const476ed0d50c3Schristos   do_is_local_label_name(const char* name) const
477ed0d50c3Schristos   {
478ed0d50c3Schristos     if (name[0] == '.' && name[1] == 'X')
479ed0d50c3Schristos       return true;
480ed0d50c3Schristos     return Target::do_is_local_label_name(name);
481ed0d50c3Schristos   }
482ed0d50c3Schristos 
483ed0d50c3Schristos   // Return the PLT address to use for a global symbol.
484ed0d50c3Schristos   uint64_t
do_plt_address_for_global(const Symbol * gsym) const485ed0d50c3Schristos   do_plt_address_for_global(const Symbol* gsym) const
486ed0d50c3Schristos   { return this->plt_section()->address_for_global(gsym); }
487ed0d50c3Schristos 
488ed0d50c3Schristos   uint64_t
do_plt_address_for_local(const Relobj * relobj,unsigned int symndx) const489ed0d50c3Schristos   do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
490ed0d50c3Schristos   { return this->plt_section()->address_for_local(relobj, symndx); }
491ed0d50c3Schristos 
492ed0d50c3Schristos   // We can tell whether we take the address of a function.
493ed0d50c3Schristos   inline bool
do_can_check_for_function_pointers() const494ed0d50c3Schristos   do_can_check_for_function_pointers() const
495ed0d50c3Schristos   { return true; }
496ed0d50c3Schristos 
497ed0d50c3Schristos   // Return the base for a DW_EH_PE_datarel encoding.
498ed0d50c3Schristos   uint64_t
499ed0d50c3Schristos   do_ehframe_datarel_base() const;
500ed0d50c3Schristos 
501ed0d50c3Schristos   // Return whether SYM is call to a non-split function.
502ed0d50c3Schristos   bool
503ed0d50c3Schristos   do_is_call_to_non_split(const Symbol* sym, const unsigned char*,
504ed0d50c3Schristos 			  const unsigned char*, section_size_type) const;
505ed0d50c3Schristos 
506ed0d50c3Schristos   // Adjust -fsplit-stack code which calls non-split-stack code.
507ed0d50c3Schristos   void
508ed0d50c3Schristos   do_calls_non_split(Relobj* object, unsigned int shndx,
509ed0d50c3Schristos 		     section_offset_type fnoffset, section_size_type fnsize,
510ed0d50c3Schristos 		     const unsigned char* prelocs, size_t reloc_count,
511ed0d50c3Schristos 		     unsigned char* view, section_size_type view_size,
512ed0d50c3Schristos 		     std::string* from, std::string* to) const;
513ed0d50c3Schristos 
514ed0d50c3Schristos   // Return the size of the GOT section.
515ed0d50c3Schristos   section_size_type
got_size() const516ed0d50c3Schristos   got_size() const
517ed0d50c3Schristos   {
518ed0d50c3Schristos     gold_assert(this->got_ != NULL);
519ed0d50c3Schristos     return this->got_->data_size();
520ed0d50c3Schristos   }
521ed0d50c3Schristos 
522ed0d50c3Schristos   // Return the number of entries in the GOT.
523ed0d50c3Schristos   unsigned int
got_entry_count() const524ed0d50c3Schristos   got_entry_count() const
525ed0d50c3Schristos   {
526ed0d50c3Schristos     if (this->got_ == NULL)
527ed0d50c3Schristos       return 0;
528ed0d50c3Schristos     return this->got_size() / 4;
529ed0d50c3Schristos   }
530ed0d50c3Schristos 
531ed0d50c3Schristos   // Return the number of entries in the PLT.
532ed0d50c3Schristos   unsigned int
533ed0d50c3Schristos   plt_entry_count() const;
534ed0d50c3Schristos 
535ed0d50c3Schristos   // Return the offset of the first non-reserved PLT entry.
536ed0d50c3Schristos   unsigned int
537ed0d50c3Schristos   first_plt_entry_offset() const;
538ed0d50c3Schristos 
539ed0d50c3Schristos   // Return the size of each PLT entry.
540ed0d50c3Schristos   unsigned int
541ed0d50c3Schristos   plt_entry_size() const;
542ed0d50c3Schristos 
543ed0d50c3Schristos  protected:
544ed0d50c3Schristos   // Instantiate the plt_ member.
545ed0d50c3Schristos   // This chooses the right PLT flavor for an executable or a shared object.
546ed0d50c3Schristos   Output_data_plt_i386*
make_data_plt(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative,bool dyn)547ed0d50c3Schristos   make_data_plt(Layout* layout,
548ed0d50c3Schristos 		Output_data_got_plt_i386* got_plt,
549ed0d50c3Schristos 		Output_data_space* got_irelative,
550ed0d50c3Schristos 		bool dyn)
551ed0d50c3Schristos   { return this->do_make_data_plt(layout, got_plt, got_irelative, dyn); }
552ed0d50c3Schristos 
553ed0d50c3Schristos   virtual Output_data_plt_i386*
do_make_data_plt(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative,bool dyn)554ed0d50c3Schristos   do_make_data_plt(Layout* layout,
555ed0d50c3Schristos 		   Output_data_got_plt_i386* got_plt,
556ed0d50c3Schristos 		   Output_data_space* got_irelative,
557ed0d50c3Schristos 		   bool dyn)
558ed0d50c3Schristos   {
559ed0d50c3Schristos     if (dyn)
560ed0d50c3Schristos       return new Output_data_plt_i386_dyn(layout, got_plt, got_irelative);
561ed0d50c3Schristos     else
562ed0d50c3Schristos       return new Output_data_plt_i386_exec(layout, got_plt, got_irelative);
563ed0d50c3Schristos   }
564ed0d50c3Schristos 
565ed0d50c3Schristos  private:
566ed0d50c3Schristos   // The class which scans relocations.
567ed0d50c3Schristos   struct Scan
568ed0d50c3Schristos   {
569ed0d50c3Schristos     static inline int
570ed0d50c3Schristos 
571ed0d50c3Schristos     get_reference_flags(unsigned int r_type);
572ed0d50c3Schristos 
573ed0d50c3Schristos     inline void
574ed0d50c3Schristos     local(Symbol_table* symtab, Layout* layout, Target_i386* target,
575ed0d50c3Schristos 	  Sized_relobj_file<32, false>* object,
576ed0d50c3Schristos 	  unsigned int data_shndx,
577ed0d50c3Schristos 	  Output_section* output_section,
578ed0d50c3Schristos 	  const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
579ed0d50c3Schristos 	  const elfcpp::Sym<32, false>& lsym,
580ed0d50c3Schristos 	  bool is_discarded);
581ed0d50c3Schristos 
582ed0d50c3Schristos     inline void
583ed0d50c3Schristos     global(Symbol_table* symtab, Layout* layout, Target_i386* target,
584ed0d50c3Schristos 	   Sized_relobj_file<32, false>* object,
585ed0d50c3Schristos 	   unsigned int data_shndx,
586ed0d50c3Schristos 	   Output_section* output_section,
587ed0d50c3Schristos 	   const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
588ed0d50c3Schristos 	   Symbol* gsym);
589ed0d50c3Schristos 
590ed0d50c3Schristos     inline bool
591ed0d50c3Schristos     local_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
592ed0d50c3Schristos 					Target_i386* target,
593ed0d50c3Schristos 					Sized_relobj_file<32, false>* object,
594ed0d50c3Schristos 					unsigned int data_shndx,
595ed0d50c3Schristos 					Output_section* output_section,
596ed0d50c3Schristos 					const elfcpp::Rel<32, false>& reloc,
597ed0d50c3Schristos 					unsigned int r_type,
598ed0d50c3Schristos 					const elfcpp::Sym<32, false>& lsym);
599ed0d50c3Schristos 
600ed0d50c3Schristos     inline bool
601ed0d50c3Schristos     global_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
602ed0d50c3Schristos 					 Target_i386* target,
603ed0d50c3Schristos 					 Sized_relobj_file<32, false>* object,
604ed0d50c3Schristos 					 unsigned int data_shndx,
605ed0d50c3Schristos 					 Output_section* output_section,
606ed0d50c3Schristos 					 const elfcpp::Rel<32, false>& reloc,
607ed0d50c3Schristos 					 unsigned int r_type,
608ed0d50c3Schristos 					 Symbol* gsym);
609ed0d50c3Schristos 
610ed0d50c3Schristos     inline bool
611ed0d50c3Schristos     possible_function_pointer_reloc(unsigned int r_type);
612ed0d50c3Schristos 
613ed0d50c3Schristos     bool
614ed0d50c3Schristos     reloc_needs_plt_for_ifunc(Sized_relobj_file<32, false>*,
615ed0d50c3Schristos 			      unsigned int r_type);
616ed0d50c3Schristos 
617ed0d50c3Schristos     static void
618ed0d50c3Schristos     unsupported_reloc_local(Sized_relobj_file<32, false>*, unsigned int r_type);
619ed0d50c3Schristos 
620ed0d50c3Schristos     static void
621ed0d50c3Schristos     unsupported_reloc_global(Sized_relobj_file<32, false>*, unsigned int r_type,
622ed0d50c3Schristos 			     Symbol*);
623ed0d50c3Schristos   };
624ed0d50c3Schristos 
625ed0d50c3Schristos   // The class which implements relocation.
626ed0d50c3Schristos   class Relocate
627ed0d50c3Schristos   {
628ed0d50c3Schristos    public:
Relocate()629ed0d50c3Schristos     Relocate()
630ed0d50c3Schristos       : skip_call_tls_get_addr_(false),
631ed0d50c3Schristos 	local_dynamic_type_(LOCAL_DYNAMIC_NONE)
632ed0d50c3Schristos     { }
633ed0d50c3Schristos 
~Relocate()634ed0d50c3Schristos     ~Relocate()
635ed0d50c3Schristos     {
636ed0d50c3Schristos       if (this->skip_call_tls_get_addr_)
637ed0d50c3Schristos 	{
638ed0d50c3Schristos 	  // FIXME: This needs to specify the location somehow.
639ed0d50c3Schristos 	  gold_error(_("missing expected TLS relocation"));
640ed0d50c3Schristos 	}
641ed0d50c3Schristos     }
642ed0d50c3Schristos 
643ed0d50c3Schristos     // Return whether the static relocation needs to be applied.
644ed0d50c3Schristos     inline bool
645ed0d50c3Schristos     should_apply_static_reloc(const Sized_symbol<32>* gsym,
646ed0d50c3Schristos 			      unsigned int r_type,
647ed0d50c3Schristos 			      bool is_32bit,
648ed0d50c3Schristos 			      Output_section* output_section);
649ed0d50c3Schristos 
650ed0d50c3Schristos     // Do a relocation.  Return false if the caller should not issue
651ed0d50c3Schristos     // any warnings about this relocation.
652ed0d50c3Schristos     inline bool
653ed0d50c3Schristos     relocate(const Relocate_info<32, false>*, unsigned int,
654ed0d50c3Schristos 	     Target_i386*, Output_section*, size_t, const unsigned char*,
655ed0d50c3Schristos 	     const Sized_symbol<32>*, const Symbol_value<32>*,
656ed0d50c3Schristos 	     unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
657ed0d50c3Schristos 	     section_size_type);
658ed0d50c3Schristos 
659ed0d50c3Schristos    private:
660ed0d50c3Schristos     // Do a TLS relocation.
661ed0d50c3Schristos     inline void
662ed0d50c3Schristos     relocate_tls(const Relocate_info<32, false>*, Target_i386* target,
663ed0d50c3Schristos 		 size_t relnum, const elfcpp::Rel<32, false>&,
664ed0d50c3Schristos 		 unsigned int r_type, const Sized_symbol<32>*,
665ed0d50c3Schristos 		 const Symbol_value<32>*,
666ed0d50c3Schristos 		 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
667ed0d50c3Schristos 		 section_size_type);
668ed0d50c3Schristos 
669ed0d50c3Schristos     // Do a TLS General-Dynamic to Initial-Exec transition.
670ed0d50c3Schristos     inline void
671ed0d50c3Schristos     tls_gd_to_ie(const Relocate_info<32, false>*, size_t relnum,
672ed0d50c3Schristos 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
673ed0d50c3Schristos 		 elfcpp::Elf_types<32>::Elf_Addr value,
674ed0d50c3Schristos 		 unsigned char* view,
675ed0d50c3Schristos 		 section_size_type view_size);
676ed0d50c3Schristos 
677ed0d50c3Schristos     // Do a TLS General-Dynamic to Local-Exec transition.
678ed0d50c3Schristos     inline void
679ed0d50c3Schristos     tls_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
680ed0d50c3Schristos 		 Output_segment* tls_segment,
681ed0d50c3Schristos 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
682ed0d50c3Schristos 		 elfcpp::Elf_types<32>::Elf_Addr value,
683ed0d50c3Schristos 		 unsigned char* view,
684ed0d50c3Schristos 		 section_size_type view_size);
685ed0d50c3Schristos 
686ed0d50c3Schristos     // Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Initial-Exec
687ed0d50c3Schristos     // transition.
688ed0d50c3Schristos     inline void
689ed0d50c3Schristos     tls_desc_gd_to_ie(const Relocate_info<32, false>*, size_t relnum,
690ed0d50c3Schristos 		      const elfcpp::Rel<32, false>&, unsigned int r_type,
691ed0d50c3Schristos 		      elfcpp::Elf_types<32>::Elf_Addr value,
692ed0d50c3Schristos 		      unsigned char* view,
693ed0d50c3Schristos 		      section_size_type view_size);
694ed0d50c3Schristos 
695ed0d50c3Schristos     // Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Local-Exec
696ed0d50c3Schristos     // transition.
697ed0d50c3Schristos     inline void
698ed0d50c3Schristos     tls_desc_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
699ed0d50c3Schristos 		      Output_segment* tls_segment,
700ed0d50c3Schristos 		      const elfcpp::Rel<32, false>&, unsigned int r_type,
701ed0d50c3Schristos 		      elfcpp::Elf_types<32>::Elf_Addr value,
702ed0d50c3Schristos 		      unsigned char* view,
703ed0d50c3Schristos 		      section_size_type view_size);
704ed0d50c3Schristos 
705ed0d50c3Schristos     // Do a TLS Local-Dynamic to Local-Exec transition.
706ed0d50c3Schristos     inline void
707ed0d50c3Schristos     tls_ld_to_le(const Relocate_info<32, false>*, size_t relnum,
708ed0d50c3Schristos 		 Output_segment* tls_segment,
709ed0d50c3Schristos 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
710ed0d50c3Schristos 		 elfcpp::Elf_types<32>::Elf_Addr value,
711ed0d50c3Schristos 		 unsigned char* view,
712ed0d50c3Schristos 		 section_size_type view_size);
713ed0d50c3Schristos 
714ed0d50c3Schristos     // Do a TLS Initial-Exec to Local-Exec transition.
715ed0d50c3Schristos     static inline void
716ed0d50c3Schristos     tls_ie_to_le(const Relocate_info<32, false>*, size_t relnum,
717ed0d50c3Schristos 		 Output_segment* tls_segment,
718ed0d50c3Schristos 		 const elfcpp::Rel<32, false>&, unsigned int r_type,
719ed0d50c3Schristos 		 elfcpp::Elf_types<32>::Elf_Addr value,
720ed0d50c3Schristos 		 unsigned char* view,
721ed0d50c3Schristos 		 section_size_type view_size);
722ed0d50c3Schristos 
723ed0d50c3Schristos     // We need to keep track of which type of local dynamic relocation
724ed0d50c3Schristos     // we have seen, so that we can optimize R_386_TLS_LDO_32 correctly.
725ed0d50c3Schristos     enum Local_dynamic_type
726ed0d50c3Schristos     {
727ed0d50c3Schristos       LOCAL_DYNAMIC_NONE,
728ed0d50c3Schristos       LOCAL_DYNAMIC_SUN,
729ed0d50c3Schristos       LOCAL_DYNAMIC_GNU
730ed0d50c3Schristos     };
731ed0d50c3Schristos 
732ed0d50c3Schristos     // This is set if we should skip the next reloc, which should be a
733ed0d50c3Schristos     // PLT32 reloc against ___tls_get_addr.
734ed0d50c3Schristos     bool skip_call_tls_get_addr_;
735ed0d50c3Schristos     // The type of local dynamic relocation we have seen in the section
736ed0d50c3Schristos     // being relocated, if any.
737ed0d50c3Schristos     Local_dynamic_type local_dynamic_type_;
738ed0d50c3Schristos   };
739ed0d50c3Schristos 
740ed0d50c3Schristos   // A class for inquiring about properties of a relocation,
741ed0d50c3Schristos   // used while scanning relocs during a relocatable link and
742ed0d50c3Schristos   // garbage collection.
743ed0d50c3Schristos   class Classify_reloc :
744ed0d50c3Schristos       public gold::Default_classify_reloc<elfcpp::SHT_REL, 32, false>
745ed0d50c3Schristos   {
746ed0d50c3Schristos    public:
747ed0d50c3Schristos     typedef Reloc_types<elfcpp::SHT_REL, 32, false>::Reloc Reltype;
748ed0d50c3Schristos 
749ed0d50c3Schristos     // Return the explicit addend of the relocation (return 0 for SHT_REL).
750ed0d50c3Schristos     static elfcpp::Elf_types<32>::Elf_Swxword
get_r_addend(const Reltype *)751ed0d50c3Schristos     get_r_addend(const Reltype*)
752ed0d50c3Schristos     { return 0; }
753ed0d50c3Schristos 
754ed0d50c3Schristos     // Return the size of the addend of the relocation (only used for SHT_REL).
755ed0d50c3Schristos     static unsigned int
756ed0d50c3Schristos     get_size_for_reloc(unsigned int, Relobj*);
757ed0d50c3Schristos   };
758ed0d50c3Schristos 
759ed0d50c3Schristos   // Adjust TLS relocation type based on the options and whether this
760ed0d50c3Schristos   // is a local symbol.
761ed0d50c3Schristos   static tls::Tls_optimization
762ed0d50c3Schristos   optimize_tls_reloc(bool is_final, int r_type);
763ed0d50c3Schristos 
764ed0d50c3Schristos   // Check if relocation against this symbol is a candidate for
765ed0d50c3Schristos   // conversion from
766ed0d50c3Schristos   // mov foo@GOT(%reg), %reg
767ed0d50c3Schristos   // to
768ed0d50c3Schristos   // lea foo@GOTOFF(%reg), %reg.
769ed0d50c3Schristos   static bool
can_convert_mov_to_lea(const Symbol * gsym)770ed0d50c3Schristos   can_convert_mov_to_lea(const Symbol* gsym)
771ed0d50c3Schristos   {
772ed0d50c3Schristos     gold_assert(gsym != NULL);
773ed0d50c3Schristos     return (gsym->type() != elfcpp::STT_GNU_IFUNC
774ed0d50c3Schristos 	    && !gsym->is_undefined ()
775ed0d50c3Schristos 	    && !gsym->is_from_dynobj()
776ed0d50c3Schristos 	    && !gsym->is_preemptible()
777ed0d50c3Schristos 	    && (!parameters->options().shared()
778ed0d50c3Schristos 		|| (gsym->visibility() != elfcpp::STV_DEFAULT
779ed0d50c3Schristos 		    && gsym->visibility() != elfcpp::STV_PROTECTED)
780ed0d50c3Schristos 		|| parameters->options().Bsymbolic())
781ed0d50c3Schristos 	    && strcmp(gsym->name(), "_DYNAMIC") != 0);
782ed0d50c3Schristos   }
783ed0d50c3Schristos 
784ed0d50c3Schristos   // Get the GOT section, creating it if necessary.
785ed0d50c3Schristos   Output_data_got<32, false>*
786ed0d50c3Schristos   got_section(Symbol_table*, Layout*);
787ed0d50c3Schristos 
788ed0d50c3Schristos   // Get the GOT PLT section.
789ed0d50c3Schristos   Output_data_got_plt_i386*
got_plt_section() const790ed0d50c3Schristos   got_plt_section() const
791ed0d50c3Schristos   {
792ed0d50c3Schristos     gold_assert(this->got_plt_ != NULL);
793ed0d50c3Schristos     return this->got_plt_;
794ed0d50c3Schristos   }
795ed0d50c3Schristos 
796ed0d50c3Schristos   // Get the GOT section for TLSDESC entries.
797ed0d50c3Schristos   Output_data_got<32, false>*
got_tlsdesc_section() const798ed0d50c3Schristos   got_tlsdesc_section() const
799ed0d50c3Schristos   {
800ed0d50c3Schristos     gold_assert(this->got_tlsdesc_ != NULL);
801ed0d50c3Schristos     return this->got_tlsdesc_;
802ed0d50c3Schristos   }
803ed0d50c3Schristos 
804ed0d50c3Schristos   // Create the PLT section.
805ed0d50c3Schristos   void
806ed0d50c3Schristos   make_plt_section(Symbol_table* symtab, Layout* layout);
807ed0d50c3Schristos 
808ed0d50c3Schristos   // Create a PLT entry for a global symbol.
809ed0d50c3Schristos   void
810ed0d50c3Schristos   make_plt_entry(Symbol_table*, Layout*, Symbol*);
811ed0d50c3Schristos 
812ed0d50c3Schristos   // Create a PLT entry for a local STT_GNU_IFUNC symbol.
813ed0d50c3Schristos   void
814ed0d50c3Schristos   make_local_ifunc_plt_entry(Symbol_table*, Layout*,
815ed0d50c3Schristos 			     Sized_relobj_file<32, false>* relobj,
816ed0d50c3Schristos 			     unsigned int local_sym_index);
817ed0d50c3Schristos 
818ed0d50c3Schristos   // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
819ed0d50c3Schristos   void
820ed0d50c3Schristos   define_tls_base_symbol(Symbol_table*, Layout*);
821ed0d50c3Schristos 
822ed0d50c3Schristos   // Create a GOT entry for the TLS module index.
823ed0d50c3Schristos   unsigned int
824ed0d50c3Schristos   got_mod_index_entry(Symbol_table* symtab, Layout* layout,
825ed0d50c3Schristos 		      Sized_relobj_file<32, false>* object);
826ed0d50c3Schristos 
827ed0d50c3Schristos   // Get the PLT section.
828ed0d50c3Schristos   Output_data_plt_i386*
plt_section() const829ed0d50c3Schristos   plt_section() const
830ed0d50c3Schristos   {
831ed0d50c3Schristos     gold_assert(this->plt_ != NULL);
832ed0d50c3Schristos     return this->plt_;
833ed0d50c3Schristos   }
834ed0d50c3Schristos 
835ed0d50c3Schristos   // Get the dynamic reloc section, creating it if necessary.
836ed0d50c3Schristos   Reloc_section*
837ed0d50c3Schristos   rel_dyn_section(Layout*);
838ed0d50c3Schristos 
839ed0d50c3Schristos   // Get the section to use for TLS_DESC relocations.
840ed0d50c3Schristos   Reloc_section*
841ed0d50c3Schristos   rel_tls_desc_section(Layout*) const;
842ed0d50c3Schristos 
843ed0d50c3Schristos   // Get the section to use for IRELATIVE relocations.
844ed0d50c3Schristos   Reloc_section*
845ed0d50c3Schristos   rel_irelative_section(Layout*);
846ed0d50c3Schristos 
847ed0d50c3Schristos   // Add a potential copy relocation.
848ed0d50c3Schristos   void
copy_reloc(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * object,unsigned int shndx,Output_section * output_section,Symbol * sym,const elfcpp::Rel<32,false> & reloc)849ed0d50c3Schristos   copy_reloc(Symbol_table* symtab, Layout* layout,
850ed0d50c3Schristos 	     Sized_relobj_file<32, false>* object,
851ed0d50c3Schristos 	     unsigned int shndx, Output_section* output_section,
852ed0d50c3Schristos 	     Symbol* sym, const elfcpp::Rel<32, false>& reloc)
853ed0d50c3Schristos   {
854ed0d50c3Schristos     unsigned int r_type = elfcpp::elf_r_type<32>(reloc.get_r_info());
855ed0d50c3Schristos     this->copy_relocs_.copy_reloc(symtab, layout,
856ed0d50c3Schristos 				  symtab->get_sized_symbol<32>(sym),
857ed0d50c3Schristos 				  object, shndx, output_section,
858ed0d50c3Schristos 				  r_type, reloc.get_r_offset(), 0,
859ed0d50c3Schristos 				  this->rel_dyn_section(layout));
860ed0d50c3Schristos   }
861ed0d50c3Schristos 
862ed0d50c3Schristos   // Information about this specific target which we pass to the
863ed0d50c3Schristos   // general Target structure.
864ed0d50c3Schristos   static const Target::Target_info i386_info;
865ed0d50c3Schristos 
866ed0d50c3Schristos   // The types of GOT entries needed for this platform.
867ed0d50c3Schristos   // These values are exposed to the ABI in an incremental link.
868ed0d50c3Schristos   // Do not renumber existing values without changing the version
869ed0d50c3Schristos   // number of the .gnu_incremental_inputs section.
870ed0d50c3Schristos   enum Got_type
871ed0d50c3Schristos   {
872ed0d50c3Schristos     GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
873ed0d50c3Schristos     GOT_TYPE_TLS_NOFFSET = 1,   // GOT entry for negative TLS offset
874ed0d50c3Schristos     GOT_TYPE_TLS_OFFSET = 2,    // GOT entry for positive TLS offset
875ed0d50c3Schristos     GOT_TYPE_TLS_PAIR = 3,      // GOT entry for TLS module/offset pair
876ed0d50c3Schristos     GOT_TYPE_TLS_DESC = 4       // GOT entry for TLS_DESC pair
877ed0d50c3Schristos   };
878ed0d50c3Schristos 
879ed0d50c3Schristos   // The GOT section.
880ed0d50c3Schristos   Output_data_got<32, false>* got_;
881ed0d50c3Schristos   // The PLT section.
882ed0d50c3Schristos   Output_data_plt_i386* plt_;
883ed0d50c3Schristos   // The GOT PLT section.
884ed0d50c3Schristos   Output_data_got_plt_i386* got_plt_;
885ed0d50c3Schristos   // The GOT section for IRELATIVE relocations.
886ed0d50c3Schristos   Output_data_space* got_irelative_;
887ed0d50c3Schristos   // The GOT section for TLSDESC relocations.
888ed0d50c3Schristos   Output_data_got<32, false>* got_tlsdesc_;
889ed0d50c3Schristos   // The _GLOBAL_OFFSET_TABLE_ symbol.
890ed0d50c3Schristos   Symbol* global_offset_table_;
891ed0d50c3Schristos   // The dynamic reloc section.
892ed0d50c3Schristos   Reloc_section* rel_dyn_;
893ed0d50c3Schristos   // The section to use for IRELATIVE relocs.
894ed0d50c3Schristos   Reloc_section* rel_irelative_;
895ed0d50c3Schristos   // Relocs saved to avoid a COPY reloc.
896ed0d50c3Schristos   Copy_relocs<elfcpp::SHT_REL, 32, false> copy_relocs_;
897ed0d50c3Schristos   // Offset of the GOT entry for the TLS module index.
898ed0d50c3Schristos   unsigned int got_mod_index_offset_;
899ed0d50c3Schristos   // True if the _TLS_MODULE_BASE_ symbol has been defined.
900ed0d50c3Schristos   bool tls_base_symbol_defined_;
901ed0d50c3Schristos };
902ed0d50c3Schristos 
903ed0d50c3Schristos const Target::Target_info Target_i386::i386_info =
904ed0d50c3Schristos {
905ed0d50c3Schristos   32,			// size
906ed0d50c3Schristos   false,		// is_big_endian
907ed0d50c3Schristos   elfcpp::EM_386,	// machine_code
908ed0d50c3Schristos   false,		// has_make_symbol
909ed0d50c3Schristos   false,		// has_resolve
910ed0d50c3Schristos   true,			// has_code_fill
911ed0d50c3Schristos   true,			// is_default_stack_executable
912ed0d50c3Schristos   true,			// can_icf_inline_merge_sections
913ed0d50c3Schristos   '\0',			// wrap_char
914ed0d50c3Schristos   "/usr/lib/libc.so.1",	// dynamic_linker
915ed0d50c3Schristos   0x08048000,		// default_text_segment_address
916ed0d50c3Schristos   0x1000,		// abi_pagesize (overridable by -z max-page-size)
917ed0d50c3Schristos   0x1000,		// common_pagesize (overridable by -z common-page-size)
918ed0d50c3Schristos   false,                // isolate_execinstr
919ed0d50c3Schristos   0,                    // rosegment_gap
920ed0d50c3Schristos   elfcpp::SHN_UNDEF,	// small_common_shndx
921ed0d50c3Schristos   elfcpp::SHN_UNDEF,	// large_common_shndx
922ed0d50c3Schristos   0,			// small_common_section_flags
923ed0d50c3Schristos   0,			// large_common_section_flags
924ed0d50c3Schristos   NULL,			// attributes_section
925ed0d50c3Schristos   NULL,			// attributes_vendor
926ed0d50c3Schristos   "_start",		// entry_symbol_name
927ed0d50c3Schristos   32,			// hash_entry_size
92806324dcfSchristos   elfcpp::SHT_PROGBITS,	// unwind_section_type
929ed0d50c3Schristos };
930ed0d50c3Schristos 
931ed0d50c3Schristos // Get the GOT section, creating it if necessary.
932ed0d50c3Schristos 
933ed0d50c3Schristos Output_data_got<32, false>*
got_section(Symbol_table * symtab,Layout * layout)934ed0d50c3Schristos Target_i386::got_section(Symbol_table* symtab, Layout* layout)
935ed0d50c3Schristos {
936ed0d50c3Schristos   if (this->got_ == NULL)
937ed0d50c3Schristos     {
938ed0d50c3Schristos       gold_assert(symtab != NULL && layout != NULL);
939ed0d50c3Schristos 
940ed0d50c3Schristos       this->got_ = new Output_data_got<32, false>();
941ed0d50c3Schristos 
942ed0d50c3Schristos       // When using -z now, we can treat .got.plt as a relro section.
943ed0d50c3Schristos       // Without -z now, it is modified after program startup by lazy
944ed0d50c3Schristos       // PLT relocations.
945ed0d50c3Schristos       bool is_got_plt_relro = parameters->options().now();
946ed0d50c3Schristos       Output_section_order got_order = (is_got_plt_relro
947ed0d50c3Schristos 					? ORDER_RELRO
948ed0d50c3Schristos 					: ORDER_RELRO_LAST);
949ed0d50c3Schristos       Output_section_order got_plt_order = (is_got_plt_relro
950ed0d50c3Schristos 					    ? ORDER_RELRO
951ed0d50c3Schristos 					    : ORDER_NON_RELRO_FIRST);
952ed0d50c3Schristos 
953ed0d50c3Schristos       layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
954ed0d50c3Schristos 				      (elfcpp::SHF_ALLOC
955ed0d50c3Schristos 				       | elfcpp::SHF_WRITE),
956ed0d50c3Schristos 				      this->got_, got_order, true);
957ed0d50c3Schristos 
958ed0d50c3Schristos       this->got_plt_ = new Output_data_got_plt_i386(layout);
959ed0d50c3Schristos       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
960ed0d50c3Schristos 				      (elfcpp::SHF_ALLOC
961ed0d50c3Schristos 				       | elfcpp::SHF_WRITE),
962ed0d50c3Schristos 				      this->got_plt_, got_plt_order,
963ed0d50c3Schristos 				      is_got_plt_relro);
964ed0d50c3Schristos 
965ed0d50c3Schristos       // The first three entries are reserved.
966ed0d50c3Schristos       this->got_plt_->set_current_data_size(3 * 4);
967ed0d50c3Schristos 
968ed0d50c3Schristos       if (!is_got_plt_relro)
969ed0d50c3Schristos 	{
970ed0d50c3Schristos 	  // Those bytes can go into the relro segment.
971ed0d50c3Schristos 	  layout->increase_relro(3 * 4);
972ed0d50c3Schristos 	}
973ed0d50c3Schristos 
974ed0d50c3Schristos       // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
975ed0d50c3Schristos       this->global_offset_table_ =
976ed0d50c3Schristos 	symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
977ed0d50c3Schristos 				      Symbol_table::PREDEFINED,
978ed0d50c3Schristos 				      this->got_plt_,
979ed0d50c3Schristos 				      0, 0, elfcpp::STT_OBJECT,
980ed0d50c3Schristos 				      elfcpp::STB_LOCAL,
981ed0d50c3Schristos 				      elfcpp::STV_HIDDEN, 0,
982ed0d50c3Schristos 				      false, false);
983ed0d50c3Schristos 
984ed0d50c3Schristos       // If there are any IRELATIVE relocations, they get GOT entries
985ed0d50c3Schristos       // in .got.plt after the jump slot relocations.
986ed0d50c3Schristos       this->got_irelative_ = new Output_data_space(4, "** GOT IRELATIVE PLT");
987ed0d50c3Schristos       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
988ed0d50c3Schristos 				      (elfcpp::SHF_ALLOC
989ed0d50c3Schristos 				       | elfcpp::SHF_WRITE),
990ed0d50c3Schristos 				      this->got_irelative_,
991ed0d50c3Schristos 				      got_plt_order, is_got_plt_relro);
992ed0d50c3Schristos 
993ed0d50c3Schristos       // If there are any TLSDESC relocations, they get GOT entries in
994ed0d50c3Schristos       // .got.plt after the jump slot entries.
995ed0d50c3Schristos       this->got_tlsdesc_ = new Output_data_got<32, false>();
996ed0d50c3Schristos       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
997ed0d50c3Schristos 				      (elfcpp::SHF_ALLOC
998ed0d50c3Schristos 				       | elfcpp::SHF_WRITE),
999ed0d50c3Schristos 				      this->got_tlsdesc_,
1000ed0d50c3Schristos 				      got_plt_order, is_got_plt_relro);
1001ed0d50c3Schristos     }
1002ed0d50c3Schristos 
1003ed0d50c3Schristos   return this->got_;
1004ed0d50c3Schristos }
1005ed0d50c3Schristos 
1006ed0d50c3Schristos // Get the dynamic reloc section, creating it if necessary.
1007ed0d50c3Schristos 
1008ed0d50c3Schristos Target_i386::Reloc_section*
rel_dyn_section(Layout * layout)1009ed0d50c3Schristos Target_i386::rel_dyn_section(Layout* layout)
1010ed0d50c3Schristos {
1011ed0d50c3Schristos   if (this->rel_dyn_ == NULL)
1012ed0d50c3Schristos     {
1013ed0d50c3Schristos       gold_assert(layout != NULL);
1014ed0d50c3Schristos       this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
1015ed0d50c3Schristos       layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
1016ed0d50c3Schristos 				      elfcpp::SHF_ALLOC, this->rel_dyn_,
1017ed0d50c3Schristos 				      ORDER_DYNAMIC_RELOCS, false);
1018ed0d50c3Schristos     }
1019ed0d50c3Schristos   return this->rel_dyn_;
1020ed0d50c3Schristos }
1021ed0d50c3Schristos 
1022ed0d50c3Schristos // Get the section to use for IRELATIVE relocs, creating it if
1023ed0d50c3Schristos // necessary.  These go in .rel.dyn, but only after all other dynamic
1024ed0d50c3Schristos // relocations.  They need to follow the other dynamic relocations so
1025ed0d50c3Schristos // that they can refer to global variables initialized by those
1026ed0d50c3Schristos // relocs.
1027ed0d50c3Schristos 
1028ed0d50c3Schristos Target_i386::Reloc_section*
rel_irelative_section(Layout * layout)1029ed0d50c3Schristos Target_i386::rel_irelative_section(Layout* layout)
1030ed0d50c3Schristos {
1031ed0d50c3Schristos   if (this->rel_irelative_ == NULL)
1032ed0d50c3Schristos     {
1033ed0d50c3Schristos       // Make sure we have already create the dynamic reloc section.
1034ed0d50c3Schristos       this->rel_dyn_section(layout);
1035ed0d50c3Schristos       this->rel_irelative_ = new Reloc_section(false);
1036ed0d50c3Schristos       layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
1037ed0d50c3Schristos 				      elfcpp::SHF_ALLOC, this->rel_irelative_,
1038ed0d50c3Schristos 				      ORDER_DYNAMIC_RELOCS, false);
1039ed0d50c3Schristos       gold_assert(this->rel_dyn_->output_section()
1040ed0d50c3Schristos 		  == this->rel_irelative_->output_section());
1041ed0d50c3Schristos     }
1042ed0d50c3Schristos   return this->rel_irelative_;
1043ed0d50c3Schristos }
1044ed0d50c3Schristos 
1045ed0d50c3Schristos // Write the first three reserved words of the .got.plt section.
1046ed0d50c3Schristos // The remainder of the section is written while writing the PLT
1047ed0d50c3Schristos // in Output_data_plt_i386::do_write.
1048ed0d50c3Schristos 
1049ed0d50c3Schristos void
do_write(Output_file * of)1050ed0d50c3Schristos Output_data_got_plt_i386::do_write(Output_file* of)
1051ed0d50c3Schristos {
1052ed0d50c3Schristos   // The first entry in the GOT is the address of the .dynamic section
1053ed0d50c3Schristos   // aka the PT_DYNAMIC segment.  The next two entries are reserved.
1054ed0d50c3Schristos   // We saved space for them when we created the section in
1055ed0d50c3Schristos   // Target_i386::got_section.
1056ed0d50c3Schristos   const off_t got_file_offset = this->offset();
1057ed0d50c3Schristos   gold_assert(this->data_size() >= 12);
1058ed0d50c3Schristos   unsigned char* const got_view = of->get_output_view(got_file_offset, 12);
1059ed0d50c3Schristos   Output_section* dynamic = this->layout_->dynamic_section();
1060ed0d50c3Schristos   uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
1061ed0d50c3Schristos   elfcpp::Swap<32, false>::writeval(got_view, dynamic_addr);
1062ed0d50c3Schristos   memset(got_view + 4, 0, 8);
1063ed0d50c3Schristos   of->write_output_view(got_file_offset, 12, got_view);
1064ed0d50c3Schristos }
1065ed0d50c3Schristos 
1066ed0d50c3Schristos // Create the PLT section.  The ordinary .got section is an argument,
1067ed0d50c3Schristos // since we need to refer to the start.  We also create our own .got
1068ed0d50c3Schristos // section just for PLT entries.
1069ed0d50c3Schristos 
Output_data_plt_i386(Layout * layout,uint64_t addralign,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative)1070ed0d50c3Schristos Output_data_plt_i386::Output_data_plt_i386(Layout* layout,
1071ed0d50c3Schristos 					   uint64_t addralign,
1072ed0d50c3Schristos 					   Output_data_got_plt_i386* got_plt,
1073ed0d50c3Schristos 					   Output_data_space* got_irelative)
1074ed0d50c3Schristos   : Output_section_data(addralign),
1075ed0d50c3Schristos     tls_desc_rel_(NULL), irelative_rel_(NULL), got_plt_(got_plt),
1076ed0d50c3Schristos     got_irelative_(got_irelative), count_(0), irelative_count_(0),
1077ed0d50c3Schristos     global_ifuncs_(), local_ifuncs_()
1078ed0d50c3Schristos {
1079ed0d50c3Schristos   this->rel_ = new Reloc_section(false);
1080ed0d50c3Schristos   layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
1081ed0d50c3Schristos 				  elfcpp::SHF_ALLOC, this->rel_,
1082ed0d50c3Schristos 				  ORDER_DYNAMIC_PLT_RELOCS, false);
1083ed0d50c3Schristos }
1084ed0d50c3Schristos 
1085ed0d50c3Schristos void
do_adjust_output_section(Output_section * os)1086ed0d50c3Schristos Output_data_plt_i386::do_adjust_output_section(Output_section* os)
1087ed0d50c3Schristos {
1088ed0d50c3Schristos   // UnixWare sets the entsize of .plt to 4, and so does the old GNU
1089ed0d50c3Schristos   // linker, and so do we.
1090ed0d50c3Schristos   os->set_entsize(4);
1091ed0d50c3Schristos }
1092ed0d50c3Schristos 
1093ed0d50c3Schristos // Add an entry to the PLT.
1094ed0d50c3Schristos 
1095ed0d50c3Schristos void
add_entry(Symbol_table * symtab,Layout * layout,Symbol * gsym)1096ed0d50c3Schristos Output_data_plt_i386::add_entry(Symbol_table* symtab, Layout* layout,
1097ed0d50c3Schristos 				Symbol* gsym)
1098ed0d50c3Schristos {
1099ed0d50c3Schristos   gold_assert(!gsym->has_plt_offset());
1100ed0d50c3Schristos 
1101ed0d50c3Schristos   // Every PLT entry needs a reloc.
1102ed0d50c3Schristos   if (gsym->type() == elfcpp::STT_GNU_IFUNC
1103ed0d50c3Schristos       && gsym->can_use_relative_reloc(false))
1104ed0d50c3Schristos     {
1105ed0d50c3Schristos       gsym->set_plt_offset(this->irelative_count_ * this->get_plt_entry_size());
1106ed0d50c3Schristos       ++this->irelative_count_;
1107ed0d50c3Schristos       section_offset_type got_offset =
1108ed0d50c3Schristos 	this->got_irelative_->current_data_size();
1109ed0d50c3Schristos       this->got_irelative_->set_current_data_size(got_offset + 4);
1110ed0d50c3Schristos       Reloc_section* rel = this->rel_irelative(symtab, layout);
1111ed0d50c3Schristos       rel->add_symbolless_global_addend(gsym, elfcpp::R_386_IRELATIVE,
1112ed0d50c3Schristos 					this->got_irelative_, got_offset);
1113ed0d50c3Schristos       struct Global_ifunc gi;
1114ed0d50c3Schristos       gi.sym = gsym;
1115ed0d50c3Schristos       gi.got_offset = got_offset;
1116ed0d50c3Schristos       this->global_ifuncs_.push_back(gi);
1117ed0d50c3Schristos     }
1118ed0d50c3Schristos   else
1119ed0d50c3Schristos     {
1120ed0d50c3Schristos       // When setting the PLT offset we skip the initial reserved PLT
1121ed0d50c3Schristos       // entry.
1122ed0d50c3Schristos       gsym->set_plt_offset((this->count_ + 1) * this->get_plt_entry_size());
1123ed0d50c3Schristos 
1124ed0d50c3Schristos       ++this->count_;
1125ed0d50c3Schristos 
1126ed0d50c3Schristos       section_offset_type got_offset = this->got_plt_->current_data_size();
1127ed0d50c3Schristos 
1128ed0d50c3Schristos       // Every PLT entry needs a GOT entry which points back to the
1129ed0d50c3Schristos       // PLT entry (this will be changed by the dynamic linker,
1130ed0d50c3Schristos       // normally lazily when the function is called).
1131ed0d50c3Schristos       this->got_plt_->set_current_data_size(got_offset + 4);
1132ed0d50c3Schristos 
1133ed0d50c3Schristos       gsym->set_needs_dynsym_entry();
1134ed0d50c3Schristos       this->rel_->add_global(gsym, elfcpp::R_386_JUMP_SLOT, this->got_plt_,
1135ed0d50c3Schristos 			     got_offset);
1136ed0d50c3Schristos     }
1137ed0d50c3Schristos 
1138ed0d50c3Schristos   // Note that we don't need to save the symbol.  The contents of the
1139ed0d50c3Schristos   // PLT are independent of which symbols are used.  The symbols only
1140ed0d50c3Schristos   // appear in the relocations.
1141ed0d50c3Schristos }
1142ed0d50c3Schristos 
1143ed0d50c3Schristos // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.  Return
1144ed0d50c3Schristos // the PLT offset.
1145ed0d50c3Schristos 
1146ed0d50c3Schristos unsigned int
add_local_ifunc_entry(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * relobj,unsigned int local_sym_index)1147ed0d50c3Schristos Output_data_plt_i386::add_local_ifunc_entry(
1148ed0d50c3Schristos     Symbol_table* symtab,
1149ed0d50c3Schristos     Layout* layout,
1150ed0d50c3Schristos     Sized_relobj_file<32, false>* relobj,
1151ed0d50c3Schristos     unsigned int local_sym_index)
1152ed0d50c3Schristos {
1153ed0d50c3Schristos   unsigned int plt_offset = this->irelative_count_ * this->get_plt_entry_size();
1154ed0d50c3Schristos   ++this->irelative_count_;
1155ed0d50c3Schristos 
1156ed0d50c3Schristos   section_offset_type got_offset = this->got_irelative_->current_data_size();
1157ed0d50c3Schristos 
1158ed0d50c3Schristos   // Every PLT entry needs a GOT entry which points back to the PLT
1159ed0d50c3Schristos   // entry.
1160ed0d50c3Schristos   this->got_irelative_->set_current_data_size(got_offset + 4);
1161ed0d50c3Schristos 
1162ed0d50c3Schristos   // Every PLT entry needs a reloc.
1163ed0d50c3Schristos   Reloc_section* rel = this->rel_irelative(symtab, layout);
1164ed0d50c3Schristos   rel->add_symbolless_local_addend(relobj, local_sym_index,
1165ed0d50c3Schristos 				   elfcpp::R_386_IRELATIVE,
1166ed0d50c3Schristos 				   this->got_irelative_, got_offset);
1167ed0d50c3Schristos 
1168ed0d50c3Schristos   struct Local_ifunc li;
1169ed0d50c3Schristos   li.object = relobj;
1170ed0d50c3Schristos   li.local_sym_index = local_sym_index;
1171ed0d50c3Schristos   li.got_offset = got_offset;
1172ed0d50c3Schristos   this->local_ifuncs_.push_back(li);
1173ed0d50c3Schristos 
1174ed0d50c3Schristos   return plt_offset;
1175ed0d50c3Schristos }
1176ed0d50c3Schristos 
1177ed0d50c3Schristos // Return where the TLS_DESC relocations should go, creating it if
1178ed0d50c3Schristos // necessary. These follow the JUMP_SLOT relocations.
1179ed0d50c3Schristos 
1180ed0d50c3Schristos Output_data_plt_i386::Reloc_section*
rel_tls_desc(Layout * layout)1181ed0d50c3Schristos Output_data_plt_i386::rel_tls_desc(Layout* layout)
1182ed0d50c3Schristos {
1183ed0d50c3Schristos   if (this->tls_desc_rel_ == NULL)
1184ed0d50c3Schristos     {
1185ed0d50c3Schristos       this->tls_desc_rel_ = new Reloc_section(false);
1186ed0d50c3Schristos       layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
1187ed0d50c3Schristos 				      elfcpp::SHF_ALLOC, this->tls_desc_rel_,
1188ed0d50c3Schristos 				      ORDER_DYNAMIC_PLT_RELOCS, false);
1189ed0d50c3Schristos       gold_assert(this->tls_desc_rel_->output_section()
1190ed0d50c3Schristos 		  == this->rel_->output_section());
1191ed0d50c3Schristos     }
1192ed0d50c3Schristos   return this->tls_desc_rel_;
1193ed0d50c3Schristos }
1194ed0d50c3Schristos 
1195ed0d50c3Schristos // Return where the IRELATIVE relocations should go in the PLT.  These
1196ed0d50c3Schristos // follow the JUMP_SLOT and TLS_DESC relocations.
1197ed0d50c3Schristos 
1198ed0d50c3Schristos Output_data_plt_i386::Reloc_section*
rel_irelative(Symbol_table * symtab,Layout * layout)1199ed0d50c3Schristos Output_data_plt_i386::rel_irelative(Symbol_table* symtab, Layout* layout)
1200ed0d50c3Schristos {
1201ed0d50c3Schristos   if (this->irelative_rel_ == NULL)
1202ed0d50c3Schristos     {
1203ed0d50c3Schristos       // Make sure we have a place for the TLS_DESC relocations, in
1204ed0d50c3Schristos       // case we see any later on.
1205ed0d50c3Schristos       this->rel_tls_desc(layout);
1206ed0d50c3Schristos       this->irelative_rel_ = new Reloc_section(false);
1207ed0d50c3Schristos       layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
1208ed0d50c3Schristos 				      elfcpp::SHF_ALLOC, this->irelative_rel_,
1209ed0d50c3Schristos 				      ORDER_DYNAMIC_PLT_RELOCS, false);
1210ed0d50c3Schristos       gold_assert(this->irelative_rel_->output_section()
1211ed0d50c3Schristos 		  == this->rel_->output_section());
1212ed0d50c3Schristos 
1213ed0d50c3Schristos       if (parameters->doing_static_link())
1214ed0d50c3Schristos 	{
1215ed0d50c3Schristos 	  // A statically linked executable will only have a .rel.plt
1216ed0d50c3Schristos 	  // section to hold R_386_IRELATIVE relocs for STT_GNU_IFUNC
1217ed0d50c3Schristos 	  // symbols.  The library will use these symbols to locate
1218ed0d50c3Schristos 	  // the IRELATIVE relocs at program startup time.
1219ed0d50c3Schristos 	  symtab->define_in_output_data("__rel_iplt_start", NULL,
1220ed0d50c3Schristos 					Symbol_table::PREDEFINED,
1221ed0d50c3Schristos 					this->irelative_rel_, 0, 0,
1222ed0d50c3Schristos 					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
1223ed0d50c3Schristos 					elfcpp::STV_HIDDEN, 0, false, true);
1224ed0d50c3Schristos 	  symtab->define_in_output_data("__rel_iplt_end", NULL,
1225ed0d50c3Schristos 					Symbol_table::PREDEFINED,
1226ed0d50c3Schristos 					this->irelative_rel_, 0, 0,
1227ed0d50c3Schristos 					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
1228ed0d50c3Schristos 					elfcpp::STV_HIDDEN, 0, true, true);
1229ed0d50c3Schristos 	}
1230ed0d50c3Schristos     }
1231ed0d50c3Schristos   return this->irelative_rel_;
1232ed0d50c3Schristos }
1233ed0d50c3Schristos 
1234ed0d50c3Schristos // Return the PLT address to use for a global symbol.
1235ed0d50c3Schristos 
1236ed0d50c3Schristos uint64_t
address_for_global(const Symbol * gsym)1237ed0d50c3Schristos Output_data_plt_i386::address_for_global(const Symbol* gsym)
1238ed0d50c3Schristos {
1239ed0d50c3Schristos   uint64_t offset = 0;
1240ed0d50c3Schristos   if (gsym->type() == elfcpp::STT_GNU_IFUNC
1241ed0d50c3Schristos       && gsym->can_use_relative_reloc(false))
1242ed0d50c3Schristos     offset = (this->count_ + 1) * this->get_plt_entry_size();
1243ed0d50c3Schristos   return this->address() + offset + gsym->plt_offset();
1244ed0d50c3Schristos }
1245ed0d50c3Schristos 
1246ed0d50c3Schristos // Return the PLT address to use for a local symbol.  These are always
1247ed0d50c3Schristos // IRELATIVE relocs.
1248ed0d50c3Schristos 
1249ed0d50c3Schristos uint64_t
address_for_local(const Relobj * object,unsigned int r_sym)1250ed0d50c3Schristos Output_data_plt_i386::address_for_local(const Relobj* object,
1251ed0d50c3Schristos 					unsigned int r_sym)
1252ed0d50c3Schristos {
1253ed0d50c3Schristos   return (this->address()
1254ed0d50c3Schristos 	  + (this->count_ + 1) * this->get_plt_entry_size()
1255ed0d50c3Schristos 	  + object->local_plt_offset(r_sym));
1256ed0d50c3Schristos }
1257ed0d50c3Schristos 
1258ed0d50c3Schristos // The first entry in the PLT for an executable.
1259ed0d50c3Schristos 
1260ed0d50c3Schristos const unsigned char Output_data_plt_i386_exec::first_plt_entry[plt_entry_size] =
1261ed0d50c3Schristos {
1262ed0d50c3Schristos   0xff, 0x35,	// pushl contents of memory address
1263ed0d50c3Schristos   0, 0, 0, 0,	// replaced with address of .got + 4
1264ed0d50c3Schristos   0xff, 0x25,	// jmp indirect
1265ed0d50c3Schristos   0, 0, 0, 0,	// replaced with address of .got + 8
1266ed0d50c3Schristos   0, 0, 0, 0	// unused
1267ed0d50c3Schristos };
1268ed0d50c3Schristos 
1269ed0d50c3Schristos void
do_fill_first_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr got_address)1270ed0d50c3Schristos Output_data_plt_i386_exec::do_fill_first_plt_entry(
1271ed0d50c3Schristos     unsigned char* pov,
1272ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr got_address)
1273ed0d50c3Schristos {
1274ed0d50c3Schristos   memcpy(pov, first_plt_entry, plt_entry_size);
1275ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_address + 4);
1276ed0d50c3Schristos   elfcpp::Swap<32, false>::writeval(pov + 8, got_address + 8);
1277ed0d50c3Schristos }
1278ed0d50c3Schristos 
1279ed0d50c3Schristos // The first entry in the PLT for a shared object.
1280ed0d50c3Schristos 
1281ed0d50c3Schristos const unsigned char Output_data_plt_i386_dyn::first_plt_entry[plt_entry_size] =
1282ed0d50c3Schristos {
1283ed0d50c3Schristos   0xff, 0xb3, 4, 0, 0, 0,	// pushl 4(%ebx)
1284ed0d50c3Schristos   0xff, 0xa3, 8, 0, 0, 0,	// jmp *8(%ebx)
1285ed0d50c3Schristos   0, 0, 0, 0			// unused
1286ed0d50c3Schristos };
1287ed0d50c3Schristos 
1288ed0d50c3Schristos void
do_fill_first_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr)1289ed0d50c3Schristos Output_data_plt_i386_dyn::do_fill_first_plt_entry(
1290ed0d50c3Schristos     unsigned char* pov,
1291ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr)
1292ed0d50c3Schristos {
1293ed0d50c3Schristos   memcpy(pov, first_plt_entry, plt_entry_size);
1294ed0d50c3Schristos }
1295ed0d50c3Schristos 
1296ed0d50c3Schristos // Subsequent entries in the PLT for an executable.
1297ed0d50c3Schristos 
1298ed0d50c3Schristos const unsigned char Output_data_plt_i386_exec::plt_entry[plt_entry_size] =
1299ed0d50c3Schristos {
1300ed0d50c3Schristos   0xff, 0x25,	// jmp indirect
1301ed0d50c3Schristos   0, 0, 0, 0,	// replaced with address of symbol in .got
1302ed0d50c3Schristos   0x68,		// pushl immediate
1303ed0d50c3Schristos   0, 0, 0, 0,	// replaced with offset into relocation table
1304ed0d50c3Schristos   0xe9,		// jmp relative
1305ed0d50c3Schristos   0, 0, 0, 0	// replaced with offset to start of .plt
1306ed0d50c3Schristos };
1307ed0d50c3Schristos 
1308ed0d50c3Schristos unsigned int
do_fill_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr got_address,unsigned int got_offset,unsigned int plt_offset,unsigned int plt_rel_offset)1309ed0d50c3Schristos Output_data_plt_i386_exec::do_fill_plt_entry(
1310ed0d50c3Schristos     unsigned char* pov,
1311ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr got_address,
1312ed0d50c3Schristos     unsigned int got_offset,
1313ed0d50c3Schristos     unsigned int plt_offset,
1314ed0d50c3Schristos     unsigned int plt_rel_offset)
1315ed0d50c3Schristos {
1316ed0d50c3Schristos   memcpy(pov, plt_entry, plt_entry_size);
1317ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2,
1318ed0d50c3Schristos 					      got_address + got_offset);
1319ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 7, plt_rel_offset);
1320ed0d50c3Schristos   elfcpp::Swap<32, false>::writeval(pov + 12, - (plt_offset + 12 + 4));
1321ed0d50c3Schristos   return 6;
1322ed0d50c3Schristos }
1323ed0d50c3Schristos 
1324ed0d50c3Schristos // Subsequent entries in the PLT for a shared object.
1325ed0d50c3Schristos 
1326ed0d50c3Schristos const unsigned char Output_data_plt_i386_dyn::plt_entry[plt_entry_size] =
1327ed0d50c3Schristos {
1328ed0d50c3Schristos   0xff, 0xa3,	// jmp *offset(%ebx)
1329ed0d50c3Schristos   0, 0, 0, 0,	// replaced with offset of symbol in .got
1330ed0d50c3Schristos   0x68,		// pushl immediate
1331ed0d50c3Schristos   0, 0, 0, 0,	// replaced with offset into relocation table
1332ed0d50c3Schristos   0xe9,		// jmp relative
1333ed0d50c3Schristos   0, 0, 0, 0	// replaced with offset to start of .plt
1334ed0d50c3Schristos };
1335ed0d50c3Schristos 
1336ed0d50c3Schristos unsigned int
do_fill_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr,unsigned int got_offset,unsigned int plt_offset,unsigned int plt_rel_offset)1337ed0d50c3Schristos Output_data_plt_i386_dyn::do_fill_plt_entry(unsigned char* pov,
1338ed0d50c3Schristos 					    elfcpp::Elf_types<32>::Elf_Addr,
1339ed0d50c3Schristos 					    unsigned int got_offset,
1340ed0d50c3Schristos 					    unsigned int plt_offset,
1341ed0d50c3Schristos 					    unsigned int plt_rel_offset)
1342ed0d50c3Schristos {
1343ed0d50c3Schristos   memcpy(pov, plt_entry, plt_entry_size);
1344ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset);
1345ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 7, plt_rel_offset);
1346ed0d50c3Schristos   elfcpp::Swap<32, false>::writeval(pov + 12, - (plt_offset + 12 + 4));
1347ed0d50c3Schristos   return 6;
1348ed0d50c3Schristos }
1349ed0d50c3Schristos 
1350ed0d50c3Schristos // The .eh_frame unwind information for the PLT.
1351ed0d50c3Schristos 
1352ed0d50c3Schristos const unsigned char
1353ed0d50c3Schristos Output_data_plt_i386::plt_eh_frame_cie[plt_eh_frame_cie_size] =
1354ed0d50c3Schristos {
1355ed0d50c3Schristos   1,				// CIE version.
1356ed0d50c3Schristos   'z',				// Augmentation: augmentation size included.
1357ed0d50c3Schristos   'R',				// Augmentation: FDE encoding included.
1358ed0d50c3Schristos   '\0',				// End of augmentation string.
1359ed0d50c3Schristos   1,				// Code alignment factor.
1360ed0d50c3Schristos   0x7c,				// Data alignment factor.
1361ed0d50c3Schristos   8,				// Return address column.
1362ed0d50c3Schristos   1,				// Augmentation size.
1363ed0d50c3Schristos   (elfcpp::DW_EH_PE_pcrel	// FDE encoding.
1364ed0d50c3Schristos    | elfcpp::DW_EH_PE_sdata4),
1365ed0d50c3Schristos   elfcpp::DW_CFA_def_cfa, 4, 4,	// DW_CFA_def_cfa: r4 (esp) ofs 4.
1366ed0d50c3Schristos   elfcpp::DW_CFA_offset + 8, 1,	// DW_CFA_offset: r8 (eip) at cfa-4.
1367ed0d50c3Schristos   elfcpp::DW_CFA_nop,		// Align to 16 bytes.
1368ed0d50c3Schristos   elfcpp::DW_CFA_nop
1369ed0d50c3Schristos };
1370ed0d50c3Schristos 
1371ed0d50c3Schristos const unsigned char
1372ed0d50c3Schristos Output_data_plt_i386_standard::plt_eh_frame_fde[plt_eh_frame_fde_size] =
1373ed0d50c3Schristos {
1374ed0d50c3Schristos   0, 0, 0, 0,				// Replaced with offset to .plt.
1375ed0d50c3Schristos   0, 0, 0, 0,				// Replaced with size of .plt.
1376ed0d50c3Schristos   0,					// Augmentation size.
1377ed0d50c3Schristos   elfcpp::DW_CFA_def_cfa_offset, 8,	// DW_CFA_def_cfa_offset: 8.
1378ed0d50c3Schristos   elfcpp::DW_CFA_advance_loc + 6,	// Advance 6 to __PLT__ + 6.
1379ed0d50c3Schristos   elfcpp::DW_CFA_def_cfa_offset, 12,	// DW_CFA_def_cfa_offset: 12.
1380ed0d50c3Schristos   elfcpp::DW_CFA_advance_loc + 10,	// Advance 10 to __PLT__ + 16.
1381ed0d50c3Schristos   elfcpp::DW_CFA_def_cfa_expression,	// DW_CFA_def_cfa_expression.
1382ed0d50c3Schristos   11,					// Block length.
1383ed0d50c3Schristos   elfcpp::DW_OP_breg4, 4,		// Push %esp + 4.
1384ed0d50c3Schristos   elfcpp::DW_OP_breg8, 0,		// Push %eip.
1385ed0d50c3Schristos   elfcpp::DW_OP_lit15,			// Push 0xf.
1386ed0d50c3Schristos   elfcpp::DW_OP_and,			// & (%eip & 0xf).
1387ed0d50c3Schristos   elfcpp::DW_OP_lit11,			// Push 0xb.
1388ed0d50c3Schristos   elfcpp::DW_OP_ge,			// >= ((%eip & 0xf) >= 0xb)
1389ed0d50c3Schristos   elfcpp::DW_OP_lit2,			// Push 2.
1390ed0d50c3Schristos   elfcpp::DW_OP_shl,			// << (((%eip & 0xf) >= 0xb) << 2)
1391ed0d50c3Schristos   elfcpp::DW_OP_plus,			// + ((((%eip&0xf)>=0xb)<<2)+%esp+4
1392ed0d50c3Schristos   elfcpp::DW_CFA_nop,			// Align to 32 bytes.
1393ed0d50c3Schristos   elfcpp::DW_CFA_nop,
1394ed0d50c3Schristos   elfcpp::DW_CFA_nop,
1395ed0d50c3Schristos   elfcpp::DW_CFA_nop
1396ed0d50c3Schristos };
1397ed0d50c3Schristos 
1398ed0d50c3Schristos // Write out the PLT.  This uses the hand-coded instructions above,
1399ed0d50c3Schristos // and adjusts them as needed.  This is all specified by the i386 ELF
1400ed0d50c3Schristos // Processor Supplement.
1401ed0d50c3Schristos 
1402ed0d50c3Schristos void
do_write(Output_file * of)1403ed0d50c3Schristos Output_data_plt_i386::do_write(Output_file* of)
1404ed0d50c3Schristos {
1405ed0d50c3Schristos   const off_t offset = this->offset();
1406ed0d50c3Schristos   const section_size_type oview_size =
1407ed0d50c3Schristos     convert_to_section_size_type(this->data_size());
1408ed0d50c3Schristos   unsigned char* const oview = of->get_output_view(offset, oview_size);
1409ed0d50c3Schristos 
1410ed0d50c3Schristos   const off_t got_file_offset = this->got_plt_->offset();
1411ed0d50c3Schristos   gold_assert(parameters->incremental_update()
1412ed0d50c3Schristos 	      || (got_file_offset + this->got_plt_->data_size()
1413ed0d50c3Schristos 		  == this->got_irelative_->offset()));
1414ed0d50c3Schristos   const section_size_type got_size =
1415ed0d50c3Schristos     convert_to_section_size_type(this->got_plt_->data_size()
1416ed0d50c3Schristos 				 + this->got_irelative_->data_size());
1417ed0d50c3Schristos 
1418ed0d50c3Schristos   unsigned char* const got_view = of->get_output_view(got_file_offset,
1419ed0d50c3Schristos 						      got_size);
1420ed0d50c3Schristos 
1421ed0d50c3Schristos   unsigned char* pov = oview;
1422ed0d50c3Schristos 
1423ed0d50c3Schristos   elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address();
1424ed0d50c3Schristos   elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address();
1425ed0d50c3Schristos 
1426ed0d50c3Schristos   this->fill_first_plt_entry(pov, got_address);
1427ed0d50c3Schristos   pov += this->get_plt_entry_size();
1428ed0d50c3Schristos 
1429ed0d50c3Schristos   // The first three entries in the GOT are reserved, and are written
1430ed0d50c3Schristos   // by Output_data_got_plt_i386::do_write.
1431ed0d50c3Schristos   unsigned char* got_pov = got_view + 12;
1432ed0d50c3Schristos 
1433ed0d50c3Schristos   const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
1434ed0d50c3Schristos 
1435ed0d50c3Schristos   unsigned int plt_offset = this->get_plt_entry_size();
1436ed0d50c3Schristos   unsigned int plt_rel_offset = 0;
1437ed0d50c3Schristos   unsigned int got_offset = 12;
1438ed0d50c3Schristos   const unsigned int count = this->count_ + this->irelative_count_;
1439ed0d50c3Schristos   for (unsigned int i = 0;
1440ed0d50c3Schristos        i < count;
1441ed0d50c3Schristos        ++i,
1442ed0d50c3Schristos 	 pov += this->get_plt_entry_size(),
1443ed0d50c3Schristos 	 got_pov += 4,
1444ed0d50c3Schristos 	 plt_offset += this->get_plt_entry_size(),
1445ed0d50c3Schristos 	 plt_rel_offset += rel_size,
1446ed0d50c3Schristos 	 got_offset += 4)
1447ed0d50c3Schristos     {
1448ed0d50c3Schristos       // Set and adjust the PLT entry itself.
1449ed0d50c3Schristos       unsigned int lazy_offset = this->fill_plt_entry(pov,
1450ed0d50c3Schristos 						      got_address,
1451ed0d50c3Schristos 						      got_offset,
1452ed0d50c3Schristos 						      plt_offset,
1453ed0d50c3Schristos 						      plt_rel_offset);
1454ed0d50c3Schristos 
1455ed0d50c3Schristos       // Set the entry in the GOT.
1456ed0d50c3Schristos       elfcpp::Swap<32, false>::writeval(got_pov,
1457ed0d50c3Schristos 					plt_address + plt_offset + lazy_offset);
1458ed0d50c3Schristos     }
1459ed0d50c3Schristos 
1460ed0d50c3Schristos   // If any STT_GNU_IFUNC symbols have PLT entries, we need to change
1461ed0d50c3Schristos   // the GOT to point to the actual symbol value, rather than point to
1462ed0d50c3Schristos   // the PLT entry.  That will let the dynamic linker call the right
1463ed0d50c3Schristos   // function when resolving IRELATIVE relocations.
1464ed0d50c3Schristos   unsigned char* got_irelative_view = got_view + this->got_plt_->data_size();
1465ed0d50c3Schristos   for (std::vector<Global_ifunc>::const_iterator p =
1466ed0d50c3Schristos 	 this->global_ifuncs_.begin();
1467ed0d50c3Schristos        p != this->global_ifuncs_.end();
1468ed0d50c3Schristos        ++p)
1469ed0d50c3Schristos     {
1470ed0d50c3Schristos       const Sized_symbol<32>* ssym =
1471ed0d50c3Schristos 	static_cast<const Sized_symbol<32>*>(p->sym);
1472ed0d50c3Schristos       elfcpp::Swap<32, false>::writeval(got_irelative_view + p->got_offset,
1473ed0d50c3Schristos 					ssym->value());
1474ed0d50c3Schristos     }
1475ed0d50c3Schristos 
1476ed0d50c3Schristos   for (std::vector<Local_ifunc>::const_iterator p =
1477ed0d50c3Schristos 	 this->local_ifuncs_.begin();
1478ed0d50c3Schristos        p != this->local_ifuncs_.end();
1479ed0d50c3Schristos        ++p)
1480ed0d50c3Schristos     {
1481ed0d50c3Schristos       const Symbol_value<32>* psymval =
1482ed0d50c3Schristos 	p->object->local_symbol(p->local_sym_index);
1483ed0d50c3Schristos       elfcpp::Swap<32, false>::writeval(got_irelative_view + p->got_offset,
1484ed0d50c3Schristos 					psymval->value(p->object, 0));
1485ed0d50c3Schristos     }
1486ed0d50c3Schristos 
1487ed0d50c3Schristos   gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
1488ed0d50c3Schristos   gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
1489ed0d50c3Schristos 
1490ed0d50c3Schristos   of->write_output_view(offset, oview_size, oview);
1491ed0d50c3Schristos   of->write_output_view(got_file_offset, got_size, got_view);
1492ed0d50c3Schristos }
1493ed0d50c3Schristos 
1494ed0d50c3Schristos // Create the PLT section.
1495ed0d50c3Schristos 
1496ed0d50c3Schristos void
make_plt_section(Symbol_table * symtab,Layout * layout)1497ed0d50c3Schristos Target_i386::make_plt_section(Symbol_table* symtab, Layout* layout)
1498ed0d50c3Schristos {
1499ed0d50c3Schristos   if (this->plt_ == NULL)
1500ed0d50c3Schristos     {
1501ed0d50c3Schristos       // Create the GOT sections first.
1502ed0d50c3Schristos       this->got_section(symtab, layout);
1503ed0d50c3Schristos 
1504ed0d50c3Schristos       const bool dyn = parameters->options().output_is_position_independent();
1505ed0d50c3Schristos       this->plt_ = this->make_data_plt(layout,
1506ed0d50c3Schristos 				       this->got_plt_,
1507ed0d50c3Schristos 				       this->got_irelative_,
1508ed0d50c3Schristos 				       dyn);
1509ed0d50c3Schristos 
1510ed0d50c3Schristos       // Add unwind information if requested.
1511ed0d50c3Schristos       if (parameters->options().ld_generated_unwind_info())
1512ed0d50c3Schristos 	this->plt_->add_eh_frame(layout);
1513ed0d50c3Schristos 
1514ed0d50c3Schristos       layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
1515ed0d50c3Schristos 				      (elfcpp::SHF_ALLOC
1516ed0d50c3Schristos 				       | elfcpp::SHF_EXECINSTR),
1517ed0d50c3Schristos 				      this->plt_, ORDER_PLT, false);
1518ed0d50c3Schristos 
1519ed0d50c3Schristos       // Make the sh_info field of .rel.plt point to .plt.
1520ed0d50c3Schristos       Output_section* rel_plt_os = this->plt_->rel_plt()->output_section();
1521ed0d50c3Schristos       rel_plt_os->set_info_section(this->plt_->output_section());
1522ed0d50c3Schristos     }
1523ed0d50c3Schristos }
1524ed0d50c3Schristos 
1525ed0d50c3Schristos // Create a PLT entry for a global symbol.
1526ed0d50c3Schristos 
1527ed0d50c3Schristos void
make_plt_entry(Symbol_table * symtab,Layout * layout,Symbol * gsym)1528ed0d50c3Schristos Target_i386::make_plt_entry(Symbol_table* symtab, Layout* layout, Symbol* gsym)
1529ed0d50c3Schristos {
1530ed0d50c3Schristos   if (gsym->has_plt_offset())
1531ed0d50c3Schristos     return;
1532ed0d50c3Schristos   if (this->plt_ == NULL)
1533ed0d50c3Schristos     this->make_plt_section(symtab, layout);
1534ed0d50c3Schristos   this->plt_->add_entry(symtab, layout, gsym);
1535ed0d50c3Schristos }
1536ed0d50c3Schristos 
1537ed0d50c3Schristos // Make a PLT entry for a local STT_GNU_IFUNC symbol.
1538ed0d50c3Schristos 
1539ed0d50c3Schristos void
make_local_ifunc_plt_entry(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * relobj,unsigned int local_sym_index)1540ed0d50c3Schristos Target_i386::make_local_ifunc_plt_entry(Symbol_table* symtab, Layout* layout,
1541ed0d50c3Schristos 					Sized_relobj_file<32, false>* relobj,
1542ed0d50c3Schristos 					unsigned int local_sym_index)
1543ed0d50c3Schristos {
1544ed0d50c3Schristos   if (relobj->local_has_plt_offset(local_sym_index))
1545ed0d50c3Schristos     return;
1546ed0d50c3Schristos   if (this->plt_ == NULL)
1547ed0d50c3Schristos     this->make_plt_section(symtab, layout);
1548ed0d50c3Schristos   unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout,
1549ed0d50c3Schristos 							      relobj,
1550ed0d50c3Schristos 							      local_sym_index);
1551ed0d50c3Schristos   relobj->set_local_plt_offset(local_sym_index, plt_offset);
1552ed0d50c3Schristos }
1553ed0d50c3Schristos 
1554ed0d50c3Schristos // Return the number of entries in the PLT.
1555ed0d50c3Schristos 
1556ed0d50c3Schristos unsigned int
plt_entry_count() const1557ed0d50c3Schristos Target_i386::plt_entry_count() const
1558ed0d50c3Schristos {
1559ed0d50c3Schristos   if (this->plt_ == NULL)
1560ed0d50c3Schristos     return 0;
1561ed0d50c3Schristos   return this->plt_->entry_count();
1562ed0d50c3Schristos }
1563ed0d50c3Schristos 
1564ed0d50c3Schristos // Return the offset of the first non-reserved PLT entry.
1565ed0d50c3Schristos 
1566ed0d50c3Schristos unsigned int
first_plt_entry_offset() const1567ed0d50c3Schristos Target_i386::first_plt_entry_offset() const
1568ed0d50c3Schristos {
1569ed0d50c3Schristos   if (this->plt_ == NULL)
1570ed0d50c3Schristos     return 0;
1571ed0d50c3Schristos   return this->plt_->first_plt_entry_offset();
1572ed0d50c3Schristos }
1573ed0d50c3Schristos 
1574ed0d50c3Schristos // Return the size of each PLT entry.
1575ed0d50c3Schristos 
1576ed0d50c3Schristos unsigned int
plt_entry_size() const1577ed0d50c3Schristos Target_i386::plt_entry_size() const
1578ed0d50c3Schristos {
1579ed0d50c3Schristos   if (this->plt_ == NULL)
1580ed0d50c3Schristos     return 0;
1581ed0d50c3Schristos   return this->plt_->get_plt_entry_size();
1582ed0d50c3Schristos }
1583ed0d50c3Schristos 
1584ed0d50c3Schristos // Get the section to use for TLS_DESC relocations.
1585ed0d50c3Schristos 
1586ed0d50c3Schristos Target_i386::Reloc_section*
rel_tls_desc_section(Layout * layout) const1587ed0d50c3Schristos Target_i386::rel_tls_desc_section(Layout* layout) const
1588ed0d50c3Schristos {
1589ed0d50c3Schristos   return this->plt_section()->rel_tls_desc(layout);
1590ed0d50c3Schristos }
1591ed0d50c3Schristos 
1592ed0d50c3Schristos // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
1593ed0d50c3Schristos 
1594ed0d50c3Schristos void
define_tls_base_symbol(Symbol_table * symtab,Layout * layout)1595ed0d50c3Schristos Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
1596ed0d50c3Schristos {
1597ed0d50c3Schristos   if (this->tls_base_symbol_defined_)
1598ed0d50c3Schristos     return;
1599ed0d50c3Schristos 
1600ed0d50c3Schristos   Output_segment* tls_segment = layout->tls_segment();
1601ed0d50c3Schristos   if (tls_segment != NULL)
1602ed0d50c3Schristos     {
1603ed0d50c3Schristos       bool is_exec = parameters->options().output_is_executable();
1604ed0d50c3Schristos       symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
1605ed0d50c3Schristos 				       Symbol_table::PREDEFINED,
1606ed0d50c3Schristos 				       tls_segment, 0, 0,
1607ed0d50c3Schristos 				       elfcpp::STT_TLS,
1608ed0d50c3Schristos 				       elfcpp::STB_LOCAL,
1609ed0d50c3Schristos 				       elfcpp::STV_HIDDEN, 0,
1610ed0d50c3Schristos 				       (is_exec
1611ed0d50c3Schristos 					? Symbol::SEGMENT_END
1612ed0d50c3Schristos 					: Symbol::SEGMENT_START),
1613ed0d50c3Schristos 				       true);
1614ed0d50c3Schristos     }
1615ed0d50c3Schristos   this->tls_base_symbol_defined_ = true;
1616ed0d50c3Schristos }
1617ed0d50c3Schristos 
1618ed0d50c3Schristos // Create a GOT entry for the TLS module index.
1619ed0d50c3Schristos 
1620ed0d50c3Schristos unsigned int
got_mod_index_entry(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * object)1621ed0d50c3Schristos Target_i386::got_mod_index_entry(Symbol_table* symtab, Layout* layout,
1622ed0d50c3Schristos 				 Sized_relobj_file<32, false>* object)
1623ed0d50c3Schristos {
1624ed0d50c3Schristos   if (this->got_mod_index_offset_ == -1U)
1625ed0d50c3Schristos     {
1626ed0d50c3Schristos       gold_assert(symtab != NULL && layout != NULL && object != NULL);
1627ed0d50c3Schristos       Reloc_section* rel_dyn = this->rel_dyn_section(layout);
1628ed0d50c3Schristos       Output_data_got<32, false>* got = this->got_section(symtab, layout);
1629ed0d50c3Schristos       unsigned int got_offset = got->add_constant(0);
1630ed0d50c3Schristos       rel_dyn->add_local(object, 0, elfcpp::R_386_TLS_DTPMOD32, got,
1631ed0d50c3Schristos 			 got_offset);
1632ed0d50c3Schristos       got->add_constant(0);
1633ed0d50c3Schristos       this->got_mod_index_offset_ = got_offset;
1634ed0d50c3Schristos     }
1635ed0d50c3Schristos   return this->got_mod_index_offset_;
1636ed0d50c3Schristos }
1637ed0d50c3Schristos 
1638ed0d50c3Schristos // Optimize the TLS relocation type based on what we know about the
1639ed0d50c3Schristos // symbol.  IS_FINAL is true if the final address of this symbol is
1640ed0d50c3Schristos // known at link time.
1641ed0d50c3Schristos 
1642ed0d50c3Schristos tls::Tls_optimization
optimize_tls_reloc(bool is_final,int r_type)1643ed0d50c3Schristos Target_i386::optimize_tls_reloc(bool is_final, int r_type)
1644ed0d50c3Schristos {
1645ed0d50c3Schristos   // If we are generating a shared library, then we can't do anything
1646ed0d50c3Schristos   // in the linker.
1647ed0d50c3Schristos   if (parameters->options().shared())
1648ed0d50c3Schristos     return tls::TLSOPT_NONE;
1649ed0d50c3Schristos 
1650ed0d50c3Schristos   switch (r_type)
1651ed0d50c3Schristos     {
1652ed0d50c3Schristos     case elfcpp::R_386_TLS_GD:
1653ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTDESC:
1654ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC_CALL:
1655ed0d50c3Schristos       // These are General-Dynamic which permits fully general TLS
1656ed0d50c3Schristos       // access.  Since we know that we are generating an executable,
1657ed0d50c3Schristos       // we can convert this to Initial-Exec.  If we also know that
1658ed0d50c3Schristos       // this is a local symbol, we can further switch to Local-Exec.
1659ed0d50c3Schristos       if (is_final)
1660ed0d50c3Schristos 	return tls::TLSOPT_TO_LE;
1661ed0d50c3Schristos       return tls::TLSOPT_TO_IE;
1662ed0d50c3Schristos 
1663ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM:
1664ed0d50c3Schristos       // This is Local-Dynamic, which refers to a local symbol in the
1665ed0d50c3Schristos       // dynamic TLS block.  Since we know that we generating an
1666ed0d50c3Schristos       // executable, we can switch to Local-Exec.
1667ed0d50c3Schristos       return tls::TLSOPT_TO_LE;
1668ed0d50c3Schristos 
1669ed0d50c3Schristos     case elfcpp::R_386_TLS_LDO_32:
1670ed0d50c3Schristos       // Another type of Local-Dynamic relocation.
1671ed0d50c3Schristos       return tls::TLSOPT_TO_LE;
1672ed0d50c3Schristos 
1673ed0d50c3Schristos     case elfcpp::R_386_TLS_IE:
1674ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTIE:
1675ed0d50c3Schristos     case elfcpp::R_386_TLS_IE_32:
1676ed0d50c3Schristos       // These are Initial-Exec relocs which get the thread offset
1677ed0d50c3Schristos       // from the GOT.  If we know that we are linking against the
1678ed0d50c3Schristos       // local symbol, we can switch to Local-Exec, which links the
1679ed0d50c3Schristos       // thread offset into the instruction.
1680ed0d50c3Schristos       if (is_final)
1681ed0d50c3Schristos 	return tls::TLSOPT_TO_LE;
1682ed0d50c3Schristos       return tls::TLSOPT_NONE;
1683ed0d50c3Schristos 
1684ed0d50c3Schristos     case elfcpp::R_386_TLS_LE:
1685ed0d50c3Schristos     case elfcpp::R_386_TLS_LE_32:
1686ed0d50c3Schristos       // When we already have Local-Exec, there is nothing further we
1687ed0d50c3Schristos       // can do.
1688ed0d50c3Schristos       return tls::TLSOPT_NONE;
1689ed0d50c3Schristos 
1690ed0d50c3Schristos     default:
1691ed0d50c3Schristos       gold_unreachable();
1692ed0d50c3Schristos     }
1693ed0d50c3Schristos }
1694ed0d50c3Schristos 
1695ed0d50c3Schristos // Get the Reference_flags for a particular relocation.
1696ed0d50c3Schristos 
1697ed0d50c3Schristos int
get_reference_flags(unsigned int r_type)1698ed0d50c3Schristos Target_i386::Scan::get_reference_flags(unsigned int r_type)
1699ed0d50c3Schristos {
1700ed0d50c3Schristos   switch (r_type)
1701ed0d50c3Schristos     {
1702ed0d50c3Schristos     case elfcpp::R_386_NONE:
1703ed0d50c3Schristos     case elfcpp::R_386_GNU_VTINHERIT:
1704ed0d50c3Schristos     case elfcpp::R_386_GNU_VTENTRY:
1705ed0d50c3Schristos     case elfcpp::R_386_GOTPC:
1706ed0d50c3Schristos       // No symbol reference.
1707ed0d50c3Schristos       return 0;
1708ed0d50c3Schristos 
1709ed0d50c3Schristos     case elfcpp::R_386_32:
1710ed0d50c3Schristos     case elfcpp::R_386_16:
1711ed0d50c3Schristos     case elfcpp::R_386_8:
1712ed0d50c3Schristos       return Symbol::ABSOLUTE_REF;
1713ed0d50c3Schristos 
1714ed0d50c3Schristos     case elfcpp::R_386_PC32:
1715ed0d50c3Schristos     case elfcpp::R_386_PC16:
1716ed0d50c3Schristos     case elfcpp::R_386_PC8:
1717ed0d50c3Schristos     case elfcpp::R_386_GOTOFF:
1718ed0d50c3Schristos       return Symbol::RELATIVE_REF;
1719ed0d50c3Schristos 
1720ed0d50c3Schristos     case elfcpp::R_386_PLT32:
1721ed0d50c3Schristos       return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
1722ed0d50c3Schristos 
1723ed0d50c3Schristos     case elfcpp::R_386_GOT32:
1724ed0d50c3Schristos     case elfcpp::R_386_GOT32X:
1725ed0d50c3Schristos       // Absolute in GOT.
1726ed0d50c3Schristos       return Symbol::ABSOLUTE_REF;
1727ed0d50c3Schristos 
1728ed0d50c3Schristos     case elfcpp::R_386_TLS_GD:            // Global-dynamic
1729ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
1730ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC_CALL:
1731ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
1732ed0d50c3Schristos     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
1733ed0d50c3Schristos     case elfcpp::R_386_TLS_IE:            // Initial-exec
1734ed0d50c3Schristos     case elfcpp::R_386_TLS_IE_32:
1735ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTIE:
1736ed0d50c3Schristos     case elfcpp::R_386_TLS_LE:            // Local-exec
1737ed0d50c3Schristos     case elfcpp::R_386_TLS_LE_32:
1738ed0d50c3Schristos       return Symbol::TLS_REF;
1739ed0d50c3Schristos 
1740ed0d50c3Schristos     case elfcpp::R_386_COPY:
1741ed0d50c3Schristos     case elfcpp::R_386_GLOB_DAT:
1742ed0d50c3Schristos     case elfcpp::R_386_JUMP_SLOT:
1743ed0d50c3Schristos     case elfcpp::R_386_RELATIVE:
1744ed0d50c3Schristos     case elfcpp::R_386_IRELATIVE:
1745ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF:
1746ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPMOD32:
1747ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPOFF32:
1748ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF32:
1749ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC:
1750ed0d50c3Schristos     case elfcpp::R_386_32PLT:
1751ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_32:
1752ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_PUSH:
1753ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_CALL:
1754ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_POP:
1755ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_32:
1756ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_PUSH:
1757ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_CALL:
1758ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_POP:
1759ed0d50c3Schristos     case elfcpp::R_386_USED_BY_INTEL_200:
1760ed0d50c3Schristos     default:
1761ed0d50c3Schristos       // Not expected.  We will give an error later.
1762ed0d50c3Schristos       return 0;
1763ed0d50c3Schristos     }
1764ed0d50c3Schristos }
1765ed0d50c3Schristos 
1766ed0d50c3Schristos // Report an unsupported relocation against a local symbol.
1767ed0d50c3Schristos 
1768ed0d50c3Schristos void
unsupported_reloc_local(Sized_relobj_file<32,false> * object,unsigned int r_type)1769ed0d50c3Schristos Target_i386::Scan::unsupported_reloc_local(Sized_relobj_file<32, false>* object,
1770ed0d50c3Schristos 					   unsigned int r_type)
1771ed0d50c3Schristos {
1772ed0d50c3Schristos   gold_error(_("%s: unsupported reloc %u against local symbol"),
1773ed0d50c3Schristos 	     object->name().c_str(), r_type);
1774ed0d50c3Schristos }
1775ed0d50c3Schristos 
1776ed0d50c3Schristos // Return whether we need to make a PLT entry for a relocation of a
1777ed0d50c3Schristos // given type against a STT_GNU_IFUNC symbol.
1778ed0d50c3Schristos 
1779ed0d50c3Schristos bool
reloc_needs_plt_for_ifunc(Sized_relobj_file<32,false> * object,unsigned int r_type)1780ed0d50c3Schristos Target_i386::Scan::reloc_needs_plt_for_ifunc(
1781ed0d50c3Schristos     Sized_relobj_file<32, false>* object,
1782ed0d50c3Schristos     unsigned int r_type)
1783ed0d50c3Schristos {
1784ed0d50c3Schristos   int flags = Scan::get_reference_flags(r_type);
1785ed0d50c3Schristos   if (flags & Symbol::TLS_REF)
1786ed0d50c3Schristos     gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
1787ed0d50c3Schristos 	       object->name().c_str(), r_type);
1788ed0d50c3Schristos   return flags != 0;
1789ed0d50c3Schristos }
1790ed0d50c3Schristos 
1791ed0d50c3Schristos // Scan a relocation for a local symbol.
1792ed0d50c3Schristos 
1793ed0d50c3Schristos inline void
local(Symbol_table * symtab,Layout * layout,Target_i386 * target,Sized_relobj_file<32,false> * object,unsigned int data_shndx,Output_section * output_section,const elfcpp::Rel<32,false> & reloc,unsigned int r_type,const elfcpp::Sym<32,false> & lsym,bool is_discarded)1794ed0d50c3Schristos Target_i386::Scan::local(Symbol_table* symtab,
1795ed0d50c3Schristos 			 Layout* layout,
1796ed0d50c3Schristos 			 Target_i386* target,
1797ed0d50c3Schristos 			 Sized_relobj_file<32, false>* object,
1798ed0d50c3Schristos 			 unsigned int data_shndx,
1799ed0d50c3Schristos 			 Output_section* output_section,
1800ed0d50c3Schristos 			 const elfcpp::Rel<32, false>& reloc,
1801ed0d50c3Schristos 			 unsigned int r_type,
1802ed0d50c3Schristos 			 const elfcpp::Sym<32, false>& lsym,
1803ed0d50c3Schristos 			 bool is_discarded)
1804ed0d50c3Schristos {
1805ed0d50c3Schristos   if (is_discarded)
1806ed0d50c3Schristos     return;
1807ed0d50c3Schristos 
1808ed0d50c3Schristos   // A local STT_GNU_IFUNC symbol may require a PLT entry.
1809ed0d50c3Schristos   if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC
1810ed0d50c3Schristos       && this->reloc_needs_plt_for_ifunc(object, r_type))
1811ed0d50c3Schristos     {
1812ed0d50c3Schristos       unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
1813ed0d50c3Schristos       target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
1814ed0d50c3Schristos     }
1815ed0d50c3Schristos 
1816ed0d50c3Schristos   switch (r_type)
1817ed0d50c3Schristos     {
1818ed0d50c3Schristos     case elfcpp::R_386_NONE:
1819ed0d50c3Schristos     case elfcpp::R_386_GNU_VTINHERIT:
1820ed0d50c3Schristos     case elfcpp::R_386_GNU_VTENTRY:
1821ed0d50c3Schristos       break;
1822ed0d50c3Schristos 
1823ed0d50c3Schristos     case elfcpp::R_386_32:
1824ed0d50c3Schristos       // If building a shared library (or a position-independent
1825ed0d50c3Schristos       // executable), we need to create a dynamic relocation for
1826ed0d50c3Schristos       // this location. The relocation applied at link time will
1827ed0d50c3Schristos       // apply the link-time value, so we flag the location with
1828ed0d50c3Schristos       // an R_386_RELATIVE relocation so the dynamic loader can
1829ed0d50c3Schristos       // relocate it easily.
1830ed0d50c3Schristos       if (parameters->options().output_is_position_independent())
1831ed0d50c3Schristos 	{
1832ed0d50c3Schristos 	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
1833ed0d50c3Schristos 	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
1834ed0d50c3Schristos 	  rel_dyn->add_local_relative(object, r_sym, elfcpp::R_386_RELATIVE,
1835ed0d50c3Schristos 				      output_section, data_shndx,
1836ed0d50c3Schristos 				      reloc.get_r_offset());
1837ed0d50c3Schristos 	}
1838ed0d50c3Schristos       break;
1839ed0d50c3Schristos 
1840ed0d50c3Schristos     case elfcpp::R_386_16:
1841ed0d50c3Schristos     case elfcpp::R_386_8:
1842ed0d50c3Schristos       // If building a shared library (or a position-independent
1843ed0d50c3Schristos       // executable), we need to create a dynamic relocation for
1844ed0d50c3Schristos       // this location. Because the addend needs to remain in the
1845ed0d50c3Schristos       // data section, we need to be careful not to apply this
1846ed0d50c3Schristos       // relocation statically.
1847ed0d50c3Schristos       if (parameters->options().output_is_position_independent())
1848ed0d50c3Schristos 	{
1849ed0d50c3Schristos 	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
1850ed0d50c3Schristos 	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
1851ed0d50c3Schristos 	  if (lsym.get_st_type() != elfcpp::STT_SECTION)
1852ed0d50c3Schristos 	    rel_dyn->add_local(object, r_sym, r_type, output_section,
1853ed0d50c3Schristos 			       data_shndx, reloc.get_r_offset());
1854ed0d50c3Schristos 	  else
1855ed0d50c3Schristos 	    {
1856ed0d50c3Schristos 	      gold_assert(lsym.get_st_value() == 0);
1857ed0d50c3Schristos 	      unsigned int shndx = lsym.get_st_shndx();
1858ed0d50c3Schristos 	      bool is_ordinary;
1859ed0d50c3Schristos 	      shndx = object->adjust_sym_shndx(r_sym, shndx,
1860ed0d50c3Schristos 					       &is_ordinary);
1861ed0d50c3Schristos 	      if (!is_ordinary)
1862ed0d50c3Schristos 		object->error(_("section symbol %u has bad shndx %u"),
1863ed0d50c3Schristos 			      r_sym, shndx);
1864ed0d50c3Schristos 	      else
1865ed0d50c3Schristos 		rel_dyn->add_local_section(object, shndx,
1866ed0d50c3Schristos 					   r_type, output_section,
1867ed0d50c3Schristos 					   data_shndx, reloc.get_r_offset());
1868ed0d50c3Schristos 	    }
1869ed0d50c3Schristos 	}
1870ed0d50c3Schristos       break;
1871ed0d50c3Schristos 
1872ed0d50c3Schristos     case elfcpp::R_386_PC32:
1873ed0d50c3Schristos     case elfcpp::R_386_PC16:
1874ed0d50c3Schristos     case elfcpp::R_386_PC8:
1875ed0d50c3Schristos       break;
1876ed0d50c3Schristos 
1877ed0d50c3Schristos     case elfcpp::R_386_PLT32:
1878ed0d50c3Schristos       // Since we know this is a local symbol, we can handle this as a
1879ed0d50c3Schristos       // PC32 reloc.
1880ed0d50c3Schristos       break;
1881ed0d50c3Schristos 
1882ed0d50c3Schristos     case elfcpp::R_386_GOTOFF:
1883ed0d50c3Schristos     case elfcpp::R_386_GOTPC:
1884ed0d50c3Schristos       // We need a GOT section.
1885ed0d50c3Schristos       target->got_section(symtab, layout);
1886ed0d50c3Schristos       break;
1887ed0d50c3Schristos 
1888ed0d50c3Schristos     case elfcpp::R_386_GOT32:
1889ed0d50c3Schristos     case elfcpp::R_386_GOT32X:
1890ed0d50c3Schristos       {
1891ed0d50c3Schristos 	// We need GOT section.
1892ed0d50c3Schristos 	Output_data_got<32, false>* got = target->got_section(symtab, layout);
1893ed0d50c3Schristos 
1894ed0d50c3Schristos 	// If the relocation symbol isn't IFUNC,
1895ed0d50c3Schristos 	// and is local, then we will convert
1896ed0d50c3Schristos 	// mov foo@GOT(%reg), %reg
1897ed0d50c3Schristos 	// to
1898ed0d50c3Schristos 	// lea foo@GOTOFF(%reg), %reg
1899ed0d50c3Schristos 	// in Relocate::relocate.
1900ed0d50c3Schristos 	if (reloc.get_r_offset() >= 2
1901ed0d50c3Schristos 	    && lsym.get_st_type() != elfcpp::STT_GNU_IFUNC)
1902ed0d50c3Schristos 	  {
1903ed0d50c3Schristos 	    section_size_type stype;
1904ed0d50c3Schristos 	    const unsigned char* view = object->section_contents(data_shndx,
1905ed0d50c3Schristos 								 &stype, true);
1906ed0d50c3Schristos 	    if (view[reloc.get_r_offset() - 2] == 0x8b)
1907ed0d50c3Schristos 	      break;
1908ed0d50c3Schristos 	  }
1909ed0d50c3Schristos 
1910ed0d50c3Schristos 	// Otherwise, the symbol requires a GOT entry.
1911ed0d50c3Schristos 	unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
1912ed0d50c3Schristos 
1913ed0d50c3Schristos 	// For a STT_GNU_IFUNC symbol we want the PLT offset.  That
1914ed0d50c3Schristos 	// lets function pointers compare correctly with shared
1915ed0d50c3Schristos 	// libraries.  Otherwise we would need an IRELATIVE reloc.
1916ed0d50c3Schristos 	bool is_new;
1917ed0d50c3Schristos 	if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC)
1918ed0d50c3Schristos 	  is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
1919ed0d50c3Schristos 	else
1920ed0d50c3Schristos 	  is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
1921ed0d50c3Schristos 	if (is_new)
1922ed0d50c3Schristos 	  {
1923ed0d50c3Schristos 	    // If we are generating a shared object, we need to add a
1924ed0d50c3Schristos 	    // dynamic RELATIVE relocation for this symbol's GOT entry.
1925ed0d50c3Schristos 	    if (parameters->options().output_is_position_independent())
1926ed0d50c3Schristos 	      {
1927ed0d50c3Schristos 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
1928ed0d50c3Schristos 		unsigned int got_offset =
1929ed0d50c3Schristos 		  object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
1930ed0d50c3Schristos 		rel_dyn->add_local_relative(object, r_sym,
1931ed0d50c3Schristos 					    elfcpp::R_386_RELATIVE,
1932ed0d50c3Schristos 					    got, got_offset);
1933ed0d50c3Schristos 	      }
1934ed0d50c3Schristos 	  }
1935ed0d50c3Schristos       }
1936ed0d50c3Schristos       break;
1937ed0d50c3Schristos 
1938ed0d50c3Schristos       // These are relocations which should only be seen by the
1939ed0d50c3Schristos       // dynamic linker, and should never be seen here.
1940ed0d50c3Schristos     case elfcpp::R_386_COPY:
1941ed0d50c3Schristos     case elfcpp::R_386_GLOB_DAT:
1942ed0d50c3Schristos     case elfcpp::R_386_JUMP_SLOT:
1943ed0d50c3Schristos     case elfcpp::R_386_RELATIVE:
1944ed0d50c3Schristos     case elfcpp::R_386_IRELATIVE:
1945ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF:
1946ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPMOD32:
1947ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPOFF32:
1948ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF32:
1949ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC:
1950ed0d50c3Schristos       gold_error(_("%s: unexpected reloc %u in object file"),
1951ed0d50c3Schristos 		 object->name().c_str(), r_type);
1952ed0d50c3Schristos       break;
1953ed0d50c3Schristos 
1954ed0d50c3Schristos       // These are initial TLS relocs, which are expected when
1955ed0d50c3Schristos       // linking.
1956ed0d50c3Schristos     case elfcpp::R_386_TLS_GD:            // Global-dynamic
1957ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
1958ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC_CALL:
1959ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
1960ed0d50c3Schristos     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
1961ed0d50c3Schristos     case elfcpp::R_386_TLS_IE:            // Initial-exec
1962ed0d50c3Schristos     case elfcpp::R_386_TLS_IE_32:
1963ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTIE:
1964ed0d50c3Schristos     case elfcpp::R_386_TLS_LE:            // Local-exec
1965ed0d50c3Schristos     case elfcpp::R_386_TLS_LE_32:
1966ed0d50c3Schristos       {
1967ed0d50c3Schristos 	bool output_is_shared = parameters->options().shared();
1968ed0d50c3Schristos 	const tls::Tls_optimization optimized_type
1969ed0d50c3Schristos 	    = Target_i386::optimize_tls_reloc(!output_is_shared, r_type);
1970ed0d50c3Schristos 	switch (r_type)
1971ed0d50c3Schristos 	  {
1972ed0d50c3Schristos 	  case elfcpp::R_386_TLS_GD:          // Global-dynamic
1973ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
1974ed0d50c3Schristos 	      {
1975ed0d50c3Schristos 		// Create a pair of GOT entries for the module index and
1976ed0d50c3Schristos 		// dtv-relative offset.
1977ed0d50c3Schristos 		Output_data_got<32, false>* got
1978ed0d50c3Schristos 		    = target->got_section(symtab, layout);
1979ed0d50c3Schristos 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
1980ed0d50c3Schristos 		unsigned int shndx = lsym.get_st_shndx();
1981ed0d50c3Schristos 		bool is_ordinary;
1982ed0d50c3Schristos 		shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
1983ed0d50c3Schristos 		if (!is_ordinary)
1984ed0d50c3Schristos 		  object->error(_("local symbol %u has bad shndx %u"),
1985ed0d50c3Schristos 			      r_sym, shndx);
1986ed0d50c3Schristos 		else
1987ed0d50c3Schristos 		  got->add_local_pair_with_rel(object, r_sym, shndx,
1988ed0d50c3Schristos 					       GOT_TYPE_TLS_PAIR,
1989ed0d50c3Schristos 					       target->rel_dyn_section(layout),
1990ed0d50c3Schristos 					       elfcpp::R_386_TLS_DTPMOD32);
1991ed0d50c3Schristos 	      }
1992ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
1993ed0d50c3Schristos 	      unsupported_reloc_local(object, r_type);
1994ed0d50c3Schristos 	    break;
1995ed0d50c3Schristos 
1996ed0d50c3Schristos 	  case elfcpp::R_386_TLS_GOTDESC:     // Global-dynamic (from ~oliva)
1997ed0d50c3Schristos 	    target->define_tls_base_symbol(symtab, layout);
1998ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
1999ed0d50c3Schristos 	      {
2000ed0d50c3Schristos 		// Create a double GOT entry with an R_386_TLS_DESC
2001ed0d50c3Schristos 		// reloc.  The R_386_TLS_DESC reloc is resolved
2002ed0d50c3Schristos 		// lazily, so the GOT entry needs to be in an area in
2003ed0d50c3Schristos 		// .got.plt, not .got.  Call got_section to make sure
2004ed0d50c3Schristos 		// the section has been created.
2005ed0d50c3Schristos 		target->got_section(symtab, layout);
2006ed0d50c3Schristos 		Output_data_got<32, false>* got = target->got_tlsdesc_section();
2007ed0d50c3Schristos 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
2008ed0d50c3Schristos 		if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC))
2009ed0d50c3Schristos 		  {
2010ed0d50c3Schristos 		    unsigned int got_offset = got->add_constant(0);
2011ed0d50c3Schristos 		    // The local symbol value is stored in the second
2012ed0d50c3Schristos 		    // GOT entry.
2013ed0d50c3Schristos 		    got->add_local(object, r_sym, GOT_TYPE_TLS_DESC);
2014ed0d50c3Schristos 		    // That set the GOT offset of the local symbol to
2015ed0d50c3Schristos 		    // point to the second entry, but we want it to
2016ed0d50c3Schristos 		    // point to the first.
2017ed0d50c3Schristos 		    object->set_local_got_offset(r_sym, GOT_TYPE_TLS_DESC,
2018ed0d50c3Schristos 						 got_offset);
2019ed0d50c3Schristos 		    Reloc_section* rt = target->rel_tls_desc_section(layout);
2020ed0d50c3Schristos 		    rt->add_absolute(elfcpp::R_386_TLS_DESC, got, got_offset);
2021ed0d50c3Schristos 		  }
2022ed0d50c3Schristos 	      }
2023ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
2024ed0d50c3Schristos 	      unsupported_reloc_local(object, r_type);
2025ed0d50c3Schristos 	    break;
2026ed0d50c3Schristos 
2027ed0d50c3Schristos 	  case elfcpp::R_386_TLS_DESC_CALL:
2028ed0d50c3Schristos 	    break;
2029ed0d50c3Schristos 
2030ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LDM:         // Local-dynamic
2031ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
2032ed0d50c3Schristos 	      {
2033ed0d50c3Schristos 		// Create a GOT entry for the module index.
2034ed0d50c3Schristos 		target->got_mod_index_entry(symtab, layout, object);
2035ed0d50c3Schristos 	      }
2036ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
2037ed0d50c3Schristos 	      unsupported_reloc_local(object, r_type);
2038ed0d50c3Schristos 	    break;
2039ed0d50c3Schristos 
2040ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LDO_32:      // Alternate local-dynamic
2041ed0d50c3Schristos 	    break;
2042ed0d50c3Schristos 
2043ed0d50c3Schristos 	  case elfcpp::R_386_TLS_IE:          // Initial-exec
2044ed0d50c3Schristos 	  case elfcpp::R_386_TLS_IE_32:
2045ed0d50c3Schristos 	  case elfcpp::R_386_TLS_GOTIE:
2046ed0d50c3Schristos 	    layout->set_has_static_tls();
2047ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
2048ed0d50c3Schristos 	      {
2049ed0d50c3Schristos 		// For the R_386_TLS_IE relocation, we need to create a
2050ed0d50c3Schristos 		// dynamic relocation when building a shared library.
2051ed0d50c3Schristos 		if (r_type == elfcpp::R_386_TLS_IE
2052ed0d50c3Schristos 		    && parameters->options().shared())
2053ed0d50c3Schristos 		  {
2054ed0d50c3Schristos 		    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2055ed0d50c3Schristos 		    unsigned int r_sym
2056ed0d50c3Schristos 			= elfcpp::elf_r_sym<32>(reloc.get_r_info());
2057ed0d50c3Schristos 		    rel_dyn->add_local_relative(object, r_sym,
2058ed0d50c3Schristos 						elfcpp::R_386_RELATIVE,
2059ed0d50c3Schristos 						output_section, data_shndx,
2060ed0d50c3Schristos 						reloc.get_r_offset());
2061ed0d50c3Schristos 		  }
2062ed0d50c3Schristos 		// Create a GOT entry for the tp-relative offset.
2063ed0d50c3Schristos 		Output_data_got<32, false>* got
2064ed0d50c3Schristos 		    = target->got_section(symtab, layout);
2065ed0d50c3Schristos 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
2066ed0d50c3Schristos 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
2067ed0d50c3Schristos 					   ? elfcpp::R_386_TLS_TPOFF32
2068ed0d50c3Schristos 					   : elfcpp::R_386_TLS_TPOFF);
2069ed0d50c3Schristos 		unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
2070ed0d50c3Schristos 					 ? GOT_TYPE_TLS_OFFSET
2071ed0d50c3Schristos 					 : GOT_TYPE_TLS_NOFFSET);
2072ed0d50c3Schristos 		got->add_local_with_rel(object, r_sym, got_type,
2073ed0d50c3Schristos 					target->rel_dyn_section(layout),
2074ed0d50c3Schristos 					dyn_r_type);
2075ed0d50c3Schristos 	      }
2076ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
2077ed0d50c3Schristos 	      unsupported_reloc_local(object, r_type);
2078ed0d50c3Schristos 	    break;
2079ed0d50c3Schristos 
2080ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LE:          // Local-exec
2081ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LE_32:
2082ed0d50c3Schristos 	    layout->set_has_static_tls();
2083ed0d50c3Schristos 	    if (output_is_shared)
2084ed0d50c3Schristos 	      {
2085ed0d50c3Schristos 		// We need to create a dynamic relocation.
2086ed0d50c3Schristos 		gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
2087ed0d50c3Schristos 		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
2088ed0d50c3Schristos 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_LE_32
2089ed0d50c3Schristos 					   ? elfcpp::R_386_TLS_TPOFF32
2090ed0d50c3Schristos 					   : elfcpp::R_386_TLS_TPOFF);
2091ed0d50c3Schristos 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2092ed0d50c3Schristos 		rel_dyn->add_local(object, r_sym, dyn_r_type, output_section,
2093ed0d50c3Schristos 				   data_shndx, reloc.get_r_offset());
2094ed0d50c3Schristos 	      }
2095ed0d50c3Schristos 	    break;
2096ed0d50c3Schristos 
2097ed0d50c3Schristos 	  default:
2098ed0d50c3Schristos 	    gold_unreachable();
2099ed0d50c3Schristos 	  }
2100ed0d50c3Schristos       }
2101ed0d50c3Schristos       break;
2102ed0d50c3Schristos 
2103ed0d50c3Schristos     case elfcpp::R_386_32PLT:
2104ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_32:
2105ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_PUSH:
2106ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_CALL:
2107ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_POP:
2108ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_32:
2109ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_PUSH:
2110ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_CALL:
2111ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_POP:
2112ed0d50c3Schristos     case elfcpp::R_386_USED_BY_INTEL_200:
2113ed0d50c3Schristos     default:
2114ed0d50c3Schristos       unsupported_reloc_local(object, r_type);
2115ed0d50c3Schristos       break;
2116ed0d50c3Schristos     }
2117ed0d50c3Schristos }
2118ed0d50c3Schristos 
2119ed0d50c3Schristos // Report an unsupported relocation against a global symbol.
2120ed0d50c3Schristos 
2121ed0d50c3Schristos void
unsupported_reloc_global(Sized_relobj_file<32,false> * object,unsigned int r_type,Symbol * gsym)2122ed0d50c3Schristos Target_i386::Scan::unsupported_reloc_global(
2123ed0d50c3Schristos     Sized_relobj_file<32, false>* object,
2124ed0d50c3Schristos     unsigned int r_type,
2125ed0d50c3Schristos     Symbol* gsym)
2126ed0d50c3Schristos {
2127ed0d50c3Schristos   gold_error(_("%s: unsupported reloc %u against global symbol %s"),
2128ed0d50c3Schristos 	     object->name().c_str(), r_type, gsym->demangled_name().c_str());
2129ed0d50c3Schristos }
2130ed0d50c3Schristos 
2131ed0d50c3Schristos inline bool
possible_function_pointer_reloc(unsigned int r_type)2132ed0d50c3Schristos Target_i386::Scan::possible_function_pointer_reloc(unsigned int r_type)
2133ed0d50c3Schristos {
2134ed0d50c3Schristos   switch (r_type)
2135ed0d50c3Schristos     {
2136ed0d50c3Schristos     case elfcpp::R_386_32:
2137ed0d50c3Schristos     case elfcpp::R_386_16:
2138ed0d50c3Schristos     case elfcpp::R_386_8:
2139ed0d50c3Schristos     case elfcpp::R_386_GOTOFF:
2140ed0d50c3Schristos     case elfcpp::R_386_GOT32:
2141ed0d50c3Schristos     case elfcpp::R_386_GOT32X:
2142ed0d50c3Schristos       {
2143ed0d50c3Schristos 	return true;
2144ed0d50c3Schristos       }
2145ed0d50c3Schristos     default:
2146ed0d50c3Schristos       return false;
2147ed0d50c3Schristos     }
2148ed0d50c3Schristos   return false;
2149ed0d50c3Schristos }
2150ed0d50c3Schristos 
2151ed0d50c3Schristos inline bool
local_reloc_may_be_function_pointer(Symbol_table *,Layout *,Target_i386 *,Sized_relobj_file<32,false> *,unsigned int,Output_section *,const elfcpp::Rel<32,false> &,unsigned int r_type,const elfcpp::Sym<32,false> &)2152ed0d50c3Schristos Target_i386::Scan::local_reloc_may_be_function_pointer(
2153ed0d50c3Schristos   Symbol_table* ,
2154ed0d50c3Schristos   Layout* ,
2155ed0d50c3Schristos   Target_i386* ,
2156ed0d50c3Schristos   Sized_relobj_file<32, false>* ,
2157ed0d50c3Schristos   unsigned int ,
2158ed0d50c3Schristos   Output_section* ,
2159ed0d50c3Schristos   const elfcpp::Rel<32, false>& ,
2160ed0d50c3Schristos   unsigned int r_type,
2161ed0d50c3Schristos   const elfcpp::Sym<32, false>&)
2162ed0d50c3Schristos {
2163ed0d50c3Schristos   return possible_function_pointer_reloc(r_type);
2164ed0d50c3Schristos }
2165ed0d50c3Schristos 
2166ed0d50c3Schristos inline bool
global_reloc_may_be_function_pointer(Symbol_table *,Layout *,Target_i386 *,Sized_relobj_file<32,false> *,unsigned int,Output_section *,const elfcpp::Rel<32,false> &,unsigned int r_type,Symbol *)2167ed0d50c3Schristos Target_i386::Scan::global_reloc_may_be_function_pointer(
2168ed0d50c3Schristos   Symbol_table* ,
2169ed0d50c3Schristos   Layout* ,
2170ed0d50c3Schristos   Target_i386* ,
2171ed0d50c3Schristos   Sized_relobj_file<32, false>* ,
2172ed0d50c3Schristos   unsigned int ,
2173ed0d50c3Schristos   Output_section* ,
2174ed0d50c3Schristos   const elfcpp::Rel<32, false>& ,
2175ed0d50c3Schristos   unsigned int r_type,
2176ed0d50c3Schristos   Symbol*)
2177ed0d50c3Schristos {
2178ed0d50c3Schristos   return possible_function_pointer_reloc(r_type);
2179ed0d50c3Schristos }
2180ed0d50c3Schristos 
2181ed0d50c3Schristos // Scan a relocation for a global symbol.
2182ed0d50c3Schristos 
2183ed0d50c3Schristos inline void
global(Symbol_table * symtab,Layout * layout,Target_i386 * target,Sized_relobj_file<32,false> * object,unsigned int data_shndx,Output_section * output_section,const elfcpp::Rel<32,false> & reloc,unsigned int r_type,Symbol * gsym)2184ed0d50c3Schristos Target_i386::Scan::global(Symbol_table* symtab,
2185ed0d50c3Schristos 				 Layout* layout,
2186ed0d50c3Schristos 				 Target_i386* target,
2187ed0d50c3Schristos 				 Sized_relobj_file<32, false>* object,
2188ed0d50c3Schristos 				 unsigned int data_shndx,
2189ed0d50c3Schristos 				 Output_section* output_section,
2190ed0d50c3Schristos 				 const elfcpp::Rel<32, false>& reloc,
2191ed0d50c3Schristos 				 unsigned int r_type,
2192ed0d50c3Schristos 				 Symbol* gsym)
2193ed0d50c3Schristos {
2194ed0d50c3Schristos   // A STT_GNU_IFUNC symbol may require a PLT entry.
2195ed0d50c3Schristos   if (gsym->type() == elfcpp::STT_GNU_IFUNC
2196ed0d50c3Schristos       && this->reloc_needs_plt_for_ifunc(object, r_type))
2197ed0d50c3Schristos     target->make_plt_entry(symtab, layout, gsym);
2198ed0d50c3Schristos 
2199ed0d50c3Schristos   switch (r_type)
2200ed0d50c3Schristos     {
2201ed0d50c3Schristos     case elfcpp::R_386_NONE:
2202ed0d50c3Schristos     case elfcpp::R_386_GNU_VTINHERIT:
2203ed0d50c3Schristos     case elfcpp::R_386_GNU_VTENTRY:
2204ed0d50c3Schristos       break;
2205ed0d50c3Schristos 
2206ed0d50c3Schristos     case elfcpp::R_386_32:
2207ed0d50c3Schristos     case elfcpp::R_386_16:
2208ed0d50c3Schristos     case elfcpp::R_386_8:
2209ed0d50c3Schristos       {
2210ed0d50c3Schristos 	// Make a PLT entry if necessary.
2211ed0d50c3Schristos 	if (gsym->needs_plt_entry())
2212ed0d50c3Schristos 	  {
2213ed0d50c3Schristos 	    target->make_plt_entry(symtab, layout, gsym);
2214ed0d50c3Schristos 	    // Since this is not a PC-relative relocation, we may be
2215ed0d50c3Schristos 	    // taking the address of a function. In that case we need to
2216ed0d50c3Schristos 	    // set the entry in the dynamic symbol table to the address of
2217ed0d50c3Schristos 	    // the PLT entry.
2218ed0d50c3Schristos 	    if (gsym->is_from_dynobj() && !parameters->options().shared())
2219ed0d50c3Schristos 	      gsym->set_needs_dynsym_value();
2220ed0d50c3Schristos 	  }
2221ed0d50c3Schristos 	// Make a dynamic relocation if necessary.
2222ed0d50c3Schristos 	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
2223ed0d50c3Schristos 	  {
2224ed0d50c3Schristos 	    if (!parameters->options().output_is_position_independent()
2225ed0d50c3Schristos 		&& gsym->may_need_copy_reloc())
2226ed0d50c3Schristos 	      {
2227ed0d50c3Schristos 		target->copy_reloc(symtab, layout, object,
2228ed0d50c3Schristos 				   data_shndx, output_section, gsym, reloc);
2229ed0d50c3Schristos 	      }
2230ed0d50c3Schristos 	    else if (r_type == elfcpp::R_386_32
2231ed0d50c3Schristos 		     && gsym->type() == elfcpp::STT_GNU_IFUNC
2232ed0d50c3Schristos 		     && gsym->can_use_relative_reloc(false)
2233ed0d50c3Schristos 		     && !gsym->is_from_dynobj()
2234ed0d50c3Schristos 		     && !gsym->is_undefined()
2235ed0d50c3Schristos 		     && !gsym->is_preemptible())
2236ed0d50c3Schristos 	      {
2237ed0d50c3Schristos 		// Use an IRELATIVE reloc for a locally defined
2238ed0d50c3Schristos 		// STT_GNU_IFUNC symbol.  This makes a function
2239ed0d50c3Schristos 		// address in a PIE executable match the address in a
2240ed0d50c3Schristos 		// shared library that it links against.
2241ed0d50c3Schristos 		Reloc_section* rel_dyn = target->rel_irelative_section(layout);
2242ed0d50c3Schristos 		rel_dyn->add_symbolless_global_addend(gsym,
2243ed0d50c3Schristos 						      elfcpp::R_386_IRELATIVE,
2244ed0d50c3Schristos 						      output_section,
2245ed0d50c3Schristos 						      object, data_shndx,
2246ed0d50c3Schristos 						      reloc.get_r_offset());
2247ed0d50c3Schristos 	      }
2248ed0d50c3Schristos 	    else if (r_type == elfcpp::R_386_32
2249ed0d50c3Schristos 		     && gsym->can_use_relative_reloc(false))
2250ed0d50c3Schristos 	      {
2251ed0d50c3Schristos 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2252ed0d50c3Schristos 		rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
2253ed0d50c3Schristos 					     output_section, object,
2254ed0d50c3Schristos 					     data_shndx, reloc.get_r_offset());
2255ed0d50c3Schristos 	      }
2256ed0d50c3Schristos 	    else
2257ed0d50c3Schristos 	      {
2258ed0d50c3Schristos 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2259ed0d50c3Schristos 		rel_dyn->add_global(gsym, r_type, output_section, object,
2260ed0d50c3Schristos 				    data_shndx, reloc.get_r_offset());
2261ed0d50c3Schristos 	      }
2262ed0d50c3Schristos 	  }
2263ed0d50c3Schristos       }
2264ed0d50c3Schristos       break;
2265ed0d50c3Schristos 
2266ed0d50c3Schristos     case elfcpp::R_386_PC32:
2267ed0d50c3Schristos     case elfcpp::R_386_PC16:
2268ed0d50c3Schristos     case elfcpp::R_386_PC8:
2269ed0d50c3Schristos       {
2270ed0d50c3Schristos 	// Make a PLT entry if necessary.
2271ed0d50c3Schristos 	if (gsym->needs_plt_entry())
2272ed0d50c3Schristos 	  {
2273ed0d50c3Schristos 	    // These relocations are used for function calls only in
2274ed0d50c3Schristos 	    // non-PIC code.  For a 32-bit relocation in a shared library,
2275ed0d50c3Schristos 	    // we'll need a text relocation anyway, so we can skip the
2276ed0d50c3Schristos 	    // PLT entry and let the dynamic linker bind the call directly
2277ed0d50c3Schristos 	    // to the target.  For smaller relocations, we should use a
2278ed0d50c3Schristos 	    // PLT entry to ensure that the call can reach.
2279ed0d50c3Schristos 	    if (!parameters->options().shared()
2280ed0d50c3Schristos 		|| r_type != elfcpp::R_386_PC32)
2281ed0d50c3Schristos 	      target->make_plt_entry(symtab, layout, gsym);
2282ed0d50c3Schristos 	  }
2283ed0d50c3Schristos 	// Make a dynamic relocation if necessary.
2284ed0d50c3Schristos 	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
2285ed0d50c3Schristos 	  {
2286ed0d50c3Schristos 	    if (parameters->options().output_is_executable()
2287ed0d50c3Schristos 		&& gsym->may_need_copy_reloc())
2288ed0d50c3Schristos 	      {
2289ed0d50c3Schristos 		target->copy_reloc(symtab, layout, object,
2290ed0d50c3Schristos 				   data_shndx, output_section, gsym, reloc);
2291ed0d50c3Schristos 	      }
2292ed0d50c3Schristos 	    else
2293ed0d50c3Schristos 	      {
2294ed0d50c3Schristos 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2295ed0d50c3Schristos 		rel_dyn->add_global(gsym, r_type, output_section, object,
2296ed0d50c3Schristos 				    data_shndx, reloc.get_r_offset());
2297ed0d50c3Schristos 	      }
2298ed0d50c3Schristos 	  }
2299ed0d50c3Schristos       }
2300ed0d50c3Schristos       break;
2301ed0d50c3Schristos 
2302ed0d50c3Schristos     case elfcpp::R_386_GOT32:
2303ed0d50c3Schristos     case elfcpp::R_386_GOT32X:
2304ed0d50c3Schristos       {
2305ed0d50c3Schristos 	// The symbol requires a GOT section.
2306ed0d50c3Schristos 	Output_data_got<32, false>* got = target->got_section(symtab, layout);
2307ed0d50c3Schristos 
2308ed0d50c3Schristos 	// If we convert this from
2309ed0d50c3Schristos 	// mov foo@GOT(%reg), %reg
2310ed0d50c3Schristos 	// to
2311ed0d50c3Schristos 	// lea foo@GOTOFF(%reg), %reg
2312ed0d50c3Schristos 	// in Relocate::relocate, then there is nothing to do here.
2313ed0d50c3Schristos 	if (reloc.get_r_offset() >= 2
2314ed0d50c3Schristos 	    && Target_i386::can_convert_mov_to_lea(gsym))
2315ed0d50c3Schristos 	  {
2316ed0d50c3Schristos 	    section_size_type stype;
2317ed0d50c3Schristos 	    const unsigned char* view = object->section_contents(data_shndx,
2318ed0d50c3Schristos 								 &stype, true);
2319ed0d50c3Schristos 	    if (view[reloc.get_r_offset() - 2] == 0x8b)
2320ed0d50c3Schristos 	      break;
2321ed0d50c3Schristos 	  }
2322ed0d50c3Schristos 
2323ed0d50c3Schristos 	if (gsym->final_value_is_known())
2324ed0d50c3Schristos 	  {
2325ed0d50c3Schristos 	    // For a STT_GNU_IFUNC symbol we want the PLT address.
2326ed0d50c3Schristos 	    if (gsym->type() == elfcpp::STT_GNU_IFUNC)
2327ed0d50c3Schristos 	      got->add_global_plt(gsym, GOT_TYPE_STANDARD);
2328ed0d50c3Schristos 	    else
2329ed0d50c3Schristos 	      got->add_global(gsym, GOT_TYPE_STANDARD);
2330ed0d50c3Schristos 	  }
2331ed0d50c3Schristos 	else
2332ed0d50c3Schristos 	  {
2333ed0d50c3Schristos 	    // If this symbol is not fully resolved, we need to add a
2334ed0d50c3Schristos 	    // GOT entry with a dynamic relocation.
2335ed0d50c3Schristos 	    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2336ed0d50c3Schristos 
2337ed0d50c3Schristos 	    // Use a GLOB_DAT rather than a RELATIVE reloc if:
2338ed0d50c3Schristos 	    //
2339ed0d50c3Schristos 	    // 1) The symbol may be defined in some other module.
2340ed0d50c3Schristos 	    //
2341ed0d50c3Schristos 	    // 2) We are building a shared library and this is a
2342ed0d50c3Schristos 	    // protected symbol; using GLOB_DAT means that the dynamic
2343ed0d50c3Schristos 	    // linker can use the address of the PLT in the main
2344ed0d50c3Schristos 	    // executable when appropriate so that function address
2345ed0d50c3Schristos 	    // comparisons work.
2346ed0d50c3Schristos 	    //
2347ed0d50c3Schristos 	    // 3) This is a STT_GNU_IFUNC symbol in position dependent
2348ed0d50c3Schristos 	    // code, again so that function address comparisons work.
2349ed0d50c3Schristos 	    if (gsym->is_from_dynobj()
2350ed0d50c3Schristos 		|| gsym->is_undefined()
2351ed0d50c3Schristos 		|| gsym->is_preemptible()
2352ed0d50c3Schristos 		|| (gsym->visibility() == elfcpp::STV_PROTECTED
2353ed0d50c3Schristos 		    && parameters->options().shared())
2354ed0d50c3Schristos 		|| (gsym->type() == elfcpp::STT_GNU_IFUNC
2355ed0d50c3Schristos 		    && parameters->options().output_is_position_independent()))
2356ed0d50c3Schristos 	      got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
2357ed0d50c3Schristos 				       rel_dyn, elfcpp::R_386_GLOB_DAT);
2358ed0d50c3Schristos 	    else
2359ed0d50c3Schristos 	      {
2360ed0d50c3Schristos 		// For a STT_GNU_IFUNC symbol we want to write the PLT
2361ed0d50c3Schristos 		// offset into the GOT, so that function pointer
2362ed0d50c3Schristos 		// comparisons work correctly.
2363ed0d50c3Schristos 		bool is_new;
2364ed0d50c3Schristos 		if (gsym->type() != elfcpp::STT_GNU_IFUNC)
2365ed0d50c3Schristos 		  is_new = got->add_global(gsym, GOT_TYPE_STANDARD);
2366ed0d50c3Schristos 		else
2367ed0d50c3Schristos 		  {
2368ed0d50c3Schristos 		    is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD);
2369ed0d50c3Schristos 		    // Tell the dynamic linker to use the PLT address
2370ed0d50c3Schristos 		    // when resolving relocations.
2371ed0d50c3Schristos 		    if (gsym->is_from_dynobj()
2372ed0d50c3Schristos 			&& !parameters->options().shared())
2373ed0d50c3Schristos 		      gsym->set_needs_dynsym_value();
2374ed0d50c3Schristos 		  }
2375ed0d50c3Schristos 		if (is_new)
2376ed0d50c3Schristos 		  {
2377ed0d50c3Schristos 		    unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
2378ed0d50c3Schristos 		    rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
2379ed0d50c3Schristos 						 got, got_off);
2380ed0d50c3Schristos 		  }
2381ed0d50c3Schristos 	      }
2382ed0d50c3Schristos 	  }
2383ed0d50c3Schristos       }
2384ed0d50c3Schristos       break;
2385ed0d50c3Schristos 
2386ed0d50c3Schristos     case elfcpp::R_386_PLT32:
2387ed0d50c3Schristos       // If the symbol is fully resolved, this is just a PC32 reloc.
2388ed0d50c3Schristos       // Otherwise we need a PLT entry.
2389ed0d50c3Schristos       if (gsym->final_value_is_known())
2390ed0d50c3Schristos 	break;
2391ed0d50c3Schristos       // If building a shared library, we can also skip the PLT entry
2392ed0d50c3Schristos       // if the symbol is defined in the output file and is protected
2393ed0d50c3Schristos       // or hidden.
2394ed0d50c3Schristos       if (gsym->is_defined()
2395ed0d50c3Schristos 	  && !gsym->is_from_dynobj()
2396ed0d50c3Schristos 	  && !gsym->is_preemptible())
2397ed0d50c3Schristos 	break;
2398ed0d50c3Schristos       target->make_plt_entry(symtab, layout, gsym);
2399ed0d50c3Schristos       break;
2400ed0d50c3Schristos 
2401ed0d50c3Schristos     case elfcpp::R_386_GOTOFF:
2402ed0d50c3Schristos       // A GOT-relative reference must resolve locally.
2403ed0d50c3Schristos       if (!gsym->is_defined())
2404ed0d50c3Schristos         gold_error(_("%s: relocation R_386_GOTOFF against undefined symbol %s"
2405ed0d50c3Schristos 		     " cannot be used when making a shared object"),
2406ed0d50c3Schristos 		   object->name().c_str(), gsym->name());
2407ed0d50c3Schristos       else if (gsym->is_from_dynobj())
2408ed0d50c3Schristos         gold_error(_("%s: relocation R_386_GOTOFF against external symbol %s"
2409ed0d50c3Schristos 		     " cannot be used when making a shared object"),
2410ed0d50c3Schristos 		   object->name().c_str(), gsym->name());
2411ed0d50c3Schristos       else if (gsym->is_preemptible())
2412ed0d50c3Schristos         gold_error(_("%s: relocation R_386_GOTOFF against preemptible symbol %s"
2413ed0d50c3Schristos 		     " cannot be used when making a shared object"),
2414ed0d50c3Schristos 		   object->name().c_str(), gsym->name());
2415ed0d50c3Schristos       // We need a GOT section.
2416ed0d50c3Schristos       target->got_section(symtab, layout);
2417ed0d50c3Schristos       break;
2418ed0d50c3Schristos 
2419ed0d50c3Schristos     case elfcpp::R_386_GOTPC:
2420ed0d50c3Schristos       // We need a GOT section.
2421ed0d50c3Schristos       target->got_section(symtab, layout);
2422ed0d50c3Schristos       break;
2423ed0d50c3Schristos 
2424ed0d50c3Schristos       // These are relocations which should only be seen by the
2425ed0d50c3Schristos       // dynamic linker, and should never be seen here.
2426ed0d50c3Schristos     case elfcpp::R_386_COPY:
2427ed0d50c3Schristos     case elfcpp::R_386_GLOB_DAT:
2428ed0d50c3Schristos     case elfcpp::R_386_JUMP_SLOT:
2429ed0d50c3Schristos     case elfcpp::R_386_RELATIVE:
2430ed0d50c3Schristos     case elfcpp::R_386_IRELATIVE:
2431ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF:
2432ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPMOD32:
2433ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPOFF32:
2434ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF32:
2435ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC:
2436ed0d50c3Schristos       gold_error(_("%s: unexpected reloc %u in object file"),
2437ed0d50c3Schristos 		 object->name().c_str(), r_type);
2438ed0d50c3Schristos       break;
2439ed0d50c3Schristos 
2440ed0d50c3Schristos       // These are initial tls relocs, which are expected when
2441ed0d50c3Schristos       // linking.
2442ed0d50c3Schristos     case elfcpp::R_386_TLS_GD:            // Global-dynamic
2443ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
2444ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC_CALL:
2445ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
2446ed0d50c3Schristos     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
2447ed0d50c3Schristos     case elfcpp::R_386_TLS_IE:            // Initial-exec
2448ed0d50c3Schristos     case elfcpp::R_386_TLS_IE_32:
2449ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTIE:
2450ed0d50c3Schristos     case elfcpp::R_386_TLS_LE:            // Local-exec
2451ed0d50c3Schristos     case elfcpp::R_386_TLS_LE_32:
2452ed0d50c3Schristos       {
2453ed0d50c3Schristos 	const bool is_final = gsym->final_value_is_known();
2454ed0d50c3Schristos 	const tls::Tls_optimization optimized_type
2455ed0d50c3Schristos 	    = Target_i386::optimize_tls_reloc(is_final, r_type);
2456ed0d50c3Schristos 	switch (r_type)
2457ed0d50c3Schristos 	  {
2458ed0d50c3Schristos 	  case elfcpp::R_386_TLS_GD:          // Global-dynamic
2459ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
2460ed0d50c3Schristos 	      {
2461ed0d50c3Schristos 		// Create a pair of GOT entries for the module index and
2462ed0d50c3Schristos 		// dtv-relative offset.
2463ed0d50c3Schristos 		Output_data_got<32, false>* got
2464ed0d50c3Schristos 		    = target->got_section(symtab, layout);
2465ed0d50c3Schristos 		got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
2466ed0d50c3Schristos 					     target->rel_dyn_section(layout),
2467ed0d50c3Schristos 					     elfcpp::R_386_TLS_DTPMOD32,
2468ed0d50c3Schristos 					     elfcpp::R_386_TLS_DTPOFF32);
2469ed0d50c3Schristos 	      }
2470ed0d50c3Schristos 	    else if (optimized_type == tls::TLSOPT_TO_IE)
2471ed0d50c3Schristos 	      {
2472ed0d50c3Schristos 		// Create a GOT entry for the tp-relative offset.
2473ed0d50c3Schristos 		Output_data_got<32, false>* got
2474ed0d50c3Schristos 		    = target->got_section(symtab, layout);
2475ed0d50c3Schristos 		got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
2476ed0d50c3Schristos 					 target->rel_dyn_section(layout),
2477ed0d50c3Schristos 					 elfcpp::R_386_TLS_TPOFF);
2478ed0d50c3Schristos 	      }
2479ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
2480ed0d50c3Schristos 	      unsupported_reloc_global(object, r_type, gsym);
2481ed0d50c3Schristos 	    break;
2482ed0d50c3Schristos 
2483ed0d50c3Schristos 	  case elfcpp::R_386_TLS_GOTDESC:     // Global-dynamic (~oliva url)
2484ed0d50c3Schristos 	    target->define_tls_base_symbol(symtab, layout);
2485ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
2486ed0d50c3Schristos 	      {
2487ed0d50c3Schristos 		// Create a double GOT entry with an R_386_TLS_DESC
2488ed0d50c3Schristos 		// reloc.  The R_386_TLS_DESC reloc is resolved
2489ed0d50c3Schristos 		// lazily, so the GOT entry needs to be in an area in
2490ed0d50c3Schristos 		// .got.plt, not .got.  Call got_section to make sure
2491ed0d50c3Schristos 		// the section has been created.
2492ed0d50c3Schristos 		target->got_section(symtab, layout);
2493ed0d50c3Schristos 		Output_data_got<32, false>* got = target->got_tlsdesc_section();
2494ed0d50c3Schristos 		Reloc_section* rt = target->rel_tls_desc_section(layout);
2495ed0d50c3Schristos 		got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt,
2496ed0d50c3Schristos 					     elfcpp::R_386_TLS_DESC, 0);
2497ed0d50c3Schristos 	      }
2498ed0d50c3Schristos 	    else if (optimized_type == tls::TLSOPT_TO_IE)
2499ed0d50c3Schristos 	      {
2500ed0d50c3Schristos 		// Create a GOT entry for the tp-relative offset.
2501ed0d50c3Schristos 		Output_data_got<32, false>* got
2502ed0d50c3Schristos 		    = target->got_section(symtab, layout);
2503ed0d50c3Schristos 		got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
2504ed0d50c3Schristos 					 target->rel_dyn_section(layout),
2505ed0d50c3Schristos 					 elfcpp::R_386_TLS_TPOFF);
2506ed0d50c3Schristos 	      }
2507ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
2508ed0d50c3Schristos 	      unsupported_reloc_global(object, r_type, gsym);
2509ed0d50c3Schristos 	    break;
2510ed0d50c3Schristos 
2511ed0d50c3Schristos 	  case elfcpp::R_386_TLS_DESC_CALL:
2512ed0d50c3Schristos 	    break;
2513ed0d50c3Schristos 
2514ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LDM:         // Local-dynamic
2515ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
2516ed0d50c3Schristos 	      {
2517ed0d50c3Schristos 		// Create a GOT entry for the module index.
2518ed0d50c3Schristos 		target->got_mod_index_entry(symtab, layout, object);
2519ed0d50c3Schristos 	      }
2520ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
2521ed0d50c3Schristos 	      unsupported_reloc_global(object, r_type, gsym);
2522ed0d50c3Schristos 	    break;
2523ed0d50c3Schristos 
2524ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LDO_32:      // Alternate local-dynamic
2525ed0d50c3Schristos 	    break;
2526ed0d50c3Schristos 
2527ed0d50c3Schristos 	  case elfcpp::R_386_TLS_IE:          // Initial-exec
2528ed0d50c3Schristos 	  case elfcpp::R_386_TLS_IE_32:
2529ed0d50c3Schristos 	  case elfcpp::R_386_TLS_GOTIE:
2530ed0d50c3Schristos 	    layout->set_has_static_tls();
2531ed0d50c3Schristos 	    if (optimized_type == tls::TLSOPT_NONE)
2532ed0d50c3Schristos 	      {
2533ed0d50c3Schristos 		// For the R_386_TLS_IE relocation, we need to create a
2534ed0d50c3Schristos 		// dynamic relocation when building a shared library.
2535ed0d50c3Schristos 		if (r_type == elfcpp::R_386_TLS_IE
2536ed0d50c3Schristos 		    && parameters->options().shared())
2537ed0d50c3Schristos 		  {
2538ed0d50c3Schristos 		    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2539ed0d50c3Schristos 		    rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE,
2540ed0d50c3Schristos 						 output_section, object,
2541ed0d50c3Schristos 						 data_shndx,
2542ed0d50c3Schristos 						 reloc.get_r_offset());
2543ed0d50c3Schristos 		  }
2544ed0d50c3Schristos 		// Create a GOT entry for the tp-relative offset.
2545ed0d50c3Schristos 		Output_data_got<32, false>* got
2546ed0d50c3Schristos 		    = target->got_section(symtab, layout);
2547ed0d50c3Schristos 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
2548ed0d50c3Schristos 					   ? elfcpp::R_386_TLS_TPOFF32
2549ed0d50c3Schristos 					   : elfcpp::R_386_TLS_TPOFF);
2550ed0d50c3Schristos 		unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
2551ed0d50c3Schristos 					 ? GOT_TYPE_TLS_OFFSET
2552ed0d50c3Schristos 					 : GOT_TYPE_TLS_NOFFSET);
2553ed0d50c3Schristos 		got->add_global_with_rel(gsym, got_type,
2554ed0d50c3Schristos 					 target->rel_dyn_section(layout),
2555ed0d50c3Schristos 					 dyn_r_type);
2556ed0d50c3Schristos 	      }
2557ed0d50c3Schristos 	    else if (optimized_type != tls::TLSOPT_TO_LE)
2558ed0d50c3Schristos 	      unsupported_reloc_global(object, r_type, gsym);
2559ed0d50c3Schristos 	    break;
2560ed0d50c3Schristos 
2561ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LE:          // Local-exec
2562ed0d50c3Schristos 	  case elfcpp::R_386_TLS_LE_32:
2563ed0d50c3Schristos 	    layout->set_has_static_tls();
2564ed0d50c3Schristos 	    if (parameters->options().shared())
2565ed0d50c3Schristos 	      {
2566ed0d50c3Schristos 		// We need to create a dynamic relocation.
2567ed0d50c3Schristos 		unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_LE_32
2568ed0d50c3Schristos 					   ? elfcpp::R_386_TLS_TPOFF32
2569ed0d50c3Schristos 					   : elfcpp::R_386_TLS_TPOFF);
2570ed0d50c3Schristos 		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
2571ed0d50c3Schristos 		rel_dyn->add_global(gsym, dyn_r_type, output_section, object,
2572ed0d50c3Schristos 				    data_shndx, reloc.get_r_offset());
2573ed0d50c3Schristos 	      }
2574ed0d50c3Schristos 	    break;
2575ed0d50c3Schristos 
2576ed0d50c3Schristos 	  default:
2577ed0d50c3Schristos 	    gold_unreachable();
2578ed0d50c3Schristos 	  }
2579ed0d50c3Schristos       }
2580ed0d50c3Schristos       break;
2581ed0d50c3Schristos 
2582ed0d50c3Schristos     case elfcpp::R_386_32PLT:
2583ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_32:
2584ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_PUSH:
2585ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_CALL:
2586ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_POP:
2587ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_32:
2588ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_PUSH:
2589ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_CALL:
2590ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_POP:
2591ed0d50c3Schristos     case elfcpp::R_386_USED_BY_INTEL_200:
2592ed0d50c3Schristos     default:
2593ed0d50c3Schristos       unsupported_reloc_global(object, r_type, gsym);
2594ed0d50c3Schristos       break;
2595ed0d50c3Schristos     }
2596ed0d50c3Schristos }
2597ed0d50c3Schristos 
2598ed0d50c3Schristos // Process relocations for gc.
2599ed0d50c3Schristos 
2600ed0d50c3Schristos void
gc_process_relocs(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * object,unsigned int data_shndx,unsigned int,const unsigned char * prelocs,size_t reloc_count,Output_section * output_section,bool needs_special_offset_handling,size_t local_symbol_count,const unsigned char * plocal_symbols)2601ed0d50c3Schristos Target_i386::gc_process_relocs(Symbol_table* symtab,
2602ed0d50c3Schristos 				      Layout* layout,
2603ed0d50c3Schristos 				      Sized_relobj_file<32, false>* object,
2604ed0d50c3Schristos 				      unsigned int data_shndx,
2605ed0d50c3Schristos 				      unsigned int,
2606ed0d50c3Schristos 				      const unsigned char* prelocs,
2607ed0d50c3Schristos 				      size_t reloc_count,
2608ed0d50c3Schristos 				      Output_section* output_section,
2609ed0d50c3Schristos 				      bool needs_special_offset_handling,
2610ed0d50c3Schristos 				      size_t local_symbol_count,
2611ed0d50c3Schristos 				      const unsigned char* plocal_symbols)
2612ed0d50c3Schristos {
2613ed0d50c3Schristos   gold::gc_process_relocs<32, false, Target_i386, Scan, Classify_reloc>(
2614ed0d50c3Schristos     symtab,
2615ed0d50c3Schristos     layout,
2616ed0d50c3Schristos     this,
2617ed0d50c3Schristos     object,
2618ed0d50c3Schristos     data_shndx,
2619ed0d50c3Schristos     prelocs,
2620ed0d50c3Schristos     reloc_count,
2621ed0d50c3Schristos     output_section,
2622ed0d50c3Schristos     needs_special_offset_handling,
2623ed0d50c3Schristos     local_symbol_count,
2624ed0d50c3Schristos     plocal_symbols);
2625ed0d50c3Schristos }
2626ed0d50c3Schristos 
2627ed0d50c3Schristos // Scan relocations for a section.
2628ed0d50c3Schristos 
2629ed0d50c3Schristos void
scan_relocs(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * object,unsigned int data_shndx,unsigned int sh_type,const unsigned char * prelocs,size_t reloc_count,Output_section * output_section,bool needs_special_offset_handling,size_t local_symbol_count,const unsigned char * plocal_symbols)2630ed0d50c3Schristos Target_i386::scan_relocs(Symbol_table* symtab,
2631ed0d50c3Schristos 				Layout* layout,
2632ed0d50c3Schristos 				Sized_relobj_file<32, false>* object,
2633ed0d50c3Schristos 				unsigned int data_shndx,
2634ed0d50c3Schristos 				unsigned int sh_type,
2635ed0d50c3Schristos 				const unsigned char* prelocs,
2636ed0d50c3Schristos 				size_t reloc_count,
2637ed0d50c3Schristos 				Output_section* output_section,
2638ed0d50c3Schristos 				bool needs_special_offset_handling,
2639ed0d50c3Schristos 				size_t local_symbol_count,
2640ed0d50c3Schristos 				const unsigned char* plocal_symbols)
2641ed0d50c3Schristos {
2642ed0d50c3Schristos   if (sh_type == elfcpp::SHT_RELA)
2643ed0d50c3Schristos     {
2644ed0d50c3Schristos       gold_error(_("%s: unsupported RELA reloc section"),
2645ed0d50c3Schristos 		 object->name().c_str());
2646ed0d50c3Schristos       return;
2647ed0d50c3Schristos     }
2648ed0d50c3Schristos 
2649ed0d50c3Schristos   gold::scan_relocs<32, false, Target_i386, Scan, Classify_reloc>(
2650ed0d50c3Schristos     symtab,
2651ed0d50c3Schristos     layout,
2652ed0d50c3Schristos     this,
2653ed0d50c3Schristos     object,
2654ed0d50c3Schristos     data_shndx,
2655ed0d50c3Schristos     prelocs,
2656ed0d50c3Schristos     reloc_count,
2657ed0d50c3Schristos     output_section,
2658ed0d50c3Schristos     needs_special_offset_handling,
2659ed0d50c3Schristos     local_symbol_count,
2660ed0d50c3Schristos     plocal_symbols);
2661ed0d50c3Schristos }
2662ed0d50c3Schristos 
2663ed0d50c3Schristos // Finalize the sections.
2664ed0d50c3Schristos 
2665ed0d50c3Schristos void
do_finalize_sections(Layout * layout,const Input_objects *,Symbol_table * symtab)2666ed0d50c3Schristos Target_i386::do_finalize_sections(
2667ed0d50c3Schristos     Layout* layout,
2668ed0d50c3Schristos     const Input_objects*,
2669ed0d50c3Schristos     Symbol_table* symtab)
2670ed0d50c3Schristos {
2671ed0d50c3Schristos   const Reloc_section* rel_plt = (this->plt_ == NULL
2672ed0d50c3Schristos 				  ? NULL
2673ed0d50c3Schristos 				  : this->plt_->rel_plt());
2674ed0d50c3Schristos   layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
2675ed0d50c3Schristos 				  this->rel_dyn_, true, false);
2676ed0d50c3Schristos 
2677ed0d50c3Schristos   // Emit any relocs we saved in an attempt to avoid generating COPY
2678ed0d50c3Schristos   // relocs.
2679ed0d50c3Schristos   if (this->copy_relocs_.any_saved_relocs())
2680ed0d50c3Schristos     this->copy_relocs_.emit(this->rel_dyn_section(layout));
2681ed0d50c3Schristos 
2682ed0d50c3Schristos   // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
2683ed0d50c3Schristos   // the .got.plt section.
2684ed0d50c3Schristos   Symbol* sym = this->global_offset_table_;
2685ed0d50c3Schristos   if (sym != NULL)
2686ed0d50c3Schristos     {
2687ed0d50c3Schristos       uint32_t data_size = this->got_plt_->current_data_size();
2688ed0d50c3Schristos       symtab->get_sized_symbol<32>(sym)->set_symsize(data_size);
2689ed0d50c3Schristos     }
2690ed0d50c3Schristos 
2691ed0d50c3Schristos   if (parameters->doing_static_link()
2692ed0d50c3Schristos       && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
2693ed0d50c3Schristos     {
2694ed0d50c3Schristos       // If linking statically, make sure that the __rel_iplt symbols
2695ed0d50c3Schristos       // were defined if necessary, even if we didn't create a PLT.
2696ed0d50c3Schristos       static const Define_symbol_in_segment syms[] =
2697ed0d50c3Schristos 	{
2698ed0d50c3Schristos 	  {
2699ed0d50c3Schristos 	    "__rel_iplt_start",		// name
2700ed0d50c3Schristos 	    elfcpp::PT_LOAD,		// segment_type
2701ed0d50c3Schristos 	    elfcpp::PF_W,		// segment_flags_set
2702ed0d50c3Schristos 	    elfcpp::PF(0),		// segment_flags_clear
2703ed0d50c3Schristos 	    0,				// value
2704ed0d50c3Schristos 	    0,				// size
2705ed0d50c3Schristos 	    elfcpp::STT_NOTYPE,		// type
2706ed0d50c3Schristos 	    elfcpp::STB_GLOBAL,		// binding
2707ed0d50c3Schristos 	    elfcpp::STV_HIDDEN,		// visibility
2708ed0d50c3Schristos 	    0,				// nonvis
2709ed0d50c3Schristos 	    Symbol::SEGMENT_START,	// offset_from_base
2710ed0d50c3Schristos 	    true			// only_if_ref
2711ed0d50c3Schristos 	  },
2712ed0d50c3Schristos 	  {
2713ed0d50c3Schristos 	    "__rel_iplt_end",		// name
2714ed0d50c3Schristos 	    elfcpp::PT_LOAD,		// segment_type
2715ed0d50c3Schristos 	    elfcpp::PF_W,		// segment_flags_set
2716ed0d50c3Schristos 	    elfcpp::PF(0),		// segment_flags_clear
2717ed0d50c3Schristos 	    0,				// value
2718ed0d50c3Schristos 	    0,				// size
2719ed0d50c3Schristos 	    elfcpp::STT_NOTYPE,		// type
2720ed0d50c3Schristos 	    elfcpp::STB_GLOBAL,		// binding
2721ed0d50c3Schristos 	    elfcpp::STV_HIDDEN,		// visibility
2722ed0d50c3Schristos 	    0,				// nonvis
2723ed0d50c3Schristos 	    Symbol::SEGMENT_START,	// offset_from_base
2724ed0d50c3Schristos 	    true			// only_if_ref
2725ed0d50c3Schristos 	  }
2726ed0d50c3Schristos 	};
2727ed0d50c3Schristos 
2728ed0d50c3Schristos       symtab->define_symbols(layout, 2, syms,
2729ed0d50c3Schristos 			     layout->script_options()->saw_sections_clause());
2730ed0d50c3Schristos     }
2731ed0d50c3Schristos }
2732ed0d50c3Schristos 
2733ed0d50c3Schristos // Return whether a direct absolute static relocation needs to be applied.
2734ed0d50c3Schristos // In cases where Scan::local() or Scan::global() has created
2735ed0d50c3Schristos // a dynamic relocation other than R_386_RELATIVE, the addend
2736ed0d50c3Schristos // of the relocation is carried in the data, and we must not
2737ed0d50c3Schristos // apply the static relocation.
2738ed0d50c3Schristos 
2739ed0d50c3Schristos inline bool
should_apply_static_reloc(const Sized_symbol<32> * gsym,unsigned int r_type,bool is_32bit,Output_section * output_section)2740ed0d50c3Schristos Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
2741ed0d50c3Schristos 						 unsigned int r_type,
2742ed0d50c3Schristos 						 bool is_32bit,
2743ed0d50c3Schristos 						 Output_section* output_section)
2744ed0d50c3Schristos {
2745ed0d50c3Schristos   // If the output section is not allocated, then we didn't call
2746ed0d50c3Schristos   // scan_relocs, we didn't create a dynamic reloc, and we must apply
2747ed0d50c3Schristos   // the reloc here.
2748ed0d50c3Schristos   if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
2749ed0d50c3Schristos     return true;
2750ed0d50c3Schristos 
2751ed0d50c3Schristos   int ref_flags = Scan::get_reference_flags(r_type);
2752ed0d50c3Schristos 
2753ed0d50c3Schristos   // For local symbols, we will have created a non-RELATIVE dynamic
2754ed0d50c3Schristos   // relocation only if (a) the output is position independent,
2755ed0d50c3Schristos   // (b) the relocation is absolute (not pc- or segment-relative), and
2756ed0d50c3Schristos   // (c) the relocation is not 32 bits wide.
2757ed0d50c3Schristos   if (gsym == NULL)
2758ed0d50c3Schristos     return !(parameters->options().output_is_position_independent()
2759ed0d50c3Schristos 	     && (ref_flags & Symbol::ABSOLUTE_REF)
2760ed0d50c3Schristos 	     && !is_32bit);
2761ed0d50c3Schristos 
2762ed0d50c3Schristos   // For global symbols, we use the same helper routines used in the
2763ed0d50c3Schristos   // scan pass.  If we did not create a dynamic relocation, or if we
2764ed0d50c3Schristos   // created a RELATIVE dynamic relocation, we should apply the static
2765ed0d50c3Schristos   // relocation.
2766ed0d50c3Schristos   bool has_dyn = gsym->needs_dynamic_reloc(ref_flags);
2767ed0d50c3Schristos   bool is_rel = (ref_flags & Symbol::ABSOLUTE_REF)
2768ed0d50c3Schristos 		&& gsym->can_use_relative_reloc(ref_flags
2769ed0d50c3Schristos 						& Symbol::FUNCTION_CALL);
2770ed0d50c3Schristos   return !has_dyn || is_rel;
2771ed0d50c3Schristos }
2772ed0d50c3Schristos 
2773ed0d50c3Schristos // Perform a relocation.
2774ed0d50c3Schristos 
2775ed0d50c3Schristos inline bool
relocate(const Relocate_info<32,false> * relinfo,unsigned int,Target_i386 * target,Output_section * output_section,size_t relnum,const unsigned char * preloc,const Sized_symbol<32> * gsym,const Symbol_value<32> * psymval,unsigned char * view,elfcpp::Elf_types<32>::Elf_Addr address,section_size_type view_size)2776ed0d50c3Schristos Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
2777ed0d50c3Schristos 				unsigned int,
2778ed0d50c3Schristos 				Target_i386* target,
2779ed0d50c3Schristos 				Output_section* output_section,
2780ed0d50c3Schristos 				size_t relnum,
2781ed0d50c3Schristos 				const unsigned char* preloc,
2782ed0d50c3Schristos 				const Sized_symbol<32>* gsym,
2783ed0d50c3Schristos 				const Symbol_value<32>* psymval,
2784ed0d50c3Schristos 				unsigned char* view,
2785ed0d50c3Schristos 				elfcpp::Elf_types<32>::Elf_Addr address,
2786ed0d50c3Schristos 				section_size_type view_size)
2787ed0d50c3Schristos {
2788ed0d50c3Schristos   const elfcpp::Rel<32, false> rel(preloc);
2789ed0d50c3Schristos   unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info());
2790ed0d50c3Schristos 
2791ed0d50c3Schristos   if (this->skip_call_tls_get_addr_)
2792ed0d50c3Schristos     {
2793ed0d50c3Schristos       if ((r_type != elfcpp::R_386_PLT32
2794ed0d50c3Schristos 	   && r_type != elfcpp::R_386_GOT32X
2795ed0d50c3Schristos 	   && r_type != elfcpp::R_386_PC32)
2796ed0d50c3Schristos 	  || gsym == NULL
2797ed0d50c3Schristos 	  || strcmp(gsym->name(), "___tls_get_addr") != 0)
279806324dcfSchristos 	{
2799ed0d50c3Schristos 	  gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
2800ed0d50c3Schristos 				 _("missing expected TLS relocation"));
280106324dcfSchristos 	  this->skip_call_tls_get_addr_ = false;
280206324dcfSchristos 	}
2803ed0d50c3Schristos       else
2804ed0d50c3Schristos 	{
2805ed0d50c3Schristos 	  this->skip_call_tls_get_addr_ = false;
2806ed0d50c3Schristos 	  return false;
2807ed0d50c3Schristos 	}
2808ed0d50c3Schristos     }
2809ed0d50c3Schristos 
2810ed0d50c3Schristos   if (view == NULL)
2811ed0d50c3Schristos     return true;
2812ed0d50c3Schristos 
2813ed0d50c3Schristos   const Sized_relobj_file<32, false>* object = relinfo->object;
2814ed0d50c3Schristos 
2815ed0d50c3Schristos   // Pick the value to use for symbols defined in shared objects.
2816ed0d50c3Schristos   Symbol_value<32> symval;
2817ed0d50c3Schristos   if (gsym != NULL
2818ed0d50c3Schristos       && gsym->type() == elfcpp::STT_GNU_IFUNC
2819ed0d50c3Schristos       && r_type == elfcpp::R_386_32
2820ed0d50c3Schristos       && gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))
2821ed0d50c3Schristos       && gsym->can_use_relative_reloc(false)
2822ed0d50c3Schristos       && !gsym->is_from_dynobj()
2823ed0d50c3Schristos       && !gsym->is_undefined()
2824ed0d50c3Schristos       && !gsym->is_preemptible())
2825ed0d50c3Schristos     {
2826ed0d50c3Schristos       // In this case we are generating a R_386_IRELATIVE reloc.  We
2827ed0d50c3Schristos       // want to use the real value of the symbol, not the PLT offset.
2828ed0d50c3Schristos     }
2829ed0d50c3Schristos   else if (gsym != NULL
2830ed0d50c3Schristos 	   && gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
2831ed0d50c3Schristos     {
2832ed0d50c3Schristos       symval.set_output_value(target->plt_address_for_global(gsym));
2833ed0d50c3Schristos       psymval = &symval;
2834ed0d50c3Schristos     }
2835ed0d50c3Schristos   else if (gsym == NULL && psymval->is_ifunc_symbol())
2836ed0d50c3Schristos     {
2837ed0d50c3Schristos       unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
2838ed0d50c3Schristos       if (object->local_has_plt_offset(r_sym))
2839ed0d50c3Schristos 	{
2840ed0d50c3Schristos 	  symval.set_output_value(target->plt_address_for_local(object, r_sym));
2841ed0d50c3Schristos 	  psymval = &symval;
2842ed0d50c3Schristos 	}
2843ed0d50c3Schristos     }
2844ed0d50c3Schristos 
2845ed0d50c3Schristos   bool baseless;
2846ed0d50c3Schristos 
2847ed0d50c3Schristos   switch (r_type)
2848ed0d50c3Schristos     {
2849ed0d50c3Schristos     case elfcpp::R_386_NONE:
2850ed0d50c3Schristos     case elfcpp::R_386_GNU_VTINHERIT:
2851ed0d50c3Schristos     case elfcpp::R_386_GNU_VTENTRY:
2852ed0d50c3Schristos       break;
2853ed0d50c3Schristos 
2854ed0d50c3Schristos     case elfcpp::R_386_32:
2855ed0d50c3Schristos       if (should_apply_static_reloc(gsym, r_type, true, output_section))
2856ed0d50c3Schristos 	Relocate_functions<32, false>::rel32(view, object, psymval);
2857ed0d50c3Schristos       break;
2858ed0d50c3Schristos 
2859ed0d50c3Schristos     case elfcpp::R_386_PC32:
2860ed0d50c3Schristos       if (should_apply_static_reloc(gsym, r_type, true, output_section))
2861ed0d50c3Schristos 	Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
2862ed0d50c3Schristos       break;
2863ed0d50c3Schristos 
2864ed0d50c3Schristos     case elfcpp::R_386_16:
2865ed0d50c3Schristos       if (should_apply_static_reloc(gsym, r_type, false, output_section))
2866ed0d50c3Schristos 	Relocate_functions<32, false>::rel16(view, object, psymval);
2867ed0d50c3Schristos       break;
2868ed0d50c3Schristos 
2869ed0d50c3Schristos     case elfcpp::R_386_PC16:
2870ed0d50c3Schristos       if (should_apply_static_reloc(gsym, r_type, false, output_section))
2871ed0d50c3Schristos 	Relocate_functions<32, false>::pcrel16(view, object, psymval, address);
2872ed0d50c3Schristos       break;
2873ed0d50c3Schristos 
2874ed0d50c3Schristos     case elfcpp::R_386_8:
2875ed0d50c3Schristos       if (should_apply_static_reloc(gsym, r_type, false, output_section))
2876ed0d50c3Schristos 	Relocate_functions<32, false>::rel8(view, object, psymval);
2877ed0d50c3Schristos       break;
2878ed0d50c3Schristos 
2879ed0d50c3Schristos     case elfcpp::R_386_PC8:
2880ed0d50c3Schristos       if (should_apply_static_reloc(gsym, r_type, false, output_section))
2881ed0d50c3Schristos 	Relocate_functions<32, false>::pcrel8(view, object, psymval, address);
2882ed0d50c3Schristos       break;
2883ed0d50c3Schristos 
2884ed0d50c3Schristos     case elfcpp::R_386_PLT32:
2885ed0d50c3Schristos       gold_assert(gsym == NULL
2886ed0d50c3Schristos 		  || gsym->has_plt_offset()
2887ed0d50c3Schristos 		  || gsym->final_value_is_known()
2888ed0d50c3Schristos 		  || (gsym->is_defined()
2889ed0d50c3Schristos 		      && !gsym->is_from_dynobj()
2890ed0d50c3Schristos 		      && !gsym->is_preemptible()));
2891ed0d50c3Schristos       Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
2892ed0d50c3Schristos       break;
2893ed0d50c3Schristos 
2894ed0d50c3Schristos     case elfcpp::R_386_GOT32:
2895ed0d50c3Schristos     case elfcpp::R_386_GOT32X:
2896ed0d50c3Schristos       baseless = (view[-1] & 0xc7) == 0x5;
2897ed0d50c3Schristos       // R_386_GOT32 and R_386_GOT32X don't work without base register
2898ed0d50c3Schristos       // when generating a position-independent output file.
2899ed0d50c3Schristos       if (baseless
2900ed0d50c3Schristos 	  && parameters->options().output_is_position_independent())
2901ed0d50c3Schristos 	{
2902ed0d50c3Schristos 	  if(gsym)
2903ed0d50c3Schristos 	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
2904ed0d50c3Schristos 				   _("unexpected reloc %u against global symbol %s without base register in object file when generating a position-independent output file"),
2905ed0d50c3Schristos 				   r_type, gsym->demangled_name().c_str());
2906ed0d50c3Schristos 	  else
2907ed0d50c3Schristos 	    gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
2908ed0d50c3Schristos 				   _("unexpected reloc %u against local symbol without base register in object file when generating a position-independent output file"),
2909ed0d50c3Schristos 				   r_type);
2910ed0d50c3Schristos 	}
2911ed0d50c3Schristos 
2912ed0d50c3Schristos       // Convert
2913ed0d50c3Schristos       // mov foo@GOT(%reg), %reg
2914ed0d50c3Schristos       // to
2915ed0d50c3Schristos       // lea foo@GOTOFF(%reg), %reg
2916ed0d50c3Schristos       // if possible.
2917ed0d50c3Schristos       if (rel.get_r_offset() >= 2
2918ed0d50c3Schristos 	  && view[-2] == 0x8b
2919ed0d50c3Schristos 	  && ((gsym == NULL && !psymval->is_ifunc_symbol())
2920ed0d50c3Schristos 	      || (gsym != NULL
2921ed0d50c3Schristos 		  && Target_i386::can_convert_mov_to_lea(gsym))))
2922ed0d50c3Schristos 	{
2923ed0d50c3Schristos 	  view[-2] = 0x8d;
2924ed0d50c3Schristos 	  elfcpp::Elf_types<32>::Elf_Addr value;
2925ed0d50c3Schristos 	  value = psymval->value(object, 0);
2926ed0d50c3Schristos 	  // Don't subtract the .got.plt section address for baseless
2927ed0d50c3Schristos 	  // addressing.
2928ed0d50c3Schristos 	  if (!baseless)
2929ed0d50c3Schristos 	    value -= target->got_plt_section()->address();
2930ed0d50c3Schristos 	  Relocate_functions<32, false>::rel32(view, value);
2931ed0d50c3Schristos 	}
2932ed0d50c3Schristos       else
2933ed0d50c3Schristos 	{
2934ed0d50c3Schristos 	  // The GOT pointer points to the end of the GOT section.
2935ed0d50c3Schristos 	  // We need to subtract the size of the GOT section to get
2936ed0d50c3Schristos 	  // the actual offset to use in the relocation.
2937ed0d50c3Schristos 	  unsigned int got_offset = 0;
2938ed0d50c3Schristos 	  if (gsym != NULL)
2939ed0d50c3Schristos 	    {
2940ed0d50c3Schristos 	      gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
2941ed0d50c3Schristos 	      got_offset = (gsym->got_offset(GOT_TYPE_STANDARD)
2942ed0d50c3Schristos 			    - target->got_size());
2943ed0d50c3Schristos 	    }
2944ed0d50c3Schristos 	  else
2945ed0d50c3Schristos 	    {
2946ed0d50c3Schristos 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
2947ed0d50c3Schristos 	      gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
2948ed0d50c3Schristos 	      got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
2949ed0d50c3Schristos 			    - target->got_size());
2950ed0d50c3Schristos 	    }
2951ed0d50c3Schristos 	  // Add the .got.plt section address for baseless addressing.
2952ed0d50c3Schristos 	  if (baseless)
2953ed0d50c3Schristos 	    got_offset += target->got_plt_section()->address();
2954ed0d50c3Schristos 	  Relocate_functions<32, false>::rel32(view, got_offset);
2955ed0d50c3Schristos 	}
2956ed0d50c3Schristos       break;
2957ed0d50c3Schristos 
2958ed0d50c3Schristos     case elfcpp::R_386_GOTOFF:
2959ed0d50c3Schristos       {
2960*b88e3e88Schristos 	elfcpp::Elf_types<32>::Elf_Addr reladdr;
2961*b88e3e88Schristos 	reladdr = target->got_plt_section()->address();
2962*b88e3e88Schristos 	Relocate_functions<32, false>::pcrel32(view, object, psymval, reladdr);
2963ed0d50c3Schristos       }
2964ed0d50c3Schristos       break;
2965ed0d50c3Schristos 
2966ed0d50c3Schristos     case elfcpp::R_386_GOTPC:
2967ed0d50c3Schristos       {
2968ed0d50c3Schristos 	elfcpp::Elf_types<32>::Elf_Addr value;
2969ed0d50c3Schristos 	value = target->got_plt_section()->address();
2970ed0d50c3Schristos 	Relocate_functions<32, false>::pcrel32(view, value, address);
2971ed0d50c3Schristos       }
2972ed0d50c3Schristos       break;
2973ed0d50c3Schristos 
2974ed0d50c3Schristos     case elfcpp::R_386_COPY:
2975ed0d50c3Schristos     case elfcpp::R_386_GLOB_DAT:
2976ed0d50c3Schristos     case elfcpp::R_386_JUMP_SLOT:
2977ed0d50c3Schristos     case elfcpp::R_386_RELATIVE:
2978ed0d50c3Schristos     case elfcpp::R_386_IRELATIVE:
2979ed0d50c3Schristos       // These are outstanding tls relocs, which are unexpected when
2980ed0d50c3Schristos       // linking.
2981ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF:
2982ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPMOD32:
2983ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPOFF32:
2984ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF32:
2985ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC:
2986ed0d50c3Schristos       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
2987ed0d50c3Schristos 			     _("unexpected reloc %u in object file"),
2988ed0d50c3Schristos 			     r_type);
2989ed0d50c3Schristos       break;
2990ed0d50c3Schristos 
2991ed0d50c3Schristos       // These are initial tls relocs, which are expected when
2992ed0d50c3Schristos       // linking.
2993ed0d50c3Schristos     case elfcpp::R_386_TLS_GD:             // Global-dynamic
2994ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTDESC:        // Global-dynamic (from ~oliva url)
2995ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC_CALL:
2996ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM:            // Local-dynamic
2997ed0d50c3Schristos     case elfcpp::R_386_TLS_LDO_32:         // Alternate local-dynamic
2998ed0d50c3Schristos     case elfcpp::R_386_TLS_IE:             // Initial-exec
2999ed0d50c3Schristos     case elfcpp::R_386_TLS_IE_32:
3000ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTIE:
3001ed0d50c3Schristos     case elfcpp::R_386_TLS_LE:             // Local-exec
3002ed0d50c3Schristos     case elfcpp::R_386_TLS_LE_32:
3003ed0d50c3Schristos       this->relocate_tls(relinfo, target, relnum, rel, r_type, gsym, psymval,
3004ed0d50c3Schristos 			 view, address, view_size);
3005ed0d50c3Schristos       break;
3006ed0d50c3Schristos 
3007ed0d50c3Schristos     case elfcpp::R_386_32PLT:
3008ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_32:
3009ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_PUSH:
3010ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_CALL:
3011ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_POP:
3012ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_32:
3013ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_PUSH:
3014ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_CALL:
3015ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_POP:
3016ed0d50c3Schristos     case elfcpp::R_386_USED_BY_INTEL_200:
3017ed0d50c3Schristos     default:
3018ed0d50c3Schristos       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
3019ed0d50c3Schristos 			     _("unsupported reloc %u"),
3020ed0d50c3Schristos 			     r_type);
3021ed0d50c3Schristos       break;
3022ed0d50c3Schristos     }
3023ed0d50c3Schristos 
3024ed0d50c3Schristos   return true;
3025ed0d50c3Schristos }
3026ed0d50c3Schristos 
3027ed0d50c3Schristos // Perform a TLS relocation.
3028ed0d50c3Schristos 
3029ed0d50c3Schristos inline void
relocate_tls(const Relocate_info<32,false> * relinfo,Target_i386 * target,size_t relnum,const elfcpp::Rel<32,false> & rel,unsigned int r_type,const Sized_symbol<32> * gsym,const Symbol_value<32> * psymval,unsigned char * view,elfcpp::Elf_types<32>::Elf_Addr,section_size_type view_size)3030ed0d50c3Schristos Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
3031ed0d50c3Schristos 				    Target_i386* target,
3032ed0d50c3Schristos 				    size_t relnum,
3033ed0d50c3Schristos 				    const elfcpp::Rel<32, false>& rel,
3034ed0d50c3Schristos 				    unsigned int r_type,
3035ed0d50c3Schristos 				    const Sized_symbol<32>* gsym,
3036ed0d50c3Schristos 				    const Symbol_value<32>* psymval,
3037ed0d50c3Schristos 				    unsigned char* view,
3038ed0d50c3Schristos 				    elfcpp::Elf_types<32>::Elf_Addr,
3039ed0d50c3Schristos 				    section_size_type view_size)
3040ed0d50c3Schristos {
3041ed0d50c3Schristos   Output_segment* tls_segment = relinfo->layout->tls_segment();
3042ed0d50c3Schristos 
3043ed0d50c3Schristos   const Sized_relobj_file<32, false>* object = relinfo->object;
3044ed0d50c3Schristos 
3045ed0d50c3Schristos   elfcpp::Elf_types<32>::Elf_Addr value = psymval->value(object, 0);
3046ed0d50c3Schristos 
3047ed0d50c3Schristos   const bool is_final = (gsym == NULL
3048ed0d50c3Schristos 			 ? !parameters->options().shared()
3049ed0d50c3Schristos 			 : gsym->final_value_is_known());
3050ed0d50c3Schristos   const tls::Tls_optimization optimized_type
3051ed0d50c3Schristos       = Target_i386::optimize_tls_reloc(is_final, r_type);
3052ed0d50c3Schristos   switch (r_type)
3053ed0d50c3Schristos     {
3054ed0d50c3Schristos     case elfcpp::R_386_TLS_GD:           // Global-dynamic
3055ed0d50c3Schristos       if (optimized_type == tls::TLSOPT_TO_LE)
3056ed0d50c3Schristos 	{
3057ed0d50c3Schristos 	  if (tls_segment == NULL)
3058ed0d50c3Schristos 	    {
3059ed0d50c3Schristos 	      gold_assert(parameters->errors()->error_count() > 0
3060ed0d50c3Schristos 			  || issue_undefined_symbol_error(gsym));
3061ed0d50c3Schristos 	      return;
3062ed0d50c3Schristos 	    }
3063ed0d50c3Schristos 	  this->tls_gd_to_le(relinfo, relnum, tls_segment,
3064ed0d50c3Schristos 			     rel, r_type, value, view,
3065ed0d50c3Schristos 			     view_size);
3066ed0d50c3Schristos 	  break;
3067ed0d50c3Schristos 	}
3068ed0d50c3Schristos       else
3069ed0d50c3Schristos 	{
3070ed0d50c3Schristos 	  unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
3071ed0d50c3Schristos 				   ? GOT_TYPE_TLS_NOFFSET
3072ed0d50c3Schristos 				   : GOT_TYPE_TLS_PAIR);
3073ed0d50c3Schristos 	  unsigned int got_offset;
3074ed0d50c3Schristos 	  if (gsym != NULL)
3075ed0d50c3Schristos 	    {
3076ed0d50c3Schristos 	      gold_assert(gsym->has_got_offset(got_type));
3077ed0d50c3Schristos 	      got_offset = gsym->got_offset(got_type) - target->got_size();
3078ed0d50c3Schristos 	    }
3079ed0d50c3Schristos 	  else
3080ed0d50c3Schristos 	    {
3081ed0d50c3Schristos 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
3082ed0d50c3Schristos 	      gold_assert(object->local_has_got_offset(r_sym, got_type));
3083ed0d50c3Schristos 	      got_offset = (object->local_got_offset(r_sym, got_type)
3084ed0d50c3Schristos 			    - target->got_size());
3085ed0d50c3Schristos 	    }
3086ed0d50c3Schristos 	  if (optimized_type == tls::TLSOPT_TO_IE)
3087ed0d50c3Schristos 	    {
3088ed0d50c3Schristos 	      this->tls_gd_to_ie(relinfo, relnum, rel, r_type,
3089ed0d50c3Schristos 				 got_offset, view, view_size);
3090ed0d50c3Schristos 	      break;
3091ed0d50c3Schristos 	    }
3092ed0d50c3Schristos 	  else if (optimized_type == tls::TLSOPT_NONE)
3093ed0d50c3Schristos 	    {
3094ed0d50c3Schristos 	      // Relocate the field with the offset of the pair of GOT
3095ed0d50c3Schristos 	      // entries.
3096ed0d50c3Schristos 	      Relocate_functions<32, false>::rel32(view, got_offset);
3097ed0d50c3Schristos 	      break;
3098ed0d50c3Schristos 	    }
3099ed0d50c3Schristos 	}
3100ed0d50c3Schristos       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
3101ed0d50c3Schristos 			     _("unsupported reloc %u"),
3102ed0d50c3Schristos 			     r_type);
3103ed0d50c3Schristos       break;
3104ed0d50c3Schristos 
3105ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTDESC:      // Global-dynamic (from ~oliva url)
3106ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC_CALL:
3107ed0d50c3Schristos       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
3108ed0d50c3Schristos       if (optimized_type == tls::TLSOPT_TO_LE)
3109ed0d50c3Schristos 	{
3110ed0d50c3Schristos 	  if (tls_segment == NULL)
3111ed0d50c3Schristos 	    {
3112ed0d50c3Schristos 	      gold_assert(parameters->errors()->error_count() > 0
3113ed0d50c3Schristos 			  || issue_undefined_symbol_error(gsym));
3114ed0d50c3Schristos 	      return;
3115ed0d50c3Schristos 	    }
3116ed0d50c3Schristos 	  this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
3117ed0d50c3Schristos 				  rel, r_type, value, view,
3118ed0d50c3Schristos 				  view_size);
3119ed0d50c3Schristos 	  break;
3120ed0d50c3Schristos 	}
3121ed0d50c3Schristos       else
3122ed0d50c3Schristos 	{
3123ed0d50c3Schristos 	  unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
3124ed0d50c3Schristos 				   ? GOT_TYPE_TLS_NOFFSET
3125ed0d50c3Schristos 				   : GOT_TYPE_TLS_DESC);
3126ed0d50c3Schristos 	  unsigned int got_offset = 0;
3127ed0d50c3Schristos 	  if (r_type == elfcpp::R_386_TLS_GOTDESC
3128ed0d50c3Schristos 	      && optimized_type == tls::TLSOPT_NONE)
3129ed0d50c3Schristos 	    {
3130ed0d50c3Schristos 	      // We created GOT entries in the .got.tlsdesc portion of
3131ed0d50c3Schristos 	      // the .got.plt section, but the offset stored in the
3132ed0d50c3Schristos 	      // symbol is the offset within .got.tlsdesc.
3133ed0d50c3Schristos 	      got_offset = (target->got_size()
3134ed0d50c3Schristos 			    + target->got_plt_section()->data_size());
3135ed0d50c3Schristos 	    }
3136ed0d50c3Schristos 	  if (gsym != NULL)
3137ed0d50c3Schristos 	    {
3138ed0d50c3Schristos 	      gold_assert(gsym->has_got_offset(got_type));
3139ed0d50c3Schristos 	      got_offset += gsym->got_offset(got_type) - target->got_size();
3140ed0d50c3Schristos 	    }
3141ed0d50c3Schristos 	  else
3142ed0d50c3Schristos 	    {
3143ed0d50c3Schristos 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
3144ed0d50c3Schristos 	      gold_assert(object->local_has_got_offset(r_sym, got_type));
3145ed0d50c3Schristos 	      got_offset += (object->local_got_offset(r_sym, got_type)
3146ed0d50c3Schristos 			     - target->got_size());
3147ed0d50c3Schristos 	    }
3148ed0d50c3Schristos 	  if (optimized_type == tls::TLSOPT_TO_IE)
3149ed0d50c3Schristos 	    {
3150ed0d50c3Schristos 	      this->tls_desc_gd_to_ie(relinfo, relnum, rel, r_type,
3151ed0d50c3Schristos 				      got_offset, view, view_size);
3152ed0d50c3Schristos 	      break;
3153ed0d50c3Schristos 	    }
3154ed0d50c3Schristos 	  else if (optimized_type == tls::TLSOPT_NONE)
3155ed0d50c3Schristos 	    {
3156ed0d50c3Schristos 	      if (r_type == elfcpp::R_386_TLS_GOTDESC)
3157ed0d50c3Schristos 		{
3158ed0d50c3Schristos 		  // Relocate the field with the offset of the pair of GOT
3159ed0d50c3Schristos 		  // entries.
3160ed0d50c3Schristos 		  Relocate_functions<32, false>::rel32(view, got_offset);
3161ed0d50c3Schristos 		}
3162ed0d50c3Schristos 	      break;
3163ed0d50c3Schristos 	    }
3164ed0d50c3Schristos 	}
3165ed0d50c3Schristos       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
3166ed0d50c3Schristos 			     _("unsupported reloc %u"),
3167ed0d50c3Schristos 			     r_type);
3168ed0d50c3Schristos       break;
3169ed0d50c3Schristos 
3170ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM:          // Local-dynamic
3171ed0d50c3Schristos       if (this->local_dynamic_type_ == LOCAL_DYNAMIC_SUN)
3172ed0d50c3Schristos 	{
3173ed0d50c3Schristos 	  gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
3174ed0d50c3Schristos 				 _("both SUN and GNU model "
3175ed0d50c3Schristos 				   "TLS relocations"));
3176ed0d50c3Schristos 	  break;
3177ed0d50c3Schristos 	}
3178ed0d50c3Schristos       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
3179ed0d50c3Schristos       if (optimized_type == tls::TLSOPT_TO_LE)
3180ed0d50c3Schristos 	{
3181ed0d50c3Schristos 	  if (tls_segment == NULL)
3182ed0d50c3Schristos 	    {
3183ed0d50c3Schristos 	      gold_assert(parameters->errors()->error_count() > 0
3184ed0d50c3Schristos 			  || issue_undefined_symbol_error(gsym));
3185ed0d50c3Schristos 	      return;
3186ed0d50c3Schristos 	    }
3187ed0d50c3Schristos 	  this->tls_ld_to_le(relinfo, relnum, tls_segment, rel, r_type,
3188ed0d50c3Schristos 			     value, view, view_size);
3189ed0d50c3Schristos 	  break;
3190ed0d50c3Schristos 	}
3191ed0d50c3Schristos       else if (optimized_type == tls::TLSOPT_NONE)
3192ed0d50c3Schristos 	{
3193ed0d50c3Schristos 	  // Relocate the field with the offset of the GOT entry for
3194ed0d50c3Schristos 	  // the module index.
3195ed0d50c3Schristos 	  unsigned int got_offset;
3196ed0d50c3Schristos 	  got_offset = (target->got_mod_index_entry(NULL, NULL, NULL)
3197ed0d50c3Schristos 			- target->got_size());
3198ed0d50c3Schristos 	  Relocate_functions<32, false>::rel32(view, got_offset);
3199ed0d50c3Schristos 	  break;
3200ed0d50c3Schristos 	}
3201ed0d50c3Schristos       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
3202ed0d50c3Schristos 			     _("unsupported reloc %u"),
3203ed0d50c3Schristos 			     r_type);
3204ed0d50c3Schristos       break;
3205ed0d50c3Schristos 
3206ed0d50c3Schristos     case elfcpp::R_386_TLS_LDO_32:       // Alternate local-dynamic
3207ed0d50c3Schristos       if (optimized_type == tls::TLSOPT_TO_LE)
3208ed0d50c3Schristos 	{
3209ed0d50c3Schristos 	  // This reloc can appear in debugging sections, in which
3210ed0d50c3Schristos 	  // case we must not convert to local-exec.  We decide what
3211ed0d50c3Schristos 	  // to do based on whether the section is marked as
3212ed0d50c3Schristos 	  // containing executable code.  That is what the GNU linker
3213ed0d50c3Schristos 	  // does as well.
3214ed0d50c3Schristos 	  elfcpp::Shdr<32, false> shdr(relinfo->data_shdr);
3215ed0d50c3Schristos 	  if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
3216ed0d50c3Schristos 	    {
3217ed0d50c3Schristos 	      if (tls_segment == NULL)
3218ed0d50c3Schristos 		{
3219ed0d50c3Schristos 		  gold_assert(parameters->errors()->error_count() > 0
3220ed0d50c3Schristos 			      || issue_undefined_symbol_error(gsym));
3221ed0d50c3Schristos 		  return;
3222ed0d50c3Schristos 		}
3223ed0d50c3Schristos 	      value -= tls_segment->memsz();
3224ed0d50c3Schristos 	    }
3225ed0d50c3Schristos 	}
3226ed0d50c3Schristos       Relocate_functions<32, false>::rel32(view, value);
3227ed0d50c3Schristos       break;
3228ed0d50c3Schristos 
3229ed0d50c3Schristos     case elfcpp::R_386_TLS_IE:           // Initial-exec
3230ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTIE:
3231ed0d50c3Schristos     case elfcpp::R_386_TLS_IE_32:
3232ed0d50c3Schristos       if (optimized_type == tls::TLSOPT_TO_LE)
3233ed0d50c3Schristos 	{
3234ed0d50c3Schristos 	  if (tls_segment == NULL)
3235ed0d50c3Schristos 	    {
3236ed0d50c3Schristos 	      gold_assert(parameters->errors()->error_count() > 0
3237ed0d50c3Schristos 			  || issue_undefined_symbol_error(gsym));
3238ed0d50c3Schristos 	      return;
3239ed0d50c3Schristos 	    }
3240ed0d50c3Schristos 	  Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
3241ed0d50c3Schristos 					      rel, r_type, value, view,
3242ed0d50c3Schristos 					      view_size);
3243ed0d50c3Schristos 	  break;
3244ed0d50c3Schristos 	}
3245ed0d50c3Schristos       else if (optimized_type == tls::TLSOPT_NONE)
3246ed0d50c3Schristos 	{
3247ed0d50c3Schristos 	  // Relocate the field with the offset of the GOT entry for
3248ed0d50c3Schristos 	  // the tp-relative offset of the symbol.
3249ed0d50c3Schristos 	  unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
3250ed0d50c3Schristos 				   ? GOT_TYPE_TLS_OFFSET
3251ed0d50c3Schristos 				   : GOT_TYPE_TLS_NOFFSET);
3252ed0d50c3Schristos 	  unsigned int got_offset;
3253ed0d50c3Schristos 	  if (gsym != NULL)
3254ed0d50c3Schristos 	    {
3255ed0d50c3Schristos 	      gold_assert(gsym->has_got_offset(got_type));
3256ed0d50c3Schristos 	      got_offset = gsym->got_offset(got_type);
3257ed0d50c3Schristos 	    }
3258ed0d50c3Schristos 	  else
3259ed0d50c3Schristos 	    {
3260ed0d50c3Schristos 	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
3261ed0d50c3Schristos 	      gold_assert(object->local_has_got_offset(r_sym, got_type));
3262ed0d50c3Schristos 	      got_offset = object->local_got_offset(r_sym, got_type);
3263ed0d50c3Schristos 	    }
3264ed0d50c3Schristos 	  // For the R_386_TLS_IE relocation, we need to apply the
3265ed0d50c3Schristos 	  // absolute address of the GOT entry.
3266ed0d50c3Schristos 	  if (r_type == elfcpp::R_386_TLS_IE)
3267ed0d50c3Schristos 	    got_offset += target->got_plt_section()->address();
3268ed0d50c3Schristos 	  // All GOT offsets are relative to the end of the GOT.
3269ed0d50c3Schristos 	  got_offset -= target->got_size();
3270ed0d50c3Schristos 	  Relocate_functions<32, false>::rel32(view, got_offset);
3271ed0d50c3Schristos 	  break;
3272ed0d50c3Schristos 	}
3273ed0d50c3Schristos       gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
3274ed0d50c3Schristos 			     _("unsupported reloc %u"),
3275ed0d50c3Schristos 			     r_type);
3276ed0d50c3Schristos       break;
3277ed0d50c3Schristos 
3278ed0d50c3Schristos     case elfcpp::R_386_TLS_LE:           // Local-exec
3279ed0d50c3Schristos       // If we're creating a shared library, a dynamic relocation will
3280ed0d50c3Schristos       // have been created for this location, so do not apply it now.
3281ed0d50c3Schristos       if (!parameters->options().shared())
3282ed0d50c3Schristos 	{
3283ed0d50c3Schristos 	  if (tls_segment == NULL)
3284ed0d50c3Schristos 	    {
3285ed0d50c3Schristos 	      gold_assert(parameters->errors()->error_count() > 0
3286ed0d50c3Schristos 			  || issue_undefined_symbol_error(gsym));
3287ed0d50c3Schristos 	      return;
3288ed0d50c3Schristos 	    }
3289ed0d50c3Schristos 	  value -= tls_segment->memsz();
3290ed0d50c3Schristos 	  Relocate_functions<32, false>::rel32(view, value);
3291ed0d50c3Schristos 	}
3292ed0d50c3Schristos       break;
3293ed0d50c3Schristos 
3294ed0d50c3Schristos     case elfcpp::R_386_TLS_LE_32:
3295ed0d50c3Schristos       // If we're creating a shared library, a dynamic relocation will
3296ed0d50c3Schristos       // have been created for this location, so do not apply it now.
3297ed0d50c3Schristos       if (!parameters->options().shared())
3298ed0d50c3Schristos 	{
3299ed0d50c3Schristos 	  if (tls_segment == NULL)
3300ed0d50c3Schristos 	    {
3301ed0d50c3Schristos 	      gold_assert(parameters->errors()->error_count() > 0
3302ed0d50c3Schristos 			  || issue_undefined_symbol_error(gsym));
3303ed0d50c3Schristos 	      return;
3304ed0d50c3Schristos 	    }
3305ed0d50c3Schristos 	  value = tls_segment->memsz() - value;
3306ed0d50c3Schristos 	  Relocate_functions<32, false>::rel32(view, value);
3307ed0d50c3Schristos 	}
3308ed0d50c3Schristos       break;
3309ed0d50c3Schristos     }
3310ed0d50c3Schristos }
3311ed0d50c3Schristos 
3312ed0d50c3Schristos // Do a relocation in which we convert a TLS General-Dynamic to a
3313ed0d50c3Schristos // Local-Exec.
3314ed0d50c3Schristos 
3315ed0d50c3Schristos inline void
tls_gd_to_le(const Relocate_info<32,false> * relinfo,size_t relnum,Output_segment * tls_segment,const elfcpp::Rel<32,false> & rel,unsigned int,elfcpp::Elf_types<32>::Elf_Addr value,unsigned char * view,section_size_type view_size)3316ed0d50c3Schristos Target_i386::Relocate::tls_gd_to_le(const Relocate_info<32, false>* relinfo,
3317ed0d50c3Schristos 				    size_t relnum,
3318ed0d50c3Schristos 				    Output_segment* tls_segment,
3319ed0d50c3Schristos 				    const elfcpp::Rel<32, false>& rel,
3320ed0d50c3Schristos 				    unsigned int,
3321ed0d50c3Schristos 				    elfcpp::Elf_types<32>::Elf_Addr value,
3322ed0d50c3Schristos 				    unsigned char* view,
3323ed0d50c3Schristos 				    section_size_type view_size)
3324ed0d50c3Schristos {
3325ed0d50c3Schristos   // leal foo(,%ebx,1),%eax; call ___tls_get_addr@PLT
3326ed0d50c3Schristos   //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
3327ed0d50c3Schristos   // leal foo(%ebx),%eax; call ___tls_get_addr@PLT
3328ed0d50c3Schristos   //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
3329ed0d50c3Schristos   // leal foo(%reg),%eax; call *___tls_get_addr@GOT(%reg)
3330ed0d50c3Schristos   //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
3331ed0d50c3Schristos 
3332ed0d50c3Schristos   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
3333ed0d50c3Schristos   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9);
3334ed0d50c3Schristos 
3335ed0d50c3Schristos   unsigned char op1 = view[-1];
3336ed0d50c3Schristos   unsigned char op2 = view[-2];
3337ed0d50c3Schristos   unsigned char op3 = view[4];
3338ed0d50c3Schristos 
3339ed0d50c3Schristos   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3340ed0d50c3Schristos 		 op2 == 0x8d || op2 == 0x04);
3341ed0d50c3Schristos   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3342ed0d50c3Schristos 		 op3 == 0xe8 || op3 == 0xff);
3343ed0d50c3Schristos 
3344ed0d50c3Schristos   int roff = 5;
3345ed0d50c3Schristos 
3346ed0d50c3Schristos   if (op2 == 0x04)
3347ed0d50c3Schristos     {
3348ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -3);
3349ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d);
3350ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3351ed0d50c3Schristos 		     ((op1 & 0xc7) == 0x05 && op1 != (4 << 3)));
3352ed0d50c3Schristos       memcpy(view - 3, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
3353ed0d50c3Schristos     }
3354ed0d50c3Schristos   else
3355ed0d50c3Schristos     {
3356ed0d50c3Schristos       unsigned char reg = op1 & 7;
3357ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3358ed0d50c3Schristos 		     ((op1 & 0xf8) == 0x80
3359ed0d50c3Schristos 		      && reg != 4
3360ed0d50c3Schristos 		      && reg != 0
3361ed0d50c3Schristos 		      && (op3 == 0xe8 || (view[5] & 0x7) == reg)));
3362ed0d50c3Schristos       if (op3 == 0xff
3363ed0d50c3Schristos 	  || (rel.get_r_offset() + 9 < view_size
3364ed0d50c3Schristos 	      && view[9] == 0x90))
3365ed0d50c3Schristos 	{
3366ed0d50c3Schristos 	  // There is an indirect call or a trailing nop.  Use the size
3367ed0d50c3Schristos 	  // byte subl.
3368ed0d50c3Schristos 	  memcpy(view - 2, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
3369ed0d50c3Schristos 	  roff = 6;
3370ed0d50c3Schristos 	}
3371ed0d50c3Schristos       else
3372ed0d50c3Schristos 	{
3373ed0d50c3Schristos 	  // Use the five byte subl.
3374ed0d50c3Schristos 	  memcpy(view - 2, "\x65\xa1\0\0\0\0\x2d\0\0\0", 11);
3375ed0d50c3Schristos 	}
3376ed0d50c3Schristos     }
3377ed0d50c3Schristos 
3378ed0d50c3Schristos   value = tls_segment->memsz() - value;
3379ed0d50c3Schristos   Relocate_functions<32, false>::rel32(view + roff, value);
3380ed0d50c3Schristos 
3381ed0d50c3Schristos   // The next reloc should be a PLT32 reloc against __tls_get_addr.
3382ed0d50c3Schristos   // We can skip it.
3383ed0d50c3Schristos   this->skip_call_tls_get_addr_ = true;
3384ed0d50c3Schristos }
3385ed0d50c3Schristos 
3386ed0d50c3Schristos // Do a relocation in which we convert a TLS General-Dynamic to an
3387ed0d50c3Schristos // Initial-Exec.
3388ed0d50c3Schristos 
3389ed0d50c3Schristos inline void
tls_gd_to_ie(const Relocate_info<32,false> * relinfo,size_t relnum,const elfcpp::Rel<32,false> & rel,unsigned int,elfcpp::Elf_types<32>::Elf_Addr value,unsigned char * view,section_size_type view_size)3390ed0d50c3Schristos Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
3391ed0d50c3Schristos 				    size_t relnum,
3392ed0d50c3Schristos 				    const elfcpp::Rel<32, false>& rel,
3393ed0d50c3Schristos 				    unsigned int,
3394ed0d50c3Schristos 				    elfcpp::Elf_types<32>::Elf_Addr value,
3395ed0d50c3Schristos 				    unsigned char* view,
3396ed0d50c3Schristos 				    section_size_type view_size)
3397ed0d50c3Schristos {
3398ed0d50c3Schristos   // leal foo(,%ebx,1),%eax; call ___tls_get_addr@PLT
3399ed0d50c3Schristos   //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
3400ed0d50c3Schristos   // leal foo(%ebx),%eax; call ___tls_get_addr@PLT; nop
3401ed0d50c3Schristos   //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%ebx),%eax
3402ed0d50c3Schristos   // leal foo(%reg),%eax; call *___tls_get_addr@GOT(%reg)
3403ed0d50c3Schristos   //  ==> movl %gs:0,%eax; addl foo@gotntpoff(%reg),%eax
3404ed0d50c3Schristos 
3405ed0d50c3Schristos   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
3406ed0d50c3Schristos   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9);
3407ed0d50c3Schristos 
3408ed0d50c3Schristos   unsigned char op1 = view[-1];
3409ed0d50c3Schristos   unsigned char op2 = view[-2];
3410ed0d50c3Schristos   unsigned char op3 = view[4];
3411ed0d50c3Schristos 
3412ed0d50c3Schristos   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3413ed0d50c3Schristos 		 op2 == 0x8d || op2 == 0x04);
3414ed0d50c3Schristos   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3415ed0d50c3Schristos 		 op3 == 0xe8 || op3 == 0xff);
3416ed0d50c3Schristos 
3417ed0d50c3Schristos   int roff;
3418ed0d50c3Schristos 
3419ed0d50c3Schristos   if (op2 == 0x04)
3420ed0d50c3Schristos     {
3421ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -3);
3422ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d);
3423ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3424ed0d50c3Schristos 		     ((op1 & 0xc7) == 0x05 && op1 != (4 << 3)));
3425ed0d50c3Schristos       roff = 5;
3426ed0d50c3Schristos     }
3427ed0d50c3Schristos   else
3428ed0d50c3Schristos     {
3429ed0d50c3Schristos       unsigned char reg = op1 & 7;
3430ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 10);
3431ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3432ed0d50c3Schristos 		     ((op1 & 0xf8) == 0x80
3433ed0d50c3Schristos 		      && reg != 4
3434ed0d50c3Schristos 		      && reg != 0
3435ed0d50c3Schristos 		      && ((op3 == 0xe8 && view[9] == 0x90)
3436ed0d50c3Schristos 			   || (view[5] & 0x7) == reg)));
3437ed0d50c3Schristos       roff = 6;
3438ed0d50c3Schristos     }
3439ed0d50c3Schristos 
3440ed0d50c3Schristos   memcpy(view + roff - 8, "\x65\xa1\0\0\0\0\x03\x83\0\0\0", 12);
3441ed0d50c3Schristos   Relocate_functions<32, false>::rel32(view + roff, value);
3442ed0d50c3Schristos 
3443ed0d50c3Schristos   // The next reloc should be a PLT32 reloc against __tls_get_addr.
3444ed0d50c3Schristos   // We can skip it.
3445ed0d50c3Schristos   this->skip_call_tls_get_addr_ = true;
3446ed0d50c3Schristos }
3447ed0d50c3Schristos 
3448ed0d50c3Schristos // Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
3449ed0d50c3Schristos // General-Dynamic to a Local-Exec.
3450ed0d50c3Schristos 
3451ed0d50c3Schristos inline void
tls_desc_gd_to_le(const Relocate_info<32,false> * relinfo,size_t relnum,Output_segment * tls_segment,const elfcpp::Rel<32,false> & rel,unsigned int r_type,elfcpp::Elf_types<32>::Elf_Addr value,unsigned char * view,section_size_type view_size)3452ed0d50c3Schristos Target_i386::Relocate::tls_desc_gd_to_le(
3453ed0d50c3Schristos     const Relocate_info<32, false>* relinfo,
3454ed0d50c3Schristos     size_t relnum,
3455ed0d50c3Schristos     Output_segment* tls_segment,
3456ed0d50c3Schristos     const elfcpp::Rel<32, false>& rel,
3457ed0d50c3Schristos     unsigned int r_type,
3458ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr value,
3459ed0d50c3Schristos     unsigned char* view,
3460ed0d50c3Schristos     section_size_type view_size)
3461ed0d50c3Schristos {
3462ed0d50c3Schristos   if (r_type == elfcpp::R_386_TLS_GOTDESC)
3463ed0d50c3Schristos     {
3464ed0d50c3Schristos       // leal foo@TLSDESC(%ebx), %eax
3465ed0d50c3Schristos       // ==> leal foo@NTPOFF, %eax
3466ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
3467ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
3468ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3469ed0d50c3Schristos 		     view[-2] == 0x8d && view[-1] == 0x83);
3470ed0d50c3Schristos       view[-1] = 0x05;
3471ed0d50c3Schristos       value -= tls_segment->memsz();
3472ed0d50c3Schristos       Relocate_functions<32, false>::rel32(view, value);
3473ed0d50c3Schristos     }
3474ed0d50c3Schristos   else
3475ed0d50c3Schristos     {
3476ed0d50c3Schristos       // call *foo@TLSCALL(%eax)
3477ed0d50c3Schristos       // ==> nop; nop
3478ed0d50c3Schristos       gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
3479ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
3480ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3481ed0d50c3Schristos 		     view[0] == 0xff && view[1] == 0x10);
3482ed0d50c3Schristos       view[0] = 0x66;
3483ed0d50c3Schristos       view[1] = 0x90;
3484ed0d50c3Schristos     }
3485ed0d50c3Schristos }
3486ed0d50c3Schristos 
3487ed0d50c3Schristos // Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
3488ed0d50c3Schristos // General-Dynamic to an Initial-Exec.
3489ed0d50c3Schristos 
3490ed0d50c3Schristos inline void
tls_desc_gd_to_ie(const Relocate_info<32,false> * relinfo,size_t relnum,const elfcpp::Rel<32,false> & rel,unsigned int r_type,elfcpp::Elf_types<32>::Elf_Addr value,unsigned char * view,section_size_type view_size)3491ed0d50c3Schristos Target_i386::Relocate::tls_desc_gd_to_ie(
3492ed0d50c3Schristos     const Relocate_info<32, false>* relinfo,
3493ed0d50c3Schristos     size_t relnum,
3494ed0d50c3Schristos     const elfcpp::Rel<32, false>& rel,
3495ed0d50c3Schristos     unsigned int r_type,
3496ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr value,
3497ed0d50c3Schristos     unsigned char* view,
3498ed0d50c3Schristos     section_size_type view_size)
3499ed0d50c3Schristos {
3500ed0d50c3Schristos   if (r_type == elfcpp::R_386_TLS_GOTDESC)
3501ed0d50c3Schristos     {
3502ed0d50c3Schristos       // leal foo@TLSDESC(%ebx), %eax
3503ed0d50c3Schristos       // ==> movl foo@GOTNTPOFF(%ebx), %eax
3504ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
3505ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
3506ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3507ed0d50c3Schristos 		     view[-2] == 0x8d && view[-1] == 0x83);
3508ed0d50c3Schristos       view[-2] = 0x8b;
3509ed0d50c3Schristos       Relocate_functions<32, false>::rel32(view, value);
3510ed0d50c3Schristos     }
3511ed0d50c3Schristos   else
3512ed0d50c3Schristos     {
3513ed0d50c3Schristos       // call *foo@TLSCALL(%eax)
3514ed0d50c3Schristos       // ==> nop; nop
3515ed0d50c3Schristos       gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
3516ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
3517ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3518ed0d50c3Schristos 		     view[0] == 0xff && view[1] == 0x10);
3519ed0d50c3Schristos       view[0] = 0x66;
3520ed0d50c3Schristos       view[1] = 0x90;
3521ed0d50c3Schristos     }
3522ed0d50c3Schristos }
3523ed0d50c3Schristos 
3524ed0d50c3Schristos // Do a relocation in which we convert a TLS Local-Dynamic to a
3525ed0d50c3Schristos // Local-Exec.
3526ed0d50c3Schristos 
3527ed0d50c3Schristos inline void
tls_ld_to_le(const Relocate_info<32,false> * relinfo,size_t relnum,Output_segment *,const elfcpp::Rel<32,false> & rel,unsigned int,elfcpp::Elf_types<32>::Elf_Addr,unsigned char * view,section_size_type view_size)3528ed0d50c3Schristos Target_i386::Relocate::tls_ld_to_le(const Relocate_info<32, false>* relinfo,
3529ed0d50c3Schristos 				    size_t relnum,
3530ed0d50c3Schristos 				    Output_segment*,
3531ed0d50c3Schristos 				    const elfcpp::Rel<32, false>& rel,
3532ed0d50c3Schristos 				    unsigned int,
3533ed0d50c3Schristos 				    elfcpp::Elf_types<32>::Elf_Addr,
3534ed0d50c3Schristos 				    unsigned char* view,
3535ed0d50c3Schristos 				    section_size_type view_size)
3536ed0d50c3Schristos {
3537ed0d50c3Schristos   // leal foo(%ebx), %eax; call ___tls_get_addr@PLT
3538ed0d50c3Schristos   // ==> movl %gs:0,%eax; nop; leal 0(%esi,1),%esi
3539ed0d50c3Schristos   // leal foo(%reg), %eax; call call *___tls_get_addr@GOT(%reg)
3540ed0d50c3Schristos   // ==> movl %gs:0,%eax; leal (%esi),%esi
3541ed0d50c3Schristos 
3542ed0d50c3Schristos   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
3543ed0d50c3Schristos 
3544ed0d50c3Schristos   unsigned char op1 = view[-1];
3545ed0d50c3Schristos   unsigned char op2 = view[-2];
3546ed0d50c3Schristos   unsigned char op3 = view[4];
3547ed0d50c3Schristos 
3548ed0d50c3Schristos   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3549ed0d50c3Schristos 		 op3 == 0xe8 || op3 == 0xff);
3550ed0d50c3Schristos   tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size,
3551ed0d50c3Schristos 		   op3 == 0xe8 ? 9 : 10);
3552ed0d50c3Schristos 
3553ed0d50c3Schristos   // FIXME: Does this test really always pass?
3554ed0d50c3Schristos   tls::check_tls(relinfo, relnum, rel.get_r_offset(), op2 == 0x8d);
3555ed0d50c3Schristos 
3556ed0d50c3Schristos   unsigned char reg = op1 & 7;
3557ed0d50c3Schristos   tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3558ed0d50c3Schristos 		 ((op1 & 0xf8) == 0x80
3559ed0d50c3Schristos 		  && reg != 4
3560ed0d50c3Schristos 		  && reg != 0
3561ed0d50c3Schristos 		  && (op3 == 0xe8 || (view[5] & 0x7) == reg)));
3562ed0d50c3Schristos 
3563ed0d50c3Schristos   if (op3 == 0xe8)
3564ed0d50c3Schristos     memcpy(view - 2, "\x65\xa1\0\0\0\0\x90\x8d\x74\x26\0", 11);
3565ed0d50c3Schristos   else
3566ed0d50c3Schristos     memcpy(view - 2, "\x65\xa1\0\0\0\0\x8d\xb6\0\0\0\0", 12);
3567ed0d50c3Schristos 
3568ed0d50c3Schristos   // The next reloc should be a PLT32 reloc against __tls_get_addr.
3569ed0d50c3Schristos   // We can skip it.
3570ed0d50c3Schristos   this->skip_call_tls_get_addr_ = true;
3571ed0d50c3Schristos }
3572ed0d50c3Schristos 
3573ed0d50c3Schristos // Do a relocation in which we convert a TLS Initial-Exec to a
3574ed0d50c3Schristos // Local-Exec.
3575ed0d50c3Schristos 
3576ed0d50c3Schristos inline void
tls_ie_to_le(const Relocate_info<32,false> * relinfo,size_t relnum,Output_segment * tls_segment,const elfcpp::Rel<32,false> & rel,unsigned int r_type,elfcpp::Elf_types<32>::Elf_Addr value,unsigned char * view,section_size_type view_size)3577ed0d50c3Schristos Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
3578ed0d50c3Schristos 				    size_t relnum,
3579ed0d50c3Schristos 				    Output_segment* tls_segment,
3580ed0d50c3Schristos 				    const elfcpp::Rel<32, false>& rel,
3581ed0d50c3Schristos 				    unsigned int r_type,
3582ed0d50c3Schristos 				    elfcpp::Elf_types<32>::Elf_Addr value,
3583ed0d50c3Schristos 				    unsigned char* view,
3584ed0d50c3Schristos 				    section_size_type view_size)
3585ed0d50c3Schristos {
3586ed0d50c3Schristos   // We have to actually change the instructions, which means that we
3587ed0d50c3Schristos   // need to examine the opcodes to figure out which instruction we
3588ed0d50c3Schristos   // are looking at.
3589ed0d50c3Schristos   if (r_type == elfcpp::R_386_TLS_IE)
3590ed0d50c3Schristos     {
3591ed0d50c3Schristos       // movl %gs:XX,%eax  ==>  movl $YY,%eax
3592ed0d50c3Schristos       // movl %gs:XX,%reg  ==>  movl $YY,%reg
3593ed0d50c3Schristos       // addl %gs:XX,%reg  ==>  addl $YY,%reg
3594ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -1);
3595ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
3596ed0d50c3Schristos 
3597ed0d50c3Schristos       unsigned char op1 = view[-1];
3598ed0d50c3Schristos       if (op1 == 0xa1)
3599ed0d50c3Schristos 	{
3600ed0d50c3Schristos 	  // movl XX,%eax  ==>  movl $YY,%eax
3601ed0d50c3Schristos 	  view[-1] = 0xb8;
3602ed0d50c3Schristos 	}
3603ed0d50c3Schristos       else
3604ed0d50c3Schristos 	{
3605ed0d50c3Schristos 	  tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
3606ed0d50c3Schristos 
3607ed0d50c3Schristos 	  unsigned char op2 = view[-2];
3608ed0d50c3Schristos 	  if (op2 == 0x8b)
3609ed0d50c3Schristos 	    {
3610ed0d50c3Schristos 	      // movl XX,%reg  ==>  movl $YY,%reg
3611ed0d50c3Schristos 	      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3612ed0d50c3Schristos 			     (op1 & 0xc7) == 0x05);
3613ed0d50c3Schristos 	      view[-2] = 0xc7;
3614ed0d50c3Schristos 	      view[-1] = 0xc0 | ((op1 >> 3) & 7);
3615ed0d50c3Schristos 	    }
3616ed0d50c3Schristos 	  else if (op2 == 0x03)
3617ed0d50c3Schristos 	    {
3618ed0d50c3Schristos 	      // addl XX,%reg  ==>  addl $YY,%reg
3619ed0d50c3Schristos 	      tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3620ed0d50c3Schristos 			     (op1 & 0xc7) == 0x05);
3621ed0d50c3Schristos 	      view[-2] = 0x81;
3622ed0d50c3Schristos 	      view[-1] = 0xc0 | ((op1 >> 3) & 7);
3623ed0d50c3Schristos 	    }
3624ed0d50c3Schristos 	  else
3625ed0d50c3Schristos 	    tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0);
3626ed0d50c3Schristos 	}
3627ed0d50c3Schristos     }
3628ed0d50c3Schristos   else
3629ed0d50c3Schristos     {
3630ed0d50c3Schristos       // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
3631ed0d50c3Schristos       // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
3632ed0d50c3Schristos       // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
3633ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
3634ed0d50c3Schristos       tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
3635ed0d50c3Schristos 
3636ed0d50c3Schristos       unsigned char op1 = view[-1];
3637ed0d50c3Schristos       unsigned char op2 = view[-2];
3638ed0d50c3Schristos       tls::check_tls(relinfo, relnum, rel.get_r_offset(),
3639ed0d50c3Schristos 		     (op1 & 0xc0) == 0x80 && (op1 & 7) != 4);
3640ed0d50c3Schristos       if (op2 == 0x8b)
3641ed0d50c3Schristos 	{
3642ed0d50c3Schristos 	  // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
3643ed0d50c3Schristos 	  view[-2] = 0xc7;
3644ed0d50c3Schristos 	  view[-1] = 0xc0 | ((op1 >> 3) & 7);
3645ed0d50c3Schristos 	}
3646ed0d50c3Schristos       else if (op2 == 0x2b)
3647ed0d50c3Schristos 	{
3648ed0d50c3Schristos 	  // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
3649ed0d50c3Schristos 	  view[-2] = 0x81;
3650ed0d50c3Schristos 	  view[-1] = 0xe8 | ((op1 >> 3) & 7);
3651ed0d50c3Schristos 	}
3652ed0d50c3Schristos       else if (op2 == 0x03)
3653ed0d50c3Schristos 	{
3654ed0d50c3Schristos 	  // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
3655ed0d50c3Schristos 	  view[-2] = 0x81;
3656ed0d50c3Schristos 	  view[-1] = 0xc0 | ((op1 >> 3) & 7);
3657ed0d50c3Schristos 	}
3658ed0d50c3Schristos       else
3659ed0d50c3Schristos 	tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0);
3660ed0d50c3Schristos     }
3661ed0d50c3Schristos 
3662ed0d50c3Schristos   value = tls_segment->memsz() - value;
3663ed0d50c3Schristos   if (r_type == elfcpp::R_386_TLS_IE || r_type == elfcpp::R_386_TLS_GOTIE)
3664ed0d50c3Schristos     value = - value;
3665ed0d50c3Schristos 
3666ed0d50c3Schristos   Relocate_functions<32, false>::rel32(view, value);
3667ed0d50c3Schristos }
3668ed0d50c3Schristos 
3669ed0d50c3Schristos // Relocate section data.
3670ed0d50c3Schristos 
3671ed0d50c3Schristos void
relocate_section(const Relocate_info<32,false> * relinfo,unsigned int sh_type,const unsigned char * prelocs,size_t reloc_count,Output_section * output_section,bool needs_special_offset_handling,unsigned char * view,elfcpp::Elf_types<32>::Elf_Addr address,section_size_type view_size,const Reloc_symbol_changes * reloc_symbol_changes)3672ed0d50c3Schristos Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
3673ed0d50c3Schristos 			      unsigned int sh_type,
3674ed0d50c3Schristos 			      const unsigned char* prelocs,
3675ed0d50c3Schristos 			      size_t reloc_count,
3676ed0d50c3Schristos 			      Output_section* output_section,
3677ed0d50c3Schristos 			      bool needs_special_offset_handling,
3678ed0d50c3Schristos 			      unsigned char* view,
3679ed0d50c3Schristos 			      elfcpp::Elf_types<32>::Elf_Addr address,
3680ed0d50c3Schristos 			      section_size_type view_size,
3681ed0d50c3Schristos 			      const Reloc_symbol_changes* reloc_symbol_changes)
3682ed0d50c3Schristos {
3683ed0d50c3Schristos   gold_assert(sh_type == elfcpp::SHT_REL);
3684ed0d50c3Schristos 
3685ed0d50c3Schristos   gold::relocate_section<32, false, Target_i386, Relocate,
3686ed0d50c3Schristos 			 gold::Default_comdat_behavior, Classify_reloc>(
3687ed0d50c3Schristos     relinfo,
3688ed0d50c3Schristos     this,
3689ed0d50c3Schristos     prelocs,
3690ed0d50c3Schristos     reloc_count,
3691ed0d50c3Schristos     output_section,
3692ed0d50c3Schristos     needs_special_offset_handling,
3693ed0d50c3Schristos     view,
3694ed0d50c3Schristos     address,
3695ed0d50c3Schristos     view_size,
3696ed0d50c3Schristos     reloc_symbol_changes);
3697ed0d50c3Schristos }
3698ed0d50c3Schristos 
3699ed0d50c3Schristos // Return the size of a relocation while scanning during a relocatable
3700ed0d50c3Schristos // link.
3701ed0d50c3Schristos 
3702ed0d50c3Schristos unsigned int
get_size_for_reloc(unsigned int r_type,Relobj * object)3703ed0d50c3Schristos Target_i386::Classify_reloc::get_size_for_reloc(
3704ed0d50c3Schristos     unsigned int r_type,
3705ed0d50c3Schristos     Relobj* object)
3706ed0d50c3Schristos {
3707ed0d50c3Schristos   switch (r_type)
3708ed0d50c3Schristos     {
3709ed0d50c3Schristos     case elfcpp::R_386_NONE:
3710ed0d50c3Schristos     case elfcpp::R_386_GNU_VTINHERIT:
3711ed0d50c3Schristos     case elfcpp::R_386_GNU_VTENTRY:
3712ed0d50c3Schristos     case elfcpp::R_386_TLS_GD:            // Global-dynamic
3713ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTDESC:       // Global-dynamic (from ~oliva url)
3714ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC_CALL:
3715ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM:           // Local-dynamic
3716ed0d50c3Schristos     case elfcpp::R_386_TLS_LDO_32:        // Alternate local-dynamic
3717ed0d50c3Schristos     case elfcpp::R_386_TLS_IE:            // Initial-exec
3718ed0d50c3Schristos     case elfcpp::R_386_TLS_IE_32:
3719ed0d50c3Schristos     case elfcpp::R_386_TLS_GOTIE:
3720ed0d50c3Schristos     case elfcpp::R_386_TLS_LE:            // Local-exec
3721ed0d50c3Schristos     case elfcpp::R_386_TLS_LE_32:
3722ed0d50c3Schristos       return 0;
3723ed0d50c3Schristos 
3724ed0d50c3Schristos     case elfcpp::R_386_32:
3725ed0d50c3Schristos     case elfcpp::R_386_PC32:
3726ed0d50c3Schristos     case elfcpp::R_386_GOT32:
3727ed0d50c3Schristos     case elfcpp::R_386_GOT32X:
3728ed0d50c3Schristos     case elfcpp::R_386_PLT32:
3729ed0d50c3Schristos     case elfcpp::R_386_GOTOFF:
3730ed0d50c3Schristos     case elfcpp::R_386_GOTPC:
3731ed0d50c3Schristos      return 4;
3732ed0d50c3Schristos 
3733ed0d50c3Schristos     case elfcpp::R_386_16:
3734ed0d50c3Schristos     case elfcpp::R_386_PC16:
3735ed0d50c3Schristos       return 2;
3736ed0d50c3Schristos 
3737ed0d50c3Schristos     case elfcpp::R_386_8:
3738ed0d50c3Schristos     case elfcpp::R_386_PC8:
3739ed0d50c3Schristos       return 1;
3740ed0d50c3Schristos 
3741ed0d50c3Schristos       // These are relocations which should only be seen by the
3742ed0d50c3Schristos       // dynamic linker, and should never be seen here.
3743ed0d50c3Schristos     case elfcpp::R_386_COPY:
3744ed0d50c3Schristos     case elfcpp::R_386_GLOB_DAT:
3745ed0d50c3Schristos     case elfcpp::R_386_JUMP_SLOT:
3746ed0d50c3Schristos     case elfcpp::R_386_RELATIVE:
3747ed0d50c3Schristos     case elfcpp::R_386_IRELATIVE:
3748ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF:
3749ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPMOD32:
3750ed0d50c3Schristos     case elfcpp::R_386_TLS_DTPOFF32:
3751ed0d50c3Schristos     case elfcpp::R_386_TLS_TPOFF32:
3752ed0d50c3Schristos     case elfcpp::R_386_TLS_DESC:
3753ed0d50c3Schristos       object->error(_("unexpected reloc %u in object file"), r_type);
3754ed0d50c3Schristos       return 0;
3755ed0d50c3Schristos 
3756ed0d50c3Schristos     case elfcpp::R_386_32PLT:
3757ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_32:
3758ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_PUSH:
3759ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_CALL:
3760ed0d50c3Schristos     case elfcpp::R_386_TLS_GD_POP:
3761ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_32:
3762ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_PUSH:
3763ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_CALL:
3764ed0d50c3Schristos     case elfcpp::R_386_TLS_LDM_POP:
3765ed0d50c3Schristos     case elfcpp::R_386_USED_BY_INTEL_200:
3766ed0d50c3Schristos     default:
3767ed0d50c3Schristos       object->error(_("unsupported reloc %u in object file"), r_type);
3768ed0d50c3Schristos       return 0;
3769ed0d50c3Schristos     }
3770ed0d50c3Schristos }
3771ed0d50c3Schristos 
3772ed0d50c3Schristos // Scan the relocs during a relocatable link.
3773ed0d50c3Schristos 
3774ed0d50c3Schristos void
scan_relocatable_relocs(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * object,unsigned int data_shndx,unsigned int sh_type,const unsigned char * prelocs,size_t reloc_count,Output_section * output_section,bool needs_special_offset_handling,size_t local_symbol_count,const unsigned char * plocal_symbols,Relocatable_relocs * rr)3775ed0d50c3Schristos Target_i386::scan_relocatable_relocs(Symbol_table* symtab,
3776ed0d50c3Schristos 				     Layout* layout,
3777ed0d50c3Schristos 				     Sized_relobj_file<32, false>* object,
3778ed0d50c3Schristos 				     unsigned int data_shndx,
3779ed0d50c3Schristos 				     unsigned int sh_type,
3780ed0d50c3Schristos 				     const unsigned char* prelocs,
3781ed0d50c3Schristos 				     size_t reloc_count,
3782ed0d50c3Schristos 				     Output_section* output_section,
3783ed0d50c3Schristos 				     bool needs_special_offset_handling,
3784ed0d50c3Schristos 				     size_t local_symbol_count,
3785ed0d50c3Schristos 				     const unsigned char* plocal_symbols,
3786ed0d50c3Schristos 				     Relocatable_relocs* rr)
3787ed0d50c3Schristos {
3788ed0d50c3Schristos   typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
3789ed0d50c3Schristos       Scan_relocatable_relocs;
3790ed0d50c3Schristos 
3791ed0d50c3Schristos   gold_assert(sh_type == elfcpp::SHT_REL);
3792ed0d50c3Schristos 
3793ed0d50c3Schristos   gold::scan_relocatable_relocs<32, false, Scan_relocatable_relocs>(
3794ed0d50c3Schristos     symtab,
3795ed0d50c3Schristos     layout,
3796ed0d50c3Schristos     object,
3797ed0d50c3Schristos     data_shndx,
3798ed0d50c3Schristos     prelocs,
3799ed0d50c3Schristos     reloc_count,
3800ed0d50c3Schristos     output_section,
3801ed0d50c3Schristos     needs_special_offset_handling,
3802ed0d50c3Schristos     local_symbol_count,
3803ed0d50c3Schristos     plocal_symbols,
3804ed0d50c3Schristos     rr);
3805ed0d50c3Schristos }
3806ed0d50c3Schristos 
3807ed0d50c3Schristos // Scan the relocs for --emit-relocs.
3808ed0d50c3Schristos 
3809ed0d50c3Schristos void
emit_relocs_scan(Symbol_table * symtab,Layout * layout,Sized_relobj_file<32,false> * object,unsigned int data_shndx,unsigned int sh_type,const unsigned char * prelocs,size_t reloc_count,Output_section * output_section,bool needs_special_offset_handling,size_t local_symbol_count,const unsigned char * plocal_syms,Relocatable_relocs * rr)3810ed0d50c3Schristos Target_i386::emit_relocs_scan(Symbol_table* symtab,
3811ed0d50c3Schristos 			      Layout* layout,
3812ed0d50c3Schristos 			      Sized_relobj_file<32, false>* object,
3813ed0d50c3Schristos 			      unsigned int data_shndx,
3814ed0d50c3Schristos 			      unsigned int sh_type,
3815ed0d50c3Schristos 			      const unsigned char* prelocs,
3816ed0d50c3Schristos 			      size_t reloc_count,
3817ed0d50c3Schristos 			      Output_section* output_section,
3818ed0d50c3Schristos 			      bool needs_special_offset_handling,
3819ed0d50c3Schristos 			      size_t local_symbol_count,
3820ed0d50c3Schristos 			      const unsigned char* plocal_syms,
3821ed0d50c3Schristos 			      Relocatable_relocs* rr)
3822ed0d50c3Schristos {
3823ed0d50c3Schristos   typedef gold::Default_classify_reloc<elfcpp::SHT_REL, 32, false>
3824ed0d50c3Schristos       Classify_reloc;
3825ed0d50c3Schristos   typedef gold::Default_emit_relocs_strategy<Classify_reloc>
3826ed0d50c3Schristos       Emit_relocs_strategy;
3827ed0d50c3Schristos 
3828ed0d50c3Schristos   gold_assert(sh_type == elfcpp::SHT_REL);
3829ed0d50c3Schristos 
3830ed0d50c3Schristos   gold::scan_relocatable_relocs<32, false, Emit_relocs_strategy>(
3831ed0d50c3Schristos     symtab,
3832ed0d50c3Schristos     layout,
3833ed0d50c3Schristos     object,
3834ed0d50c3Schristos     data_shndx,
3835ed0d50c3Schristos     prelocs,
3836ed0d50c3Schristos     reloc_count,
3837ed0d50c3Schristos     output_section,
3838ed0d50c3Schristos     needs_special_offset_handling,
3839ed0d50c3Schristos     local_symbol_count,
3840ed0d50c3Schristos     plocal_syms,
3841ed0d50c3Schristos     rr);
3842ed0d50c3Schristos }
3843ed0d50c3Schristos 
3844ed0d50c3Schristos // Emit relocations for a section.
3845ed0d50c3Schristos 
3846ed0d50c3Schristos void
relocate_relocs(const Relocate_info<32,false> * relinfo,unsigned int sh_type,const unsigned char * prelocs,size_t reloc_count,Output_section * output_section,elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,unsigned char * view,elfcpp::Elf_types<32>::Elf_Addr view_address,section_size_type view_size,unsigned char * reloc_view,section_size_type reloc_view_size)3847ed0d50c3Schristos Target_i386::relocate_relocs(
3848ed0d50c3Schristos     const Relocate_info<32, false>* relinfo,
3849ed0d50c3Schristos     unsigned int sh_type,
3850ed0d50c3Schristos     const unsigned char* prelocs,
3851ed0d50c3Schristos     size_t reloc_count,
3852ed0d50c3Schristos     Output_section* output_section,
3853ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
3854ed0d50c3Schristos     unsigned char* view,
3855ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr view_address,
3856ed0d50c3Schristos     section_size_type view_size,
3857ed0d50c3Schristos     unsigned char* reloc_view,
3858ed0d50c3Schristos     section_size_type reloc_view_size)
3859ed0d50c3Schristos {
3860ed0d50c3Schristos   gold_assert(sh_type == elfcpp::SHT_REL);
3861ed0d50c3Schristos 
3862ed0d50c3Schristos   gold::relocate_relocs<32, false, Classify_reloc>(
3863ed0d50c3Schristos     relinfo,
3864ed0d50c3Schristos     prelocs,
3865ed0d50c3Schristos     reloc_count,
3866ed0d50c3Schristos     output_section,
3867ed0d50c3Schristos     offset_in_output_section,
3868ed0d50c3Schristos     view,
3869ed0d50c3Schristos     view_address,
3870ed0d50c3Schristos     view_size,
3871ed0d50c3Schristos     reloc_view,
3872ed0d50c3Schristos     reloc_view_size);
3873ed0d50c3Schristos }
3874ed0d50c3Schristos 
3875ed0d50c3Schristos // Return the value to use for a dynamic which requires special
3876ed0d50c3Schristos // treatment.  This is how we support equality comparisons of function
3877ed0d50c3Schristos // pointers across shared library boundaries, as described in the
3878ed0d50c3Schristos // processor specific ABI supplement.
3879ed0d50c3Schristos 
3880ed0d50c3Schristos uint64_t
do_dynsym_value(const Symbol * gsym) const3881ed0d50c3Schristos Target_i386::do_dynsym_value(const Symbol* gsym) const
3882ed0d50c3Schristos {
3883ed0d50c3Schristos   gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
3884ed0d50c3Schristos   return this->plt_address_for_global(gsym);
3885ed0d50c3Schristos }
3886ed0d50c3Schristos 
3887ed0d50c3Schristos // Return a string used to fill a code section with nops to take up
3888ed0d50c3Schristos // the specified length.
3889ed0d50c3Schristos 
3890ed0d50c3Schristos std::string
do_code_fill(section_size_type length) const3891ed0d50c3Schristos Target_i386::do_code_fill(section_size_type length) const
3892ed0d50c3Schristos {
3893ed0d50c3Schristos   if (length >= 16)
3894ed0d50c3Schristos     {
3895ed0d50c3Schristos       // Build a jmp instruction to skip over the bytes.
3896ed0d50c3Schristos       unsigned char jmp[5];
3897ed0d50c3Schristos       jmp[0] = 0xe9;
3898ed0d50c3Schristos       elfcpp::Swap_unaligned<32, false>::writeval(jmp + 1, length - 5);
3899ed0d50c3Schristos       return (std::string(reinterpret_cast<char*>(&jmp[0]), 5)
3900ed0d50c3Schristos 	      + std::string(length - 5, static_cast<char>(0x90)));
3901ed0d50c3Schristos     }
3902ed0d50c3Schristos 
3903ed0d50c3Schristos   // Nop sequences of various lengths.
3904ed0d50c3Schristos   const char nop1[1] = { '\x90' };                   // nop
3905ed0d50c3Schristos   const char nop2[2] = { '\x66', '\x90' };           // xchg %ax %ax
3906ed0d50c3Schristos   const char nop3[3] = { '\x8d', '\x76', '\x00' };   // leal 0(%esi),%esi
3907ed0d50c3Schristos   const char nop4[4] = { '\x8d', '\x74', '\x26',     // leal 0(%esi,1),%esi
3908ed0d50c3Schristos 			 '\x00'};
3909ed0d50c3Schristos   const char nop5[5] = { '\x90', '\x8d', '\x74',     // nop
3910ed0d50c3Schristos 			 '\x26', '\x00' };           // leal 0(%esi,1),%esi
3911ed0d50c3Schristos   const char nop6[6] = { '\x8d', '\xb6', '\x00',     // leal 0L(%esi),%esi
3912ed0d50c3Schristos 			 '\x00', '\x00', '\x00' };
3913ed0d50c3Schristos   const char nop7[7] = { '\x8d', '\xb4', '\x26',     // leal 0L(%esi,1),%esi
3914ed0d50c3Schristos 			 '\x00', '\x00', '\x00',
3915ed0d50c3Schristos 			 '\x00' };
3916ed0d50c3Schristos   const char nop8[8] = { '\x90', '\x8d', '\xb4',     // nop
3917ed0d50c3Schristos 			 '\x26', '\x00', '\x00',     // leal 0L(%esi,1),%esi
3918ed0d50c3Schristos 			 '\x00', '\x00' };
3919ed0d50c3Schristos   const char nop9[9] = { '\x89', '\xf6', '\x8d',     // movl %esi,%esi
3920ed0d50c3Schristos 			 '\xbc', '\x27', '\x00',     // leal 0L(%edi,1),%edi
3921ed0d50c3Schristos 			 '\x00', '\x00', '\x00' };
3922ed0d50c3Schristos   const char nop10[10] = { '\x8d', '\x76', '\x00',   // leal 0(%esi),%esi
3923ed0d50c3Schristos 			   '\x8d', '\xbc', '\x27',   // leal 0L(%edi,1),%edi
3924ed0d50c3Schristos 			   '\x00', '\x00', '\x00',
3925ed0d50c3Schristos 			   '\x00' };
3926ed0d50c3Schristos   const char nop11[11] = { '\x8d', '\x74', '\x26',   // leal 0(%esi,1),%esi
3927ed0d50c3Schristos 			   '\x00', '\x8d', '\xbc',   // leal 0L(%edi,1),%edi
3928ed0d50c3Schristos 			   '\x27', '\x00', '\x00',
3929ed0d50c3Schristos 			   '\x00', '\x00' };
3930ed0d50c3Schristos   const char nop12[12] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
3931ed0d50c3Schristos 			   '\x00', '\x00', '\x00',   // leal 0L(%edi),%edi
3932ed0d50c3Schristos 			   '\x8d', '\xbf', '\x00',
3933ed0d50c3Schristos 			   '\x00', '\x00', '\x00' };
3934ed0d50c3Schristos   const char nop13[13] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
3935ed0d50c3Schristos 			   '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
3936ed0d50c3Schristos 			   '\x8d', '\xbc', '\x27',
3937ed0d50c3Schristos 			   '\x00', '\x00', '\x00',
3938ed0d50c3Schristos 			   '\x00' };
3939ed0d50c3Schristos   const char nop14[14] = { '\x8d', '\xb4', '\x26',   // leal 0L(%esi,1),%esi
3940ed0d50c3Schristos 			   '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
3941ed0d50c3Schristos 			   '\x00', '\x8d', '\xbc',
3942ed0d50c3Schristos 			   '\x27', '\x00', '\x00',
3943ed0d50c3Schristos 			   '\x00', '\x00' };
3944ed0d50c3Schristos   const char nop15[15] = { '\xeb', '\x0d', '\x90',   // jmp .+15
3945ed0d50c3Schristos 			   '\x90', '\x90', '\x90',   // nop,nop,nop,...
3946ed0d50c3Schristos 			   '\x90', '\x90', '\x90',
3947ed0d50c3Schristos 			   '\x90', '\x90', '\x90',
3948ed0d50c3Schristos 			   '\x90', '\x90', '\x90' };
3949ed0d50c3Schristos 
3950ed0d50c3Schristos   const char* nops[16] = {
3951ed0d50c3Schristos     NULL,
3952ed0d50c3Schristos     nop1, nop2, nop3, nop4, nop5, nop6, nop7,
3953ed0d50c3Schristos     nop8, nop9, nop10, nop11, nop12, nop13, nop14, nop15
3954ed0d50c3Schristos   };
3955ed0d50c3Schristos 
3956ed0d50c3Schristos   return std::string(nops[length], length);
3957ed0d50c3Schristos }
3958ed0d50c3Schristos 
3959ed0d50c3Schristos // Return the value to use for the base of a DW_EH_PE_datarel offset
3960ed0d50c3Schristos // in an FDE.  Solaris and SVR4 use DW_EH_PE_datarel because their
3961ed0d50c3Schristos // assembler can not write out the difference between two labels in
3962ed0d50c3Schristos // different sections, so instead of using a pc-relative value they
3963ed0d50c3Schristos // use an offset from the GOT.
3964ed0d50c3Schristos 
3965ed0d50c3Schristos uint64_t
do_ehframe_datarel_base() const3966ed0d50c3Schristos Target_i386::do_ehframe_datarel_base() const
3967ed0d50c3Schristos {
3968ed0d50c3Schristos   gold_assert(this->global_offset_table_ != NULL);
3969ed0d50c3Schristos   Symbol* sym = this->global_offset_table_;
3970ed0d50c3Schristos   Sized_symbol<32>* ssym = static_cast<Sized_symbol<32>*>(sym);
3971ed0d50c3Schristos   return ssym->value();
3972ed0d50c3Schristos }
3973ed0d50c3Schristos 
3974ed0d50c3Schristos // Return whether SYM should be treated as a call to a non-split
3975ed0d50c3Schristos // function.  We don't want that to be true of a call to a
3976ed0d50c3Schristos // get_pc_thunk function.
3977ed0d50c3Schristos 
3978ed0d50c3Schristos bool
do_is_call_to_non_split(const Symbol * sym,const unsigned char *,const unsigned char *,section_size_type) const3979ed0d50c3Schristos Target_i386::do_is_call_to_non_split(const Symbol* sym,
3980ed0d50c3Schristos 				     const unsigned char*,
3981ed0d50c3Schristos 				     const unsigned char*,
3982ed0d50c3Schristos 				     section_size_type) const
3983ed0d50c3Schristos {
3984ed0d50c3Schristos   return (sym->type() == elfcpp::STT_FUNC
3985ed0d50c3Schristos 	  && !is_prefix_of("__i686.get_pc_thunk.", sym->name()));
3986ed0d50c3Schristos }
3987ed0d50c3Schristos 
3988ed0d50c3Schristos // FNOFFSET in section SHNDX in OBJECT is the start of a function
3989ed0d50c3Schristos // compiled with -fsplit-stack.  The function calls non-split-stack
3990ed0d50c3Schristos // code.  We have to change the function so that it always ensures
3991ed0d50c3Schristos // that it has enough stack space to run some random function.
3992ed0d50c3Schristos 
3993ed0d50c3Schristos void
do_calls_non_split(Relobj * object,unsigned int shndx,section_offset_type fnoffset,section_size_type fnsize,const unsigned char *,size_t,unsigned char * view,section_size_type view_size,std::string * from,std::string * to) const3994ed0d50c3Schristos Target_i386::do_calls_non_split(Relobj* object, unsigned int shndx,
3995ed0d50c3Schristos 				       section_offset_type fnoffset,
3996ed0d50c3Schristos 				       section_size_type fnsize,
3997ed0d50c3Schristos 				       const unsigned char*,
3998ed0d50c3Schristos 				       size_t,
3999ed0d50c3Schristos 				       unsigned char* view,
4000ed0d50c3Schristos 				       section_size_type view_size,
4001ed0d50c3Schristos 				       std::string* from,
4002ed0d50c3Schristos 				       std::string* to) const
4003ed0d50c3Schristos {
4004ed0d50c3Schristos   // The function starts with a comparison of the stack pointer and a
4005ed0d50c3Schristos   // field in the TCB.  This is followed by a jump.
4006ed0d50c3Schristos 
4007ed0d50c3Schristos   // cmp %gs:NN,%esp
4008ed0d50c3Schristos   if (this->match_view(view, view_size, fnoffset, "\x65\x3b\x25", 3)
4009ed0d50c3Schristos       && fnsize > 7)
4010ed0d50c3Schristos     {
4011ed0d50c3Schristos       // We will call __morestack if the carry flag is set after this
4012ed0d50c3Schristos       // comparison.  We turn the comparison into an stc instruction
4013ed0d50c3Schristos       // and some nops.
4014ed0d50c3Schristos       view[fnoffset] = '\xf9';
4015ed0d50c3Schristos       this->set_view_to_nop(view, view_size, fnoffset + 1, 6);
4016ed0d50c3Schristos     }
4017ed0d50c3Schristos   // lea NN(%esp),%ecx
4018ed0d50c3Schristos   // lea NN(%esp),%edx
4019ed0d50c3Schristos   else if ((this->match_view(view, view_size, fnoffset, "\x8d\x8c\x24", 3)
4020ed0d50c3Schristos 	    || this->match_view(view, view_size, fnoffset, "\x8d\x94\x24", 3))
4021ed0d50c3Schristos 	   && fnsize > 7)
4022ed0d50c3Schristos     {
4023ed0d50c3Schristos       // This is loading an offset from the stack pointer for a
4024ed0d50c3Schristos       // comparison.  The offset is negative, so we decrease the
4025ed0d50c3Schristos       // offset by the amount of space we need for the stack.  This
4026ed0d50c3Schristos       // means we will avoid calling __morestack if there happens to
4027ed0d50c3Schristos       // be plenty of space on the stack already.
4028ed0d50c3Schristos       unsigned char* pval = view + fnoffset + 3;
4029ed0d50c3Schristos       uint32_t val = elfcpp::Swap_unaligned<32, false>::readval(pval);
4030ed0d50c3Schristos       val -= parameters->options().split_stack_adjust_size();
4031ed0d50c3Schristos       elfcpp::Swap_unaligned<32, false>::writeval(pval, val);
4032ed0d50c3Schristos     }
4033ed0d50c3Schristos   else
4034ed0d50c3Schristos     {
4035ed0d50c3Schristos       if (!object->has_no_split_stack())
4036ed0d50c3Schristos 	object->error(_("failed to match split-stack sequence at "
4037ed0d50c3Schristos 			"section %u offset %0zx"),
4038ed0d50c3Schristos 		      shndx, static_cast<size_t>(fnoffset));
4039ed0d50c3Schristos       return;
4040ed0d50c3Schristos     }
4041ed0d50c3Schristos 
4042ed0d50c3Schristos   // We have to change the function so that it calls
4043ed0d50c3Schristos   // __morestack_non_split instead of __morestack.  The former will
4044ed0d50c3Schristos   // allocate additional stack space.
4045ed0d50c3Schristos   *from = "__morestack";
4046ed0d50c3Schristos   *to = "__morestack_non_split";
4047ed0d50c3Schristos }
4048ed0d50c3Schristos 
4049ed0d50c3Schristos // The selector for i386 object files.  Note this is never instantiated
4050ed0d50c3Schristos // directly.  It's only used in Target_selector_i386_nacl, below.
4051ed0d50c3Schristos 
4052ed0d50c3Schristos class Target_selector_i386 : public Target_selector_freebsd
4053ed0d50c3Schristos {
4054ed0d50c3Schristos public:
Target_selector_i386()4055ed0d50c3Schristos   Target_selector_i386()
4056ed0d50c3Schristos     : Target_selector_freebsd(elfcpp::EM_386, 32, false,
4057ed0d50c3Schristos 			      "elf32-i386", "elf32-i386-freebsd",
4058ed0d50c3Schristos 			      "elf_i386")
4059ed0d50c3Schristos   { }
4060ed0d50c3Schristos 
4061ed0d50c3Schristos   Target*
do_instantiate_target()4062ed0d50c3Schristos   do_instantiate_target()
4063ed0d50c3Schristos   { return new Target_i386(); }
4064ed0d50c3Schristos };
4065ed0d50c3Schristos 
4066ed0d50c3Schristos // NaCl variant.  It uses different PLT contents.
4067ed0d50c3Schristos 
4068ed0d50c3Schristos class Output_data_plt_i386_nacl : public Output_data_plt_i386
4069ed0d50c3Schristos {
4070ed0d50c3Schristos  public:
Output_data_plt_i386_nacl(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative)4071ed0d50c3Schristos   Output_data_plt_i386_nacl(Layout* layout,
4072ed0d50c3Schristos 			    Output_data_got_plt_i386* got_plt,
4073ed0d50c3Schristos 			    Output_data_space* got_irelative)
4074ed0d50c3Schristos     : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
4075ed0d50c3Schristos   { }
4076ed0d50c3Schristos 
4077ed0d50c3Schristos  protected:
4078ed0d50c3Schristos   virtual unsigned int
do_get_plt_entry_size() const4079ed0d50c3Schristos   do_get_plt_entry_size() const
4080ed0d50c3Schristos   { return plt_entry_size; }
4081ed0d50c3Schristos 
4082ed0d50c3Schristos   virtual void
do_add_eh_frame(Layout * layout)4083ed0d50c3Schristos   do_add_eh_frame(Layout* layout)
4084ed0d50c3Schristos   {
4085ed0d50c3Schristos     layout->add_eh_frame_for_plt(this, plt_eh_frame_cie, plt_eh_frame_cie_size,
4086ed0d50c3Schristos 				 plt_eh_frame_fde, plt_eh_frame_fde_size);
4087ed0d50c3Schristos   }
4088ed0d50c3Schristos 
4089ed0d50c3Schristos   // The size of an entry in the PLT.
4090ed0d50c3Schristos   static const int plt_entry_size = 64;
4091ed0d50c3Schristos 
4092ed0d50c3Schristos   // The .eh_frame unwind information for the PLT.
4093ed0d50c3Schristos   static const int plt_eh_frame_fde_size = 32;
4094ed0d50c3Schristos   static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size];
4095ed0d50c3Schristos };
4096ed0d50c3Schristos 
4097ed0d50c3Schristos class Output_data_plt_i386_nacl_exec : public Output_data_plt_i386_nacl
4098ed0d50c3Schristos {
4099ed0d50c3Schristos public:
Output_data_plt_i386_nacl_exec(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative)4100ed0d50c3Schristos   Output_data_plt_i386_nacl_exec(Layout* layout,
4101ed0d50c3Schristos 				 Output_data_got_plt_i386* got_plt,
4102ed0d50c3Schristos 				 Output_data_space* got_irelative)
4103ed0d50c3Schristos     : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
4104ed0d50c3Schristos   { }
4105ed0d50c3Schristos 
4106ed0d50c3Schristos  protected:
4107ed0d50c3Schristos   virtual void
4108ed0d50c3Schristos   do_fill_first_plt_entry(unsigned char* pov,
4109ed0d50c3Schristos 			  elfcpp::Elf_types<32>::Elf_Addr got_address);
4110ed0d50c3Schristos 
4111ed0d50c3Schristos   virtual unsigned int
4112ed0d50c3Schristos   do_fill_plt_entry(unsigned char* pov,
4113ed0d50c3Schristos 		    elfcpp::Elf_types<32>::Elf_Addr got_address,
4114ed0d50c3Schristos 		    unsigned int got_offset,
4115ed0d50c3Schristos 		    unsigned int plt_offset,
4116ed0d50c3Schristos 		    unsigned int plt_rel_offset);
4117ed0d50c3Schristos 
4118ed0d50c3Schristos  private:
4119ed0d50c3Schristos   // The first entry in the PLT for an executable.
4120ed0d50c3Schristos   static const unsigned char first_plt_entry[plt_entry_size];
4121ed0d50c3Schristos 
4122ed0d50c3Schristos   // Other entries in the PLT for an executable.
4123ed0d50c3Schristos   static const unsigned char plt_entry[plt_entry_size];
4124ed0d50c3Schristos };
4125ed0d50c3Schristos 
4126ed0d50c3Schristos class Output_data_plt_i386_nacl_dyn : public Output_data_plt_i386_nacl
4127ed0d50c3Schristos {
4128ed0d50c3Schristos  public:
Output_data_plt_i386_nacl_dyn(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative)4129ed0d50c3Schristos   Output_data_plt_i386_nacl_dyn(Layout* layout,
4130ed0d50c3Schristos 				Output_data_got_plt_i386* got_plt,
4131ed0d50c3Schristos 				Output_data_space* got_irelative)
4132ed0d50c3Schristos     : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
4133ed0d50c3Schristos   { }
4134ed0d50c3Schristos 
4135ed0d50c3Schristos  protected:
4136ed0d50c3Schristos   virtual void
4137ed0d50c3Schristos   do_fill_first_plt_entry(unsigned char* pov, elfcpp::Elf_types<32>::Elf_Addr);
4138ed0d50c3Schristos 
4139ed0d50c3Schristos   virtual unsigned int
4140ed0d50c3Schristos   do_fill_plt_entry(unsigned char* pov,
4141ed0d50c3Schristos 		    elfcpp::Elf_types<32>::Elf_Addr,
4142ed0d50c3Schristos 		    unsigned int got_offset,
4143ed0d50c3Schristos 		    unsigned int plt_offset,
4144ed0d50c3Schristos 		    unsigned int plt_rel_offset);
4145ed0d50c3Schristos 
4146ed0d50c3Schristos  private:
4147ed0d50c3Schristos   // The first entry in the PLT for a shared object.
4148ed0d50c3Schristos   static const unsigned char first_plt_entry[plt_entry_size];
4149ed0d50c3Schristos 
4150ed0d50c3Schristos   // Other entries in the PLT for a shared object.
4151ed0d50c3Schristos   static const unsigned char plt_entry[plt_entry_size];
4152ed0d50c3Schristos };
4153ed0d50c3Schristos 
4154ed0d50c3Schristos class Target_i386_nacl : public Target_i386
4155ed0d50c3Schristos {
4156ed0d50c3Schristos  public:
Target_i386_nacl()4157ed0d50c3Schristos   Target_i386_nacl()
4158ed0d50c3Schristos     : Target_i386(&i386_nacl_info)
4159ed0d50c3Schristos   { }
4160ed0d50c3Schristos 
4161ed0d50c3Schristos  protected:
4162ed0d50c3Schristos   virtual Output_data_plt_i386*
do_make_data_plt(Layout * layout,Output_data_got_plt_i386 * got_plt,Output_data_space * got_irelative,bool dyn)4163ed0d50c3Schristos   do_make_data_plt(Layout* layout,
4164ed0d50c3Schristos 		   Output_data_got_plt_i386* got_plt,
4165ed0d50c3Schristos 		   Output_data_space* got_irelative,
4166ed0d50c3Schristos 		   bool dyn)
4167ed0d50c3Schristos   {
4168ed0d50c3Schristos     if (dyn)
4169ed0d50c3Schristos       return new Output_data_plt_i386_nacl_dyn(layout, got_plt, got_irelative);
4170ed0d50c3Schristos     else
4171ed0d50c3Schristos       return new Output_data_plt_i386_nacl_exec(layout, got_plt, got_irelative);
4172ed0d50c3Schristos   }
4173ed0d50c3Schristos 
4174ed0d50c3Schristos   virtual std::string
4175ed0d50c3Schristos   do_code_fill(section_size_type length) const;
4176ed0d50c3Schristos 
4177ed0d50c3Schristos  private:
4178ed0d50c3Schristos   static const Target::Target_info i386_nacl_info;
4179ed0d50c3Schristos };
4180ed0d50c3Schristos 
4181ed0d50c3Schristos const Target::Target_info Target_i386_nacl::i386_nacl_info =
4182ed0d50c3Schristos {
4183ed0d50c3Schristos   32,			// size
4184ed0d50c3Schristos   false,		// is_big_endian
4185ed0d50c3Schristos   elfcpp::EM_386,	// machine_code
4186ed0d50c3Schristos   false,		// has_make_symbol
4187ed0d50c3Schristos   false,		// has_resolve
4188ed0d50c3Schristos   true,			// has_code_fill
4189ed0d50c3Schristos   true,			// is_default_stack_executable
4190ed0d50c3Schristos   true,			// can_icf_inline_merge_sections
4191ed0d50c3Schristos   '\0',			// wrap_char
4192ed0d50c3Schristos   "/lib/ld-nacl-x86-32.so.1", // dynamic_linker
4193ed0d50c3Schristos   0x20000,		// default_text_segment_address
4194ed0d50c3Schristos   0x10000,		// abi_pagesize (overridable by -z max-page-size)
4195ed0d50c3Schristos   0x10000,		// common_pagesize (overridable by -z common-page-size)
4196ed0d50c3Schristos   true,                 // isolate_execinstr
4197ed0d50c3Schristos   0x10000000,           // rosegment_gap
4198ed0d50c3Schristos   elfcpp::SHN_UNDEF,	// small_common_shndx
4199ed0d50c3Schristos   elfcpp::SHN_UNDEF,	// large_common_shndx
4200ed0d50c3Schristos   0,			// small_common_section_flags
4201ed0d50c3Schristos   0,			// large_common_section_flags
4202ed0d50c3Schristos   NULL,			// attributes_section
4203ed0d50c3Schristos   NULL,			// attributes_vendor
4204ed0d50c3Schristos   "_start",		// entry_symbol_name
4205ed0d50c3Schristos   32,			// hash_entry_size
420606324dcfSchristos   elfcpp::SHT_PROGBITS,	// unwind_section_type
4207ed0d50c3Schristos };
4208ed0d50c3Schristos 
4209ed0d50c3Schristos #define	NACLMASK	0xe0            // 32-byte alignment mask
4210ed0d50c3Schristos 
4211ed0d50c3Schristos const unsigned char
4212ed0d50c3Schristos Output_data_plt_i386_nacl_exec::first_plt_entry[plt_entry_size] =
4213ed0d50c3Schristos {
4214ed0d50c3Schristos   0xff, 0x35,                          // pushl contents of memory address
4215ed0d50c3Schristos   0, 0, 0, 0,                          // replaced with address of .got + 4
4216ed0d50c3Schristos   0x8b, 0x0d,                          // movl contents of address, %ecx
4217ed0d50c3Schristos   0, 0, 0, 0,                          // replaced with address of .got + 8
4218ed0d50c3Schristos   0x83, 0xe1, NACLMASK,                // andl $NACLMASK, %ecx
4219ed0d50c3Schristos   0xff, 0xe1,                          // jmp *%ecx
4220ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4221ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4222ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4223ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4224ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4225ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4226ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4227ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90
4228ed0d50c3Schristos };
4229ed0d50c3Schristos 
4230ed0d50c3Schristos void
do_fill_first_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr got_address)4231ed0d50c3Schristos Output_data_plt_i386_nacl_exec::do_fill_first_plt_entry(
4232ed0d50c3Schristos     unsigned char* pov,
4233ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr got_address)
4234ed0d50c3Schristos {
4235ed0d50c3Schristos   memcpy(pov, first_plt_entry, plt_entry_size);
4236ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_address + 4);
4237ed0d50c3Schristos   elfcpp::Swap<32, false>::writeval(pov + 8, got_address + 8);
4238ed0d50c3Schristos }
4239ed0d50c3Schristos 
4240ed0d50c3Schristos // The first entry in the PLT for a shared object.
4241ed0d50c3Schristos 
4242ed0d50c3Schristos const unsigned char
4243ed0d50c3Schristos Output_data_plt_i386_nacl_dyn::first_plt_entry[plt_entry_size] =
4244ed0d50c3Schristos {
4245ed0d50c3Schristos   0xff, 0xb3, 4, 0, 0, 0,	// pushl 4(%ebx)
4246ed0d50c3Schristos   0x8b, 0x4b, 0x08,		// mov 0x8(%ebx), %ecx
4247ed0d50c3Schristos   0x83, 0xe1, NACLMASK,         // andl $NACLMASK, %ecx
4248ed0d50c3Schristos   0xff, 0xe1,                   // jmp *%ecx
4249ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4250ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4251ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4252ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4253ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4254ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4255ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4256ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4257ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90,  // nops
4258ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90   // nops
4259ed0d50c3Schristos };
4260ed0d50c3Schristos 
4261ed0d50c3Schristos void
do_fill_first_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr)4262ed0d50c3Schristos Output_data_plt_i386_nacl_dyn::do_fill_first_plt_entry(
4263ed0d50c3Schristos     unsigned char* pov,
4264ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr)
4265ed0d50c3Schristos {
4266ed0d50c3Schristos   memcpy(pov, first_plt_entry, plt_entry_size);
4267ed0d50c3Schristos }
4268ed0d50c3Schristos 
4269ed0d50c3Schristos // Subsequent entries in the PLT for an executable.
4270ed0d50c3Schristos 
4271ed0d50c3Schristos const unsigned char
4272ed0d50c3Schristos Output_data_plt_i386_nacl_exec::plt_entry[plt_entry_size] =
4273ed0d50c3Schristos {
4274ed0d50c3Schristos   0x8b, 0x0d,                    // movl contents of address, %ecx */
4275ed0d50c3Schristos   0, 0, 0, 0,                    // replaced with address of symbol in .got
4276ed0d50c3Schristos   0x83, 0xe1, NACLMASK,          // andl $NACLMASK, %ecx
4277ed0d50c3Schristos   0xff, 0xe1,                    // jmp *%ecx
4278ed0d50c3Schristos 
4279ed0d50c3Schristos   // Pad to the next 32-byte boundary with nop instructions.
4280ed0d50c3Schristos   0x90,
4281ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4282ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4283ed0d50c3Schristos 
4284ed0d50c3Schristos   // Lazy GOT entries point here (32-byte aligned).
4285ed0d50c3Schristos   0x68,                       // pushl immediate
4286ed0d50c3Schristos   0, 0, 0, 0,                 // replaced with offset into relocation table
4287ed0d50c3Schristos   0xe9,                       // jmp relative
4288ed0d50c3Schristos   0, 0, 0, 0,                 // replaced with offset to start of .plt
4289ed0d50c3Schristos 
4290ed0d50c3Schristos   // Pad to the next 32-byte boundary with nop instructions.
4291ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4292ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4293ed0d50c3Schristos   0x90, 0x90
4294ed0d50c3Schristos };
4295ed0d50c3Schristos 
4296ed0d50c3Schristos unsigned int
do_fill_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr got_address,unsigned int got_offset,unsigned int plt_offset,unsigned int plt_rel_offset)4297ed0d50c3Schristos Output_data_plt_i386_nacl_exec::do_fill_plt_entry(
4298ed0d50c3Schristos     unsigned char* pov,
4299ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr got_address,
4300ed0d50c3Schristos     unsigned int got_offset,
4301ed0d50c3Schristos     unsigned int plt_offset,
4302ed0d50c3Schristos     unsigned int plt_rel_offset)
4303ed0d50c3Schristos {
4304ed0d50c3Schristos   memcpy(pov, plt_entry, plt_entry_size);
4305ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2,
4306ed0d50c3Schristos 					      got_address + got_offset);
4307ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset);
4308ed0d50c3Schristos   elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4));
4309ed0d50c3Schristos   return 32;
4310ed0d50c3Schristos }
4311ed0d50c3Schristos 
4312ed0d50c3Schristos // Subsequent entries in the PLT for a shared object.
4313ed0d50c3Schristos 
4314ed0d50c3Schristos const unsigned char
4315ed0d50c3Schristos Output_data_plt_i386_nacl_dyn::plt_entry[plt_entry_size] =
4316ed0d50c3Schristos {
4317ed0d50c3Schristos   0x8b, 0x8b,          // movl offset(%ebx), %ecx
4318ed0d50c3Schristos   0, 0, 0, 0,          // replaced with offset of symbol in .got
4319ed0d50c3Schristos   0x83, 0xe1, 0xe0,    // andl $NACLMASK, %ecx
4320ed0d50c3Schristos   0xff, 0xe1,          // jmp *%ecx
4321ed0d50c3Schristos 
4322ed0d50c3Schristos   // Pad to the next 32-byte boundary with nop instructions.
4323ed0d50c3Schristos   0x90,
4324ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4325ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4326ed0d50c3Schristos 
4327ed0d50c3Schristos   // Lazy GOT entries point here (32-byte aligned).
4328ed0d50c3Schristos   0x68,                // pushl immediate
4329ed0d50c3Schristos   0, 0, 0, 0,          // replaced with offset into relocation table.
4330ed0d50c3Schristos   0xe9,                // jmp relative
4331ed0d50c3Schristos   0, 0, 0, 0,          // replaced with offset to start of .plt.
4332ed0d50c3Schristos 
4333ed0d50c3Schristos   // Pad to the next 32-byte boundary with nop instructions.
4334ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4335ed0d50c3Schristos   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4336ed0d50c3Schristos   0x90, 0x90
4337ed0d50c3Schristos };
4338ed0d50c3Schristos 
4339ed0d50c3Schristos unsigned int
do_fill_plt_entry(unsigned char * pov,elfcpp::Elf_types<32>::Elf_Addr,unsigned int got_offset,unsigned int plt_offset,unsigned int plt_rel_offset)4340ed0d50c3Schristos Output_data_plt_i386_nacl_dyn::do_fill_plt_entry(
4341ed0d50c3Schristos     unsigned char* pov,
4342ed0d50c3Schristos     elfcpp::Elf_types<32>::Elf_Addr,
4343ed0d50c3Schristos     unsigned int got_offset,
4344ed0d50c3Schristos     unsigned int plt_offset,
4345ed0d50c3Schristos     unsigned int plt_rel_offset)
4346ed0d50c3Schristos {
4347ed0d50c3Schristos   memcpy(pov, plt_entry, plt_entry_size);
4348ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset);
4349ed0d50c3Schristos   elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset);
4350ed0d50c3Schristos   elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4));
4351ed0d50c3Schristos   return 32;
4352ed0d50c3Schristos }
4353ed0d50c3Schristos 
4354ed0d50c3Schristos const unsigned char
4355ed0d50c3Schristos Output_data_plt_i386_nacl::plt_eh_frame_fde[plt_eh_frame_fde_size] =
4356ed0d50c3Schristos {
4357ed0d50c3Schristos   0, 0, 0, 0,				// Replaced with offset to .plt.
4358ed0d50c3Schristos   0, 0, 0, 0,				// Replaced with size of .plt.
4359ed0d50c3Schristos   0,					// Augmentation size.
4360ed0d50c3Schristos   elfcpp::DW_CFA_def_cfa_offset, 8,	// DW_CFA_def_cfa_offset: 8.
4361ed0d50c3Schristos   elfcpp::DW_CFA_advance_loc + 6,	// Advance 6 to __PLT__ + 6.
4362ed0d50c3Schristos   elfcpp::DW_CFA_def_cfa_offset, 12,	// DW_CFA_def_cfa_offset: 12.
4363ed0d50c3Schristos   elfcpp::DW_CFA_advance_loc + 58,	// Advance 58 to __PLT__ + 64.
4364ed0d50c3Schristos   elfcpp::DW_CFA_def_cfa_expression,	// DW_CFA_def_cfa_expression.
4365ed0d50c3Schristos   13,					// Block length.
4366ed0d50c3Schristos   elfcpp::DW_OP_breg4, 4,		// Push %esp + 4.
4367ed0d50c3Schristos   elfcpp::DW_OP_breg8, 0,		// Push %eip.
4368ed0d50c3Schristos   elfcpp::DW_OP_const1u, 63,            // Push 0x3f.
4369ed0d50c3Schristos   elfcpp::DW_OP_and,			// & (%eip & 0x3f).
4370ed0d50c3Schristos   elfcpp::DW_OP_const1u, 37,            // Push 0x25.
4371ed0d50c3Schristos   elfcpp::DW_OP_ge,			// >= ((%eip & 0x3f) >= 0x25)
4372ed0d50c3Schristos   elfcpp::DW_OP_lit2,			// Push 2.
4373ed0d50c3Schristos   elfcpp::DW_OP_shl,			// << (((%eip & 0x3f) >= 0x25) << 2)
4374ed0d50c3Schristos   elfcpp::DW_OP_plus,			// + ((((%eip&0x3f)>=0x25)<<2)+%esp+4
4375ed0d50c3Schristos   elfcpp::DW_CFA_nop,			// Align to 32 bytes.
4376ed0d50c3Schristos   elfcpp::DW_CFA_nop
4377ed0d50c3Schristos };
4378ed0d50c3Schristos 
4379ed0d50c3Schristos // Return a string used to fill a code section with nops.
4380ed0d50c3Schristos // For NaCl, long NOPs are only valid if they do not cross
4381ed0d50c3Schristos // bundle alignment boundaries, so keep it simple with one-byte NOPs.
4382ed0d50c3Schristos std::string
do_code_fill(section_size_type length) const4383ed0d50c3Schristos Target_i386_nacl::do_code_fill(section_size_type length) const
4384ed0d50c3Schristos {
4385ed0d50c3Schristos   return std::string(length, static_cast<char>(0x90));
4386ed0d50c3Schristos }
4387ed0d50c3Schristos 
4388ed0d50c3Schristos // The selector for i386-nacl object files.
4389ed0d50c3Schristos 
4390ed0d50c3Schristos class Target_selector_i386_nacl
4391ed0d50c3Schristos   : public Target_selector_nacl<Target_selector_i386, Target_i386_nacl>
4392ed0d50c3Schristos {
4393ed0d50c3Schristos  public:
Target_selector_i386_nacl()4394ed0d50c3Schristos   Target_selector_i386_nacl()
4395ed0d50c3Schristos     : Target_selector_nacl<Target_selector_i386,
4396ed0d50c3Schristos 			   Target_i386_nacl>("x86-32",
4397ed0d50c3Schristos 					     "elf32-i386-nacl",
4398ed0d50c3Schristos 					     "elf_i386_nacl")
4399ed0d50c3Schristos   { }
4400ed0d50c3Schristos };
4401ed0d50c3Schristos 
4402ed0d50c3Schristos Target_selector_i386_nacl target_selector_i386;
4403ed0d50c3Schristos 
4404ed0d50c3Schristos // IAMCU variant.  It uses EM_IAMCU, not EM_386.
4405ed0d50c3Schristos 
4406ed0d50c3Schristos class Target_iamcu : public Target_i386
4407ed0d50c3Schristos {
4408ed0d50c3Schristos  public:
Target_iamcu()4409ed0d50c3Schristos   Target_iamcu()
4410ed0d50c3Schristos     : Target_i386(&iamcu_info)
4411ed0d50c3Schristos   { }
4412ed0d50c3Schristos 
4413ed0d50c3Schristos  private:
4414ed0d50c3Schristos   // Information about this specific target which we pass to the
4415ed0d50c3Schristos   // general Target structure.
4416ed0d50c3Schristos   static const Target::Target_info iamcu_info;
4417ed0d50c3Schristos };
4418ed0d50c3Schristos 
4419ed0d50c3Schristos const Target::Target_info Target_iamcu::iamcu_info =
4420ed0d50c3Schristos {
4421ed0d50c3Schristos   32,			// size
4422ed0d50c3Schristos   false,		// is_big_endian
4423ed0d50c3Schristos   elfcpp::EM_IAMCU,	// machine_code
4424ed0d50c3Schristos   false,		// has_make_symbol
4425ed0d50c3Schristos   false,		// has_resolve
4426ed0d50c3Schristos   true,			// has_code_fill
4427ed0d50c3Schristos   true,			// is_default_stack_executable
4428ed0d50c3Schristos   true,			// can_icf_inline_merge_sections
4429ed0d50c3Schristos   '\0',			// wrap_char
4430ed0d50c3Schristos   "/usr/lib/libc.so.1",	// dynamic_linker
4431ed0d50c3Schristos   0x08048000,		// default_text_segment_address
4432ed0d50c3Schristos   0x1000,		// abi_pagesize (overridable by -z max-page-size)
4433ed0d50c3Schristos   0x1000,		// common_pagesize (overridable by -z common-page-size)
4434ed0d50c3Schristos   false,                // isolate_execinstr
4435ed0d50c3Schristos   0,                    // rosegment_gap
4436ed0d50c3Schristos   elfcpp::SHN_UNDEF,	// small_common_shndx
4437ed0d50c3Schristos   elfcpp::SHN_UNDEF,	// large_common_shndx
4438ed0d50c3Schristos   0,			// small_common_section_flags
4439ed0d50c3Schristos   0,			// large_common_section_flags
4440ed0d50c3Schristos   NULL,			// attributes_section
4441ed0d50c3Schristos   NULL,			// attributes_vendor
4442ed0d50c3Schristos   "_start",		// entry_symbol_name
4443ed0d50c3Schristos   32,			// hash_entry_size
444406324dcfSchristos   elfcpp::SHT_PROGBITS,	// unwind_section_type
4445ed0d50c3Schristos };
4446ed0d50c3Schristos 
4447ed0d50c3Schristos class Target_selector_iamcu : public Target_selector
4448ed0d50c3Schristos {
4449ed0d50c3Schristos public:
Target_selector_iamcu()4450ed0d50c3Schristos   Target_selector_iamcu()
4451ed0d50c3Schristos     : Target_selector(elfcpp::EM_IAMCU, 32, false, "elf32-iamcu",
4452ed0d50c3Schristos 		      "elf_iamcu")
4453ed0d50c3Schristos   { }
4454ed0d50c3Schristos 
4455ed0d50c3Schristos   Target*
do_instantiate_target()4456ed0d50c3Schristos   do_instantiate_target()
4457ed0d50c3Schristos   { return new Target_iamcu(); }
4458ed0d50c3Schristos };
4459ed0d50c3Schristos 
4460ed0d50c3Schristos Target_selector_iamcu target_selector_iamcu;
4461ed0d50c3Schristos 
4462ed0d50c3Schristos } // End anonymous namespace.
4463