1// tilegx.cc -- tilegx target support for gold.
2
3// Copyright (C) 2012-2017 Free Software Foundation, Inc.
4// Written by Jiong Wang (jiwang@tilera.com)
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
23#include "gold.h"
24
25#include <cstring>
26
27#include "elfcpp.h"
28#include "dwarf.h"
29#include "parameters.h"
30#include "reloc.h"
31#include "tilegx.h"
32#include "object.h"
33#include "symtab.h"
34#include "layout.h"
35#include "output.h"
36#include "copy-relocs.h"
37#include "target.h"
38#include "target-reloc.h"
39#include "target-select.h"
40#include "tls.h"
41#include "gc.h"
42#include "icf.h"
43
44// the first got entry reserved
45const int32_t TILEGX_GOT_RESERVE_COUNT = 1;
46
47// the first two .got.plt entry reserved
48const int32_t TILEGX_GOTPLT_RESERVE_COUNT = 2;
49
50// 1. for both 64/32 bit mode, the instruction bundle is always 64bit.
51// 2. thus .plt section should always be aligned to 64 bit.
52const int32_t TILEGX_INST_BUNDLE_SIZE = 64;
53
54namespace
55{
56
57using namespace gold;
58
59// A class to handle the PLT data.
60// This is an abstract base class that handles most of the linker details
61// but does not know the actual contents of PLT entries.  The derived
62// classes below fill in those details.
63
64template<int size, bool big_endian>
65class Output_data_plt_tilegx : public Output_section_data
66{
67 public:
68  typedef Output_data_reloc<elfcpp::SHT_RELA, true,size, big_endian>
69    Reloc_section;
70
71  Output_data_plt_tilegx(Layout* layout, uint64_t addralign,
72                         Output_data_got<size, big_endian>* got,
73                         Output_data_space* got_plt,
74                         Output_data_space* got_irelative)
75    : Output_section_data(addralign), layout_(layout),
76      irelative_rel_(NULL), got_(got), got_plt_(got_plt),
77      got_irelative_(got_irelative), count_(0),
78      irelative_count_(0), free_list_()
79  { this->init(layout); }
80
81  Output_data_plt_tilegx(Layout* layout, uint64_t plt_entry_size,
82                         Output_data_got<size, big_endian>* got,
83                         Output_data_space* got_plt,
84                         Output_data_space* got_irelative,
85                         unsigned int plt_count)
86    : Output_section_data((plt_count + 1) * plt_entry_size,
87                          TILEGX_INST_BUNDLE_SIZE, false),
88      layout_(layout), irelative_rel_(NULL), got_(got),
89      got_plt_(got_plt), got_irelative_(got_irelative), count_(plt_count),
90      irelative_count_(0), free_list_()
91  {
92    this->init(layout);
93
94    // Initialize the free list and reserve the first entry.
95    this->free_list_.init((plt_count + 1) * plt_entry_size, false);
96    this->free_list_.remove(0, plt_entry_size);
97  }
98
99  // Initialize the PLT section.
100  void
101  init(Layout* layout);
102
103  // Add an entry to the PLT.
104  void
105  add_entry(Symbol_table*, Layout*, Symbol* gsym);
106
107  // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
108  unsigned int
109  add_local_ifunc_entry(Symbol_table*, Layout*,
110    Sized_relobj_file<size, big_endian>*, unsigned int);
111
112  // Add the relocation for a PLT entry.
113  void
114  add_relocation(Symbol_table*, Layout*, Symbol*, unsigned int);
115
116  // Return the .rela.plt section data.
117  Reloc_section*
118  rela_plt()
119  { return this->rel_; }
120
121  // Return where the IRELATIVE relocations should go in the PLT
122  // relocations.
123  Reloc_section*
124  rela_irelative(Symbol_table*, Layout*);
125
126  // Return whether we created a section for IRELATIVE relocations.
127  bool
128  has_irelative_section() const
129  { return this->irelative_rel_ != NULL; }
130
131  // Return the number of PLT entries.
132  unsigned int
133  entry_count() const
134  { return this->count_ + this->irelative_count_; }
135
136  // Return the offset of the first non-reserved PLT entry.
137  unsigned int
138  first_plt_entry_offset()
139  { return this->get_plt_entry_size(); }
140
141  // Return the size of a PLT entry.
142  unsigned int
143  get_plt_entry_size() const
144  { return plt_entry_size; }
145
146  // Reserve a slot in the PLT for an existing symbol in an incremental update.
147  void
148  reserve_slot(unsigned int plt_index)
149  {
150    this->free_list_.remove((plt_index + 1) * this->get_plt_entry_size(),
151                            (plt_index + 2) * this->get_plt_entry_size());
152  }
153
154  // Return the PLT address to use for a global symbol.
155  uint64_t
156  address_for_global(const Symbol*);
157
158  // Return the PLT address to use for a local symbol.
159  uint64_t
160  address_for_local(const Relobj*, unsigned int symndx);
161
162 protected:
163  // Fill in the first PLT entry.
164  void
165  fill_first_plt_entry(unsigned char*);
166
167  // Fill in a normal PLT entry.  Returns the offset into the entry that
168  // should be the initial GOT slot value.
169  void
170  fill_plt_entry(unsigned char*,
171                 typename elfcpp::Elf_types<size>::Elf_Addr,
172                 unsigned int,
173                 typename elfcpp::Elf_types<size>::Elf_Addr,
174                 unsigned int, unsigned int);
175
176  void
177  do_adjust_output_section(Output_section* os);
178
179  // Write to a map file.
180  void
181  do_print_to_mapfile(Mapfile* mapfile) const
182  { mapfile->print_output_data(this, _("** PLT")); }
183
184 private:
185  // Set the final size.
186  void
187  set_final_data_size();
188
189  // Write out the PLT data.
190  void
191  do_write(Output_file*);
192
193  // A pointer to the Layout class, so that we can find the .dynamic
194  // section when we write out the GOT PLT section.
195  Layout* layout_;
196  // The reloc section.
197  Reloc_section* rel_;
198  // The IRELATIVE relocs, if necessary.  These must follow the
199  // regular PLT relocations.
200  Reloc_section* irelative_rel_;
201  // The .got section.
202  Output_data_got<size, big_endian>* got_;
203  // The .got.plt section.
204  Output_data_space* got_plt_;
205  // The part of the .got.plt section used for IRELATIVE relocs.
206  Output_data_space* got_irelative_;
207  // The number of PLT entries.
208  unsigned int count_;
209  // Number of PLT entries with R_TILEGX_IRELATIVE relocs.  These
210  // follow the regular PLT entries.
211  unsigned int irelative_count_;
212  // List of available regions within the section, for incremental
213  // update links.
214  Free_list free_list_;
215  // The size of an entry in the PLT.
216  static const int plt_entry_size = 40;
217  // The first entry in the PLT.
218  static const unsigned char first_plt_entry[plt_entry_size];
219  // Other entries in the PLT for an executable.
220  static const unsigned char plt_entry[plt_entry_size];
221};
222
223// The tilegx target class.
224// See the ABI at
225//   http://www.tilera.com/scm
226// TLS info comes from
227//   http://people.redhat.com/drepper/tls.pdf
228
229template<int size, bool big_endian>
230class Target_tilegx : public Sized_target<size, big_endian>
231{
232 public:
233  // TileGX use RELA
234  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
235    Reloc_section;
236
237  Target_tilegx(const Target::Target_info* info = &tilegx_info)
238    : Sized_target<size, big_endian>(info),
239      got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
240      global_offset_table_(NULL), tilegx_dynamic_(NULL), rela_dyn_(NULL),
241      rela_irelative_(NULL), copy_relocs_(elfcpp::R_TILEGX_COPY),
242      got_mod_index_offset_(-1U),
243      tls_get_addr_sym_defined_(false)
244  { }
245
246  // Scan the relocations to look for symbol adjustments.
247  void
248  gc_process_relocs(Symbol_table* symtab,
249                    Layout* layout,
250                    Sized_relobj_file<size, big_endian>* object,
251                    unsigned int data_shndx,
252                    unsigned int sh_type,
253                    const unsigned char* prelocs,
254                    size_t reloc_count,
255                    Output_section* output_section,
256                    bool needs_special_offset_handling,
257                    size_t local_symbol_count,
258                    const unsigned char* plocal_symbols);
259
260  // Scan the relocations to look for symbol adjustments.
261  void
262  scan_relocs(Symbol_table* symtab,
263              Layout* layout,
264              Sized_relobj_file<size, big_endian>* object,
265              unsigned int data_shndx,
266              unsigned int sh_type,
267              const unsigned char* prelocs,
268              size_t reloc_count,
269              Output_section* output_section,
270              bool needs_special_offset_handling,
271              size_t local_symbol_count,
272              const unsigned char* plocal_symbols);
273
274  // Finalize the sections.
275  void
276  do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
277
278  // Return the value to use for a dynamic which requires special
279  // treatment.
280  uint64_t
281  do_dynsym_value(const Symbol*) const;
282
283  // Relocate a section.
284  void
285  relocate_section(const Relocate_info<size, big_endian>*,
286                   unsigned int sh_type,
287                   const unsigned char* prelocs,
288                   size_t reloc_count,
289                   Output_section* output_section,
290                   bool needs_special_offset_handling,
291                   unsigned char* view,
292                   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
293                   section_size_type view_size,
294                   const Reloc_symbol_changes*);
295
296  // Scan the relocs during a relocatable link.
297  void
298  scan_relocatable_relocs(Symbol_table* symtab,
299                          Layout* layout,
300                          Sized_relobj_file<size, big_endian>* object,
301                          unsigned int data_shndx,
302                          unsigned int sh_type,
303                          const unsigned char* prelocs,
304                          size_t reloc_count,
305                          Output_section* output_section,
306                          bool needs_special_offset_handling,
307                          size_t local_symbol_count,
308                          const unsigned char* plocal_symbols,
309                          Relocatable_relocs*);
310
311  // Scan the relocs for --emit-relocs.
312  void
313  emit_relocs_scan(Symbol_table* symtab,
314		   Layout* layout,
315		   Sized_relobj_file<size, big_endian>* object,
316		   unsigned int data_shndx,
317		   unsigned int sh_type,
318		   const unsigned char* prelocs,
319		   size_t reloc_count,
320		   Output_section* output_section,
321		   bool needs_special_offset_handling,
322		   size_t local_symbol_count,
323		   const unsigned char* plocal_syms,
324		   Relocatable_relocs* rr);
325
326  // Relocate a section during a relocatable link.
327  void
328  relocate_relocs(
329      const Relocate_info<size, big_endian>*,
330      unsigned int sh_type,
331      const unsigned char* prelocs,
332      size_t reloc_count,
333      Output_section* output_section,
334      typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
335      unsigned char* view,
336      typename elfcpp::Elf_types<size>::Elf_Addr view_address,
337      section_size_type view_size,
338      unsigned char* reloc_view,
339      section_size_type reloc_view_size);
340
341  // Return whether SYM is defined by the ABI.
342  bool
343  do_is_defined_by_abi(const Symbol* sym) const
344  { return strcmp(sym->name(), "__tls_get_addr") == 0; }
345
346  // define tilegx specific symbols
347  virtual void
348  do_define_standard_symbols(Symbol_table*, Layout*);
349
350  // Return the PLT section.
351  uint64_t
352  do_plt_address_for_global(const Symbol* gsym) const
353  { return this->plt_section()->address_for_global(gsym); }
354
355  uint64_t
356  do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
357  { return this->plt_section()->address_for_local(relobj, symndx); }
358
359  // This function should be defined in targets that can use relocation
360  // types to determine (implemented in local_reloc_may_be_function_pointer
361  // and global_reloc_may_be_function_pointer)
362  // if a function's pointer is taken.  ICF uses this in safe mode to only
363  // fold those functions whose pointer is defintely not taken.  For tilegx
364  // pie binaries, safe ICF cannot be done by looking at relocation types.
365  bool
366  do_can_check_for_function_pointers() const
367  { return true; }
368
369  // Return the base for a DW_EH_PE_datarel encoding.
370  uint64_t
371  do_ehframe_datarel_base() const;
372
373  // Return whether there is a GOT section.
374  bool
375  has_got_section() const
376  { return this->got_ != NULL; }
377
378  // Return the size of the GOT section.
379  section_size_type
380  got_size() const
381  {
382    gold_assert(this->got_ != NULL);
383    return this->got_->data_size();
384  }
385
386  // Return the number of entries in the GOT.
387  unsigned int
388  got_entry_count() const
389  {
390    if (this->got_ == NULL)
391      return 0;
392    return this->got_size() / (size / 8);
393  }
394
395  // Return the number of entries in the PLT.
396  unsigned int
397  plt_entry_count() const;
398
399  // Return the offset of the first non-reserved PLT entry.
400  unsigned int
401  first_plt_entry_offset() const;
402
403  // Return the size of each PLT entry.
404  unsigned int
405  plt_entry_size() const;
406
407  // Create the GOT section for an incremental update.
408  Output_data_got_base*
409  init_got_plt_for_update(Symbol_table* symtab,
410                          Layout* layout,
411                          unsigned int got_count,
412                          unsigned int plt_count);
413
414  // Reserve a GOT entry for a local symbol, and regenerate any
415  // necessary dynamic relocations.
416  void
417  reserve_local_got_entry(unsigned int got_index,
418                          Sized_relobj<size, big_endian>* obj,
419                          unsigned int r_sym,
420                          unsigned int got_type);
421
422  // Reserve a GOT entry for a global symbol, and regenerate any
423  // necessary dynamic relocations.
424  void
425  reserve_global_got_entry(unsigned int got_index, Symbol* gsym,
426                           unsigned int got_type);
427
428  // Register an existing PLT entry for a global symbol.
429  void
430  register_global_plt_entry(Symbol_table*, Layout*, unsigned int plt_index,
431                            Symbol* gsym);
432
433  // Force a COPY relocation for a given symbol.
434  void
435  emit_copy_reloc(Symbol_table*, Symbol*, Output_section*, off_t);
436
437  // Apply an incremental relocation.
438  void
439  apply_relocation(const Relocate_info<size, big_endian>* relinfo,
440                   typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
441                   unsigned int r_type,
442                   typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
443                   const Symbol* gsym,
444                   unsigned char* view,
445                   typename elfcpp::Elf_types<size>::Elf_Addr address,
446                   section_size_type view_size);
447
448 private:
449  // The class which scans relocations.
450  class Scan
451  {
452  public:
453    Scan()
454      : issued_non_pic_error_(false)
455    { }
456
457    static inline int
458    get_reference_flags(unsigned int r_type);
459
460    inline void
461    local(Symbol_table* symtab, Layout* layout, Target_tilegx* target,
462          Sized_relobj_file<size, big_endian>* object,
463          unsigned int data_shndx,
464          Output_section* output_section,
465          const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
466          const elfcpp::Sym<size, big_endian>& lsym,
467          bool is_discarded);
468
469    inline void
470    global(Symbol_table* symtab, Layout* layout, Target_tilegx* target,
471           Sized_relobj_file<size, big_endian>* object,
472           unsigned int data_shndx,
473           Output_section* output_section,
474           const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
475           Symbol* gsym);
476
477    inline bool
478    local_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
479                            Target_tilegx* target,
480                            Sized_relobj_file<size, big_endian>* object,
481                            unsigned int data_shndx,
482                            Output_section* output_section,
483                            const elfcpp::Rela<size, big_endian>& reloc,
484                            unsigned int r_type,
485                            const elfcpp::Sym<size, big_endian>& lsym);
486
487    inline bool
488    global_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
489                            Target_tilegx* target,
490                            Sized_relobj_file<size, big_endian>* object,
491                            unsigned int data_shndx,
492                            Output_section* output_section,
493                            const elfcpp::Rela<size, big_endian>& reloc,
494                            unsigned int r_type,
495                            Symbol* gsym);
496
497  private:
498    static void
499    unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
500                            unsigned int r_type);
501
502    static void
503    unsupported_reloc_global(Sized_relobj_file<size, big_endian>*,
504                             unsigned int r_type, Symbol*);
505
506    void
507    check_non_pic(Relobj*, unsigned int r_type);
508
509    inline bool
510    possible_function_pointer_reloc(unsigned int r_type);
511
512    bool
513    reloc_needs_plt_for_ifunc(Sized_relobj_file<size, big_endian>*,
514                              unsigned int r_type);
515
516    // Whether we have issued an error about a non-PIC compilation.
517    bool issued_non_pic_error_;
518  };
519
520  // The class which implements relocation.
521  class Relocate
522  {
523   public:
524    Relocate()
525    { }
526
527    ~Relocate()
528    {
529    }
530
531    // Do a relocation.  Return false if the caller should not issue
532    // any warnings about this relocation.
533    inline bool
534    relocate(const Relocate_info<size, big_endian>*, unsigned int,
535	     Target_tilegx*, Output_section*, size_t, const unsigned char*,
536	     const Sized_symbol<size>*, const Symbol_value<size>*,
537	     unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
538	     section_size_type);
539  };
540
541  // Adjust TLS relocation type based on the options and whether this
542  // is a local symbol.
543  static tls::Tls_optimization
544  optimize_tls_reloc(bool is_final, int r_type);
545
546  // Get the GOT section, creating it if necessary.
547  Output_data_got<size, big_endian>*
548  got_section(Symbol_table*, Layout*);
549
550  // Get the GOT PLT section.
551  Output_data_space*
552  got_plt_section() const
553  {
554    gold_assert(this->got_plt_ != NULL);
555    return this->got_plt_;
556  }
557
558  // Create the PLT section.
559  void
560  make_plt_section(Symbol_table* symtab, Layout* layout);
561
562  // Create a PLT entry for a global symbol.
563  void
564  make_plt_entry(Symbol_table*, Layout*, Symbol*);
565
566  // Create a PLT entry for a local STT_GNU_IFUNC symbol.
567  void
568  make_local_ifunc_plt_entry(Symbol_table*, Layout*,
569                             Sized_relobj_file<size, big_endian>* relobj,
570                             unsigned int local_sym_index);
571
572  // Create a GOT entry for the TLS module index.
573  unsigned int
574  got_mod_index_entry(Symbol_table* symtab, Layout* layout,
575                      Sized_relobj_file<size, big_endian>* object);
576
577  // Get the PLT section.
578  Output_data_plt_tilegx<size, big_endian>*
579  plt_section() const
580  {
581    gold_assert(this->plt_ != NULL);
582    return this->plt_;
583  }
584
585  // Get the dynamic reloc section, creating it if necessary.
586  Reloc_section*
587  rela_dyn_section(Layout*);
588
589  // Get the section to use for IRELATIVE relocations.
590  Reloc_section*
591  rela_irelative_section(Layout*);
592
593  // Add a potential copy relocation.
594  void
595  copy_reloc(Symbol_table* symtab, Layout* layout,
596             Sized_relobj_file<size, big_endian>* object,
597             unsigned int shndx, Output_section* output_section,
598             Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
599  {
600    unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info());
601    this->copy_relocs_.copy_reloc(symtab, layout,
602                                  symtab->get_sized_symbol<size>(sym),
603                                  object, shndx, output_section,
604				  r_type, reloc.get_r_offset(),
605				  reloc.get_r_addend(),
606                                  this->rela_dyn_section(layout));
607  }
608
609  // Information about this specific target which we pass to the
610  // general Target structure.
611  static const Target::Target_info tilegx_info;
612
613  // The types of GOT entries needed for this platform.
614  // These values are exposed to the ABI in an incremental link.
615  // Do not renumber existing values without changing the version
616  // number of the .gnu_incremental_inputs section.
617  enum Got_type
618  {
619    GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
620    GOT_TYPE_TLS_OFFSET = 1,    // GOT entry for TLS offset
621    GOT_TYPE_TLS_PAIR = 2,      // GOT entry for TLS module/offset pair
622    GOT_TYPE_TLS_DESC = 3       // GOT entry for TLS_DESC pair
623  };
624
625  // This type is used as the argument to the target specific
626  // relocation routines.  The only target specific reloc is
627  // R_X86_64_TLSDESC against a local symbol.
628  struct Tlsdesc_info
629  {
630    Tlsdesc_info(Sized_relobj_file<size, big_endian>* a_object,
631                 unsigned int a_r_sym)
632      : object(a_object), r_sym(a_r_sym)
633    { }
634
635    // The object in which the local symbol is defined.
636    Sized_relobj_file<size, big_endian>* object;
637    // The local symbol index in the object.
638    unsigned int r_sym;
639  };
640
641  // The GOT section.
642  Output_data_got<size, big_endian>* got_;
643  // The PLT section.
644  Output_data_plt_tilegx<size, big_endian>* plt_;
645  // The GOT PLT section.
646  Output_data_space* got_plt_;
647  // The GOT section for IRELATIVE relocations.
648  Output_data_space* got_irelative_;
649  // The _GLOBAL_OFFSET_TABLE_ symbol.
650  Symbol* global_offset_table_;
651  // The _TILEGX_DYNAMIC_ symbol.
652  Symbol* tilegx_dynamic_;
653  // The dynamic reloc section.
654  Reloc_section* rela_dyn_;
655  // The section to use for IRELATIVE relocs.
656  Reloc_section* rela_irelative_;
657  // Relocs saved to avoid a COPY reloc.
658  Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
659  // Offset of the GOT entry for the TLS module index.
660  unsigned int got_mod_index_offset_;
661  // True if the _tls_get_addr symbol has been defined.
662  bool tls_get_addr_sym_defined_;
663};
664
665template<>
666const Target::Target_info Target_tilegx<64, false>::tilegx_info =
667{
668  64,                   // size
669  false,                // is_big_endian
670  elfcpp::EM_TILEGX,    // machine_code
671  false,                // has_make_symbol
672  false,                // has_resolve
673  false,                // has_code_fill
674  true,                 // is_default_stack_executable
675  false,                // can_icf_inline_merge_sections
676  '\0',                 // wrap_char
677  "/lib/ld.so.1",       // program interpreter
678  0x10000,              // default_text_segment_address
679  0x10000,              // abi_pagesize (overridable by -z max-page-size)
680  0x10000,              // common_pagesize (overridable by -z common-page-size)
681  false,                // isolate_execinstr
682  0,                    // rosegment_gap
683  elfcpp::SHN_UNDEF,    // small_common_shndx
684  elfcpp::SHN_UNDEF,    // large_common_shndx
685  0,                    // small_common_section_flags
686  0,                    // large_common_section_flags
687  NULL,                 // attributes_section
688  NULL,                 // attributes_vendor
689  "_start",		// entry_symbol_name
690  32,			// hash_entry_size
691};
692
693template<>
694const Target::Target_info Target_tilegx<32, false>::tilegx_info =
695{
696  32,                   // size
697  false,                // is_big_endian
698  elfcpp::EM_TILEGX,    // machine_code
699  false,                // has_make_symbol
700  false,                // has_resolve
701  false,                // has_code_fill
702  true,                 // is_default_stack_executable
703  false,                // can_icf_inline_merge_sections
704  '\0',                 // wrap_char
705  "/lib32/ld.so.1",     // program interpreter
706  0x10000,              // default_text_segment_address
707  0x10000,              // abi_pagesize (overridable by -z max-page-size)
708  0x10000,              // common_pagesize (overridable by -z common-page-size)
709  false,                // isolate_execinstr
710  0,                    // rosegment_gap
711  elfcpp::SHN_UNDEF,    // small_common_shndx
712  elfcpp::SHN_UNDEF,    // large_common_shndx
713  0,                    // small_common_section_flags
714  0,                    // large_common_section_flags
715  NULL,                 // attributes_section
716  NULL,                 // attributes_vendor
717  "_start",		// entry_symbol_name
718  32,			// hash_entry_size
719};
720
721template<>
722const Target::Target_info Target_tilegx<64, true>::tilegx_info =
723{
724  64,                   // size
725  true,                 // is_big_endian
726  elfcpp::EM_TILEGX,    // machine_code
727  false,                // has_make_symbol
728  false,                // has_resolve
729  false,                // has_code_fill
730  true,                 // is_default_stack_executable
731  false,                // can_icf_inline_merge_sections
732  '\0',                 // wrap_char
733  "/lib/ld.so.1",       // program interpreter
734  0x10000,              // default_text_segment_address
735  0x10000,              // abi_pagesize (overridable by -z max-page-size)
736  0x10000,              // common_pagesize (overridable by -z common-page-size)
737  false,                // isolate_execinstr
738  0,                    // rosegment_gap
739  elfcpp::SHN_UNDEF,    // small_common_shndx
740  elfcpp::SHN_UNDEF,    // large_common_shndx
741  0,                    // small_common_section_flags
742  0,                    // large_common_section_flags
743  NULL,                 // attributes_section
744  NULL,                 // attributes_vendor
745  "_start",		// entry_symbol_name
746  32,			// hash_entry_size
747};
748
749template<>
750const Target::Target_info Target_tilegx<32, true>::tilegx_info =
751{
752  32,                   // size
753  true,                 // is_big_endian
754  elfcpp::EM_TILEGX,    // machine_code
755  false,                // has_make_symbol
756  false,                // has_resolve
757  false,                // has_code_fill
758  true,                 // is_default_stack_executable
759  false,                // can_icf_inline_merge_sections
760  '\0',                 // wrap_char
761  "/lib32/ld.so.1",     // program interpreter
762  0x10000,              // default_text_segment_address
763  0x10000,              // abi_pagesize (overridable by -z max-page-size)
764  0x10000,              // common_pagesize (overridable by -z common-page-size)
765  false,                // isolate_execinstr
766  0,                    // rosegment_gap
767  elfcpp::SHN_UNDEF,    // small_common_shndx
768  elfcpp::SHN_UNDEF,    // large_common_shndx
769  0,                    // small_common_section_flags
770  0,                    // large_common_section_flags
771  NULL,                 // attributes_section
772  NULL,                  // attributes_vendor
773  "_start",		// entry_symbol_name
774  32,			// hash_entry_size
775};
776
777// tilegx relocation handlers
778template<int size, bool big_endian>
779class Tilegx_relocate_functions
780{
781public:
782  // overflow check will be supported later
783  typedef enum
784  {
785    STATUS_OKAY,        // No error during relocation.
786    STATUS_OVERFLOW,    // Relocation overflow.
787    STATUS_BAD_RELOC    // Relocation cannot be applied.
788  } Status;
789
790  struct Tilegx_howto
791  {
792    // right shift operand by this number of bits.
793    unsigned char srshift;
794
795    // the offset to apply relocation.
796    unsigned char doffset;
797
798    // set to 1 for pc-relative relocation.
799    unsigned char is_pcrel;
800
801    // size in bits, or 0 if this table entry should be ignored.
802    unsigned char bsize;
803
804    // whether we need to check overflow.
805    unsigned char overflow;
806  };
807
808  static const Tilegx_howto howto[elfcpp::R_TILEGX_NUM];
809
810private:
811
812  // Do a simple rela relocation
813  template<int valsize>
814  static inline void
815  rela(unsigned char* view,
816       const Sized_relobj_file<size, big_endian>* object,
817       const Symbol_value<size>* psymval,
818       typename elfcpp::Swap<size, big_endian>::Valtype addend,
819       elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset,
820       elfcpp::Elf_Xword bitmask)
821  {
822    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
823    Valtype* wv = reinterpret_cast<Valtype*>(view);
824    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
825    Valtype reloc = 0;
826    if (size == 32)
827      reloc = Bits<32>::sign_extend(psymval->value(object, addend)) >> srshift;
828    else
829      reloc = psymval->value(object, addend) >> srshift;
830
831    elfcpp::Elf_Xword dst_mask = bitmask << doffset;
832
833    val &= ~dst_mask;
834    reloc &= bitmask;
835
836    elfcpp::Swap<valsize, big_endian>::writeval(wv, val | (reloc<<doffset));
837  }
838
839  // Do a simple rela relocation
840  template<int valsize>
841  static inline void
842  rela_ua(unsigned char* view,
843          const Sized_relobj_file<size, big_endian>* object,
844          const Symbol_value<size>* psymval,
845          typename elfcpp::Swap<size, big_endian>::Valtype addend,
846          elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset,
847          elfcpp::Elf_Xword bitmask)
848  {
849    typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
850      Valtype;
851    unsigned char* wv = view;
852    Valtype val = elfcpp::Swap_unaligned<valsize, big_endian>::readval(wv);
853    Valtype reloc = 0;
854    if (size == 32)
855      reloc = Bits<32>::sign_extend(psymval->value(object, addend)) >> srshift;
856    else
857      reloc = psymval->value(object, addend) >> srshift;
858
859    elfcpp::Elf_Xword dst_mask = bitmask << doffset;
860
861    val &= ~dst_mask;
862    reloc &= bitmask;
863
864    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(wv,
865      val | (reloc<<doffset));
866  }
867
868  template<int valsize>
869  static inline void
870  rela(unsigned char* view,
871       const Sized_relobj_file<size, big_endian>* object,
872       const Symbol_value<size>* psymval,
873       typename elfcpp::Swap<size, big_endian>::Valtype addend,
874       elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset1,
875       elfcpp::Elf_Xword bitmask1, elfcpp::Elf_Xword doffset2,
876       elfcpp::Elf_Xword bitmask2)
877  {
878    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
879    Valtype* wv = reinterpret_cast<Valtype*>(view);
880    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
881    Valtype reloc = 0;
882    if (size == 32)
883      reloc = Bits<32>::sign_extend(psymval->value(object, addend)) >> srshift;
884    else
885      reloc = psymval->value(object, addend) >> srshift;
886
887    elfcpp::Elf_Xword dst_mask = (bitmask1 << doffset1)
888                                  | (bitmask2 << doffset2);
889    val &= ~dst_mask;
890    reloc = ((reloc & bitmask1) << doffset1)
891             | ((reloc & bitmask2) << doffset2);
892
893    elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
894
895  }
896
897  // Do a simple PC relative relocation with a Symbol_value with the
898  // addend in the relocation.
899  template<int valsize>
900  static inline void
901  pcrela(unsigned char* view,
902         const Sized_relobj_file<size, big_endian>* object,
903         const Symbol_value<size>* psymval,
904         typename elfcpp::Swap<size, big_endian>::Valtype addend,
905         typename elfcpp::Elf_types<size>::Elf_Addr address,
906         elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset,
907         elfcpp::Elf_Xword bitmask)
908
909  {
910    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
911    Valtype* wv = reinterpret_cast<Valtype*>(view);
912    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
913    Valtype reloc = 0;
914    if (size == 32)
915      reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
916               >> srshift;
917    else
918      reloc = (psymval->value(object, addend) - address) >> srshift;
919
920    elfcpp::Elf_Xword dst_mask = bitmask << doffset;
921    val &= ~dst_mask;
922    reloc &= bitmask;
923
924    elfcpp::Swap<valsize, big_endian>::writeval(wv, val | (reloc<<doffset));
925  }
926
927  template<int valsize>
928  static inline void
929  pcrela_ua(unsigned char* view,
930           const Sized_relobj_file<size, big_endian>* object,
931           const Symbol_value<size>* psymval,
932           typename elfcpp::Swap<size, big_endian>::Valtype addend,
933           typename elfcpp::Elf_types<size>::Elf_Addr address,
934           elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset,
935           elfcpp::Elf_Xword bitmask)
936
937  {
938    typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
939      Valtype;
940    unsigned char* wv = view;
941    Valtype reloc = 0;
942    if (size == 32)
943      reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
944               >> srshift;
945    else
946      reloc = (psymval->value(object, addend) - address) >> srshift;
947
948    reloc &= bitmask;
949
950    elfcpp::Swap<valsize, big_endian>::writeval(wv, reloc << doffset);
951  }
952
953  template<int valsize>
954  static inline void
955  pcrela(unsigned char* view,
956         const Sized_relobj_file<size, big_endian>* object,
957         const Symbol_value<size>* psymval,
958         typename elfcpp::Swap<size, big_endian>::Valtype addend,
959         typename elfcpp::Elf_types<size>::Elf_Addr address,
960         elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset1,
961         elfcpp::Elf_Xword bitmask1, elfcpp::Elf_Xword doffset2,
962         elfcpp::Elf_Xword bitmask2)
963
964  {
965    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
966    Valtype* wv = reinterpret_cast<Valtype*>(view);
967    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
968    Valtype reloc = 0;
969    if (size == 32)
970      reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
971               >> srshift;
972    else
973      reloc = (psymval->value(object, addend) - address) >> srshift;
974
975    elfcpp::Elf_Xword dst_mask = (bitmask1 << doffset1)
976                                  | (bitmask2 << doffset2);
977    val &= ~dst_mask;
978    reloc = ((reloc & bitmask1) << doffset1)
979             | ((reloc & bitmask2) << doffset2);
980
981    elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
982  }
983
984  typedef Tilegx_relocate_functions<size, big_endian> This;
985  typedef Relocate_functions<size, big_endian> Base;
986
987public:
988
989  static inline void
990  abs64(unsigned char* view,
991        const Sized_relobj_file<size, big_endian>* object,
992        const Symbol_value<size>* psymval,
993        typename elfcpp::Elf_types<size>::Elf_Addr addend)
994  {
995    This::template rela_ua<64>(view, object, psymval, addend, 0, 0,
996                               0xffffffffffffffffllu);
997  }
998
999  static inline void
1000  abs32(unsigned char* view,
1001        const Sized_relobj_file<size, big_endian>* object,
1002        const Symbol_value<size>* psymval,
1003        typename elfcpp::Elf_types<size>::Elf_Addr addend)
1004  {
1005    This::template rela_ua<32>(view, object, psymval, addend, 0, 0,
1006                               0xffffffff);
1007  }
1008
1009  static inline void
1010  abs16(unsigned char* view,
1011        const Sized_relobj_file<size, big_endian>* object,
1012        const Symbol_value<size>* psymval,
1013        typename elfcpp::Elf_types<size>::Elf_Addr addend)
1014  {
1015    This::template rela_ua<16>(view, object, psymval, addend, 0, 0,
1016                               0xffff);
1017  }
1018
1019  static inline void
1020  pc_abs64(unsigned char* view,
1021        const Sized_relobj_file<size, big_endian>* object,
1022        const Symbol_value<size>* psymval,
1023        typename elfcpp::Elf_types<size>::Elf_Addr addend,
1024	    typename elfcpp::Elf_types<size>::Elf_Addr address)
1025  {
1026    This::template pcrela_ua<64>(view, object, psymval, addend, address, 0, 0,
1027                               0xffffffffffffffffllu);
1028  }
1029
1030  static inline void
1031  pc_abs32(unsigned char* view,
1032        const Sized_relobj_file<size, big_endian>* object,
1033        const Symbol_value<size>* psymval,
1034        typename elfcpp::Elf_types<size>::Elf_Addr addend,
1035	    typename elfcpp::Elf_types<size>::Elf_Addr address)
1036  {
1037    This::template pcrela_ua<32>(view, object, psymval, addend, address, 0, 0,
1038                                 0xffffffff);
1039  }
1040
1041  static inline void
1042  pc_abs16(unsigned char* view,
1043        const Sized_relobj_file<size, big_endian>* object,
1044        const Symbol_value<size>* psymval,
1045        typename elfcpp::Elf_types<size>::Elf_Addr addend,
1046	    typename elfcpp::Elf_types<size>::Elf_Addr address)
1047  {
1048    This::template pcrela_ua<16>(view, object, psymval, addend, address, 0, 0,
1049                                 0xffff);
1050  }
1051
1052  static inline void
1053  imm_x_general(unsigned char* view,
1054                const Sized_relobj_file<size, big_endian>* object,
1055                const Symbol_value<size>* psymval,
1056                typename elfcpp::Elf_types<size>::Elf_Addr addend,
1057                Tilegx_howto &r_howto)
1058  {
1059    This::template rela<64>(view, object, psymval, addend,
1060                            (elfcpp::Elf_Xword)(r_howto.srshift),
1061                            (elfcpp::Elf_Xword)(r_howto.doffset),
1062                            (elfcpp::Elf_Xword)((1 << r_howto.bsize) - 1));
1063  }
1064
1065  static inline void
1066  imm_x_pcrel_general(unsigned char* view,
1067                      const Sized_relobj_file<size, big_endian>* object,
1068                      const Symbol_value<size>* psymval,
1069                      typename elfcpp::Elf_types<size>::Elf_Addr addend,
1070                      typename elfcpp::Elf_types<size>::Elf_Addr address,
1071                      Tilegx_howto &r_howto)
1072  {
1073    This::template pcrela<64>(view, object, psymval, addend, address,
1074                              (elfcpp::Elf_Xword)(r_howto.srshift),
1075                              (elfcpp::Elf_Xword)(r_howto.doffset),
1076                              (elfcpp::Elf_Xword)((1 << r_howto.bsize) - 1));
1077  }
1078
1079  static inline void
1080  imm_x_two_part_general(unsigned char* view,
1081                         const Sized_relobj_file<size, big_endian>* object,
1082                         const Symbol_value<size>* psymval,
1083                         typename elfcpp::Elf_types<size>::Elf_Addr addend,
1084                         typename elfcpp::Elf_types<size>::Elf_Addr address,
1085                         unsigned int r_type)
1086  {
1087
1088    elfcpp::Elf_Xword doffset1 = 0llu;
1089    elfcpp::Elf_Xword doffset2 = 0llu;
1090    elfcpp::Elf_Xword dmask1   = 0llu;
1091    elfcpp::Elf_Xword dmask2   = 0llu;
1092    elfcpp::Elf_Xword rshift   = 0llu;
1093    unsigned int pc_rel        = 0;
1094
1095    switch (r_type)
1096      {
1097      case elfcpp::R_TILEGX_BROFF_X1:
1098        doffset1 = 31llu;
1099        doffset2 = 37llu;
1100        dmask1   = 0x3fllu;
1101        dmask2   = 0x1ffc0llu;
1102        rshift   = 3llu;
1103        pc_rel   = 1;
1104        break;
1105      case elfcpp::R_TILEGX_DEST_IMM8_X1:
1106        doffset1 = 31llu;
1107        doffset2 = 43llu;
1108        dmask1   = 0x3fllu;
1109        dmask2   = 0xc0llu;
1110        rshift   = 0llu;
1111        break;
1112      }
1113
1114    if (pc_rel)
1115      This::template pcrela<64>(view, object, psymval, addend, address,
1116                                rshift, doffset1, dmask1, doffset2, dmask2);
1117    else
1118      This::template rela<64>(view, object, psymval, addend, rshift,
1119                              doffset1, dmask1, doffset2, dmask2);
1120
1121  }
1122
1123  static inline void
1124  tls_relax(unsigned char* view, unsigned int r_type,
1125            tls::Tls_optimization opt_t)
1126  {
1127
1128    const uint64_t TILEGX_X_MOVE_R0_R0 = 0x283bf8005107f000llu;
1129    const uint64_t TILEGX_Y_MOVE_R0_R0 = 0xae05f800540bf000llu;
1130    const uint64_t TILEGX_X_LD         = 0x286ae80000000000llu;
1131    const uint64_t TILEGX_X_LD4S       = 0x286a980000000000llu;
1132    const uint64_t TILEGX_X1_FULL_MASK = 0x3fffffff80000000llu;
1133    const uint64_t TILEGX_X0_RRR_MASK  = 0x000000007ffc0000llu;
1134    const uint64_t TILEGX_X1_RRR_MASK  = 0x3ffe000000000000llu;
1135    const uint64_t TILEGX_Y0_RRR_MASK  = 0x00000000780c0000llu;
1136    const uint64_t TILEGX_Y1_RRR_MASK  = 0x3c06000000000000llu;
1137    const uint64_t TILEGX_X0_RRR_SRCB_MASK = 0x000000007ffff000llu;
1138    const uint64_t TILEGX_X1_RRR_SRCB_MASK = 0x3ffff80000000000llu;
1139    const uint64_t TILEGX_Y0_RRR_SRCB_MASK = 0x00000000780ff000llu;
1140    const uint64_t TILEGX_Y1_RRR_SRCB_MASK = 0x3c07f80000000000llu;
1141    const uint64_t TILEGX_X_ADD_R0_R0_TP   = 0x2807a800500f5000llu;
1142    const uint64_t TILEGX_Y_ADD_R0_R0_TP   = 0x9a13a8002c275000llu;
1143    const uint64_t TILEGX_X_ADDX_R0_R0_TP  = 0x2805a800500b5000llu;
1144    const uint64_t TILEGX_Y_ADDX_R0_R0_TP  = 0x9a01a8002c035000llu;
1145
1146    const uint64_t R_TILEGX_IMM8_X0_TLS_ADD_MASK =
1147      (TILEGX_X0_RRR_MASK | (0x3Fllu << 12));
1148
1149    const uint64_t R_TILEGX_IMM8_X1_TLS_ADD_MASK =
1150      (TILEGX_X1_RRR_MASK | (0x3Fllu << 43));
1151
1152    const uint64_t R_TILEGX_IMM8_Y0_TLS_ADD_MASK =
1153      (TILEGX_Y0_RRR_MASK | (0x3Fllu << 12));
1154
1155    const uint64_t R_TILEGX_IMM8_Y1_TLS_ADD_MASK =
1156      (TILEGX_Y1_RRR_MASK | (0x3Fllu << 43));
1157
1158    const uint64_t R_TILEGX_IMM8_X0_TLS_ADD_LE_MASK =
1159      (TILEGX_X0_RRR_SRCB_MASK | (0x3Fllu << 6));
1160
1161    const uint64_t R_TILEGX_IMM8_X1_TLS_ADD_LE_MASK =
1162      (TILEGX_X1_RRR_SRCB_MASK | (0x3Fllu << 37));
1163
1164    const uint64_t R_TILEGX_IMM8_Y0_TLS_ADD_LE_MASK =
1165      (TILEGX_Y0_RRR_SRCB_MASK | (0x3Fllu << 6));
1166
1167    const uint64_t R_TILEGX_IMM8_Y1_TLS_ADD_LE_MASK =
1168      (TILEGX_Y1_RRR_SRCB_MASK | (0x3Fllu << 37));
1169
1170    typedef typename elfcpp::Swap<64, big_endian>::Valtype Valtype;
1171    Valtype* wv = reinterpret_cast<Valtype*>(view);
1172    Valtype val = elfcpp::Swap<64, big_endian>::readval(wv);
1173    Valtype reloc = 0;
1174
1175    switch (r_type)
1176    {
1177      case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
1178        if (opt_t == tls::TLSOPT_NONE) {
1179          // GD/IE: 1. copy dest operand into the second source operand
1180          //        2. change the opcode to "add"
1181          reloc = (val & 0x3Fllu) << 12;  // featch the dest reg
1182          reloc |= ((size == 32
1183                     ? TILEGX_X_ADDX_R0_R0_TP
1184                     : TILEGX_X_ADD_R0_R0_TP)
1185                    & TILEGX_X0_RRR_MASK);  // change opcode
1186          val &= ~R_TILEGX_IMM8_X0_TLS_ADD_MASK;
1187        } else if (opt_t == tls::TLSOPT_TO_LE) {
1188          // LE: 1. copy dest operand into the first source operand
1189          //     2. change the opcode to "move"
1190          reloc = (val & 0x3Fllu) << 6;
1191          reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK);
1192          val &= ~R_TILEGX_IMM8_X0_TLS_ADD_LE_MASK;
1193        } else
1194          gold_unreachable();
1195        break;
1196      case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
1197        if (opt_t == tls::TLSOPT_NONE) {
1198          reloc = (val & (0x3Fllu << 31)) << 12;
1199          reloc |= ((size == 32
1200                     ? TILEGX_X_ADDX_R0_R0_TP
1201                     : TILEGX_X_ADD_R0_R0_TP)
1202                    & TILEGX_X1_RRR_MASK);
1203          val &= ~R_TILEGX_IMM8_X1_TLS_ADD_MASK;
1204        } else if (opt_t == tls::TLSOPT_TO_LE) {
1205          reloc = (val & (0x3Fllu << 31)) << 6;
1206          reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X1_RRR_SRCB_MASK);
1207          val &= ~R_TILEGX_IMM8_X1_TLS_ADD_LE_MASK;
1208        } else
1209          gold_unreachable();
1210        break;
1211      case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
1212        if (opt_t == tls::TLSOPT_NONE) {
1213          reloc = (val & 0x3Fllu) << 12;
1214          reloc |= ((size == 32
1215                     ? TILEGX_Y_ADDX_R0_R0_TP
1216                     : TILEGX_Y_ADD_R0_R0_TP)
1217                    & TILEGX_Y0_RRR_MASK);
1218          val &= ~R_TILEGX_IMM8_Y0_TLS_ADD_MASK;
1219        } else if (opt_t == tls::TLSOPT_TO_LE) {
1220          reloc = (val & 0x3Fllu) << 6;
1221          reloc |= (TILEGX_Y_MOVE_R0_R0 & TILEGX_Y0_RRR_SRCB_MASK);
1222          val &= ~R_TILEGX_IMM8_Y0_TLS_ADD_LE_MASK;
1223        } else
1224          gold_unreachable();
1225        break;
1226      case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
1227        if (opt_t == tls::TLSOPT_NONE) {
1228          reloc = (val & (0x3Fllu << 31)) << 12;
1229          reloc |= ((size == 32
1230                     ? TILEGX_Y_ADDX_R0_R0_TP
1231                     : TILEGX_Y_ADD_R0_R0_TP)
1232                    & TILEGX_Y1_RRR_MASK);
1233          val &= ~R_TILEGX_IMM8_Y1_TLS_ADD_MASK;
1234        } else if (opt_t == tls::TLSOPT_TO_LE) {
1235          reloc = (val & (0x3Fllu << 31)) << 6;
1236          reloc |= (TILEGX_Y_MOVE_R0_R0 & TILEGX_Y1_RRR_SRCB_MASK);
1237          val &= ~R_TILEGX_IMM8_Y1_TLS_ADD_LE_MASK;
1238        } else
1239          gold_unreachable();
1240        break;
1241      case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
1242        if (opt_t == tls::TLSOPT_NONE) {
1243          // GD see comments for optimize_tls_reloc
1244          reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK;
1245          val &= ~TILEGX_X0_RRR_SRCB_MASK;
1246        } else if (opt_t == tls::TLSOPT_TO_IE
1247                   || opt_t == tls::TLSOPT_TO_LE) {
1248          // IE/LE
1249          reloc = (size == 32
1250                   ? TILEGX_X_ADDX_R0_R0_TP
1251                   : TILEGX_X_ADD_R0_R0_TP)
1252                   & TILEGX_X0_RRR_SRCB_MASK;
1253          val &= ~TILEGX_X0_RRR_SRCB_MASK;
1254        }
1255        break;
1256      case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
1257        if (opt_t == tls::TLSOPT_NONE) {
1258          reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X1_RRR_SRCB_MASK;
1259          val &= ~TILEGX_X1_RRR_SRCB_MASK;
1260        } else if (opt_t == tls::TLSOPT_TO_IE
1261                   || opt_t == tls::TLSOPT_TO_LE) {
1262          reloc = (size == 32
1263                   ? TILEGX_X_ADDX_R0_R0_TP
1264                   : TILEGX_X_ADD_R0_R0_TP)
1265                   & TILEGX_X1_RRR_SRCB_MASK;
1266          val &= ~TILEGX_X1_RRR_SRCB_MASK;
1267        }
1268        break;
1269      case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
1270        if (opt_t == tls::TLSOPT_NONE) {
1271          reloc = TILEGX_Y_MOVE_R0_R0 & TILEGX_Y0_RRR_SRCB_MASK;
1272          val &= ~TILEGX_Y0_RRR_SRCB_MASK;
1273        } else if (opt_t == tls::TLSOPT_TO_IE
1274                   || opt_t == tls::TLSOPT_TO_LE) {
1275          reloc = (size == 32
1276                   ? TILEGX_Y_ADDX_R0_R0_TP
1277                   : TILEGX_Y_ADD_R0_R0_TP)
1278                   & TILEGX_Y0_RRR_SRCB_MASK;
1279          val &= ~TILEGX_Y0_RRR_SRCB_MASK;
1280        }
1281        break;
1282      case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
1283        if (opt_t == tls::TLSOPT_NONE) {
1284          reloc = TILEGX_Y_MOVE_R0_R0 & TILEGX_Y1_RRR_SRCB_MASK;
1285          val &= ~TILEGX_Y1_RRR_SRCB_MASK;
1286        } else if (opt_t == tls::TLSOPT_TO_IE
1287                   || opt_t == tls::TLSOPT_TO_LE) {
1288          reloc = (size == 32
1289                   ? TILEGX_Y_ADDX_R0_R0_TP
1290                   : TILEGX_Y_ADD_R0_R0_TP)
1291                   & TILEGX_Y1_RRR_SRCB_MASK;
1292          val &= ~TILEGX_Y1_RRR_SRCB_MASK;
1293        }
1294        break;
1295      case elfcpp::R_TILEGX_TLS_IE_LOAD:
1296        if (opt_t == tls::TLSOPT_NONE) {
1297          // IE
1298          reloc = (size == 32
1299                   ? TILEGX_X_LD4S
1300                   : TILEGX_X_LD)
1301                   & TILEGX_X1_RRR_SRCB_MASK;
1302          val &= ~TILEGX_X1_RRR_SRCB_MASK;
1303        } else if (opt_t == tls::TLSOPT_TO_LE) {
1304          // LE
1305          reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X1_RRR_SRCB_MASK;
1306          val &= ~TILEGX_X1_RRR_SRCB_MASK;
1307        } else
1308          gold_unreachable();
1309        break;
1310      case elfcpp::R_TILEGX_TLS_GD_CALL:
1311        if (opt_t == tls::TLSOPT_TO_IE) {
1312          // ld/ld4s r0, r0
1313          reloc = (size == 32
1314                  ? TILEGX_X_LD4S
1315                  : TILEGX_X_LD) & TILEGX_X1_FULL_MASK;
1316          val &= ~TILEGX_X1_FULL_MASK;
1317        } else if (opt_t == tls::TLSOPT_TO_LE) {
1318          // move r0, r0
1319          reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X1_FULL_MASK;
1320          val &= ~TILEGX_X1_FULL_MASK;
1321        } else
1322          // should be handled in ::relocate
1323          gold_unreachable();
1324        break;
1325      default:
1326        gold_unreachable();
1327        break;
1328    }
1329    elfcpp::Swap<64, big_endian>::writeval(wv, val | reloc);
1330  }
1331};
1332
1333template<>
1334const Tilegx_relocate_functions<64, false>::Tilegx_howto
1335Tilegx_relocate_functions<64, false>::howto[elfcpp::R_TILEGX_NUM] =
1336{
1337  {  0,  0, 0,  0, 0}, // R_TILEGX_NONE
1338  {  0,  0, 0, 64, 0}, // R_TILEGX_64
1339  {  0,  0, 0, 32, 0}, // R_TILEGX_32
1340  {  0,  0, 0, 16, 0}, // R_TILEGX_16
1341  {  0,  0, 0,  8, 0}, // R_TILEGX_8
1342  {  0,  0, 1, 64, 0}, // R_TILEGX_64_PCREL
1343  {  0,  0, 1, 32, 0}, // R_TILEGX_32_PCREL
1344  {  0,  0, 1, 16, 0}, // R_TILEGX_16_PCREL
1345  {  0,  0, 1,  8, 0}, // R_TILEGX_8_PCREL
1346  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0
1347  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1
1348  { 32,  0, 0,  0, 0}, // R_TILEGX_HW2
1349  { 48,  0, 0,  0, 0}, // R_TILEGX_HW3
1350  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0_LAST
1351  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1_LAST
1352  { 32,  0, 0,  0, 0}, // R_TILEGX_HW2_LAST
1353  {  0,  0, 0,  0, 0}, // R_TILEGX_COPY
1354  {  0,  0, 0,  8, 0}, // R_TILEGX_GLOB_DAT
1355  {  0,  0, 0,  0, 0}, // R_TILEGX_JMP_SLOT
1356  {  0,  0, 0,  0, 0}, // R_TILEGX_RELATIVE
1357  {  3,  1, 1,  0, 0}, // R_TILEGX_BROFF_X1
1358  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1
1359  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT
1360  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X0
1361  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y0
1362  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X1
1363  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y1
1364  {  0,  1, 0,  8, 0}, // R_TILEGX_DEST_IMM8_X1
1365  {  0,  1, 0,  8, 0}, // R_TILEGX_MT_IMM14_X1
1366  {  0,  1, 0,  8, 0}, // R_TILEGX_MF_IMM14_X1
1367  {  0,  1, 0,  8, 0}, // R_TILEGX_MMSTART_X0
1368  {  0,  1, 0,  8, 0}, // R_TILEGX_MMEND_X0
1369  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X0
1370  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X1
1371  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y0
1372  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y1
1373  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0
1374  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0
1375  { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1
1376  { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1
1377  { 32, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2
1378  { 32, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2
1379  { 48, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3
1380  { 48, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3
1381  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST
1382  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST
1383  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST
1384  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST
1385  { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST
1386  { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST
1387  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL
1388  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL
1389  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL
1390  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL
1391  { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL
1392  { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL
1393  { 48, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL
1394  { 48, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL
1395  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL
1396  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL
1397  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL
1398  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL
1399  { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL
1400  { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL
1401  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT
1402  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT
1403  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL
1404  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL
1405  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL
1406  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL
1407  { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL
1408  { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL
1409  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT
1410  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT
1411  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT
1412  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT
1413  { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT
1414  { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT
1415  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD
1416  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD
1417  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE
1418  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE
1419  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
1420  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
1421  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
1422  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE
1423  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD
1424  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD
1425  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD
1426  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD
1427  {  0,  0, 0,  0, 0}, // R_TILEGX_IRELATIVE
1428  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1429  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE
1430  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE
1431  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL
1432  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL
1433  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL
1434  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL
1435  { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL
1436  { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL
1437  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE
1438  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE
1439  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE
1440  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE
1441  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1442  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1443  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD64
1444  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF64
1445  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF64
1446  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD32
1447  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF32
1448  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF32
1449  {  3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL
1450  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD
1451  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD
1452  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD
1453  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD
1454  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_IE_LOAD
1455  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD
1456  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD
1457  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD
1458  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD
1459  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTINHERIT
1460  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTENTRY
1461};
1462
1463template<>
1464const Tilegx_relocate_functions<32, false>::Tilegx_howto
1465Tilegx_relocate_functions<32, false>::howto[elfcpp::R_TILEGX_NUM] =
1466{
1467  {  0,  0, 0,  0, 0}, // R_TILEGX_NONE
1468  {  0,  0, 0, 64, 0}, // R_TILEGX_64
1469  {  0,  0, 0, 32, 0}, // R_TILEGX_32
1470  {  0,  0, 0, 16, 0}, // R_TILEGX_16
1471  {  0,  0, 0,  8, 0}, // R_TILEGX_8
1472  {  0,  0, 1, 64, 0}, // R_TILEGX_64_PCREL
1473  {  0,  0, 1, 32, 0}, // R_TILEGX_32_PCREL
1474  {  0,  0, 1, 16, 0}, // R_TILEGX_16_PCREL
1475  {  0,  0, 1,  8, 0}, // R_TILEGX_8_PCREL
1476  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0
1477  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1
1478  { 31,  0, 0,  0, 0}, // R_TILEGX_HW2
1479  { 31,  0, 0,  0, 0}, // R_TILEGX_HW3
1480  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0_LAST
1481  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1_LAST
1482  { 31,  0, 0,  0, 0}, // R_TILEGX_HW2_LAST
1483  {  0,  0, 0,  0, 0}, // R_TILEGX_COPY
1484  {  0,  0, 0,  8, 0}, // R_TILEGX_GLOB_DAT
1485  {  0,  0, 0,  0, 0}, // R_TILEGX_JMP_SLOT
1486  {  0,  0, 0,  0, 0}, // R_TILEGX_RELATIVE
1487  {  3,  1, 1,  0, 0}, // R_TILEGX_BROFF_X1
1488  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1
1489  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT
1490  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X0
1491  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y0
1492  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X1
1493  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y1
1494  {  0,  1, 0,  8, 0}, // R_TILEGX_DEST_IMM8_X1
1495  {  0,  1, 0,  8, 0}, // R_TILEGX_MT_IMM14_X1
1496  {  0,  1, 0,  8, 0}, // R_TILEGX_MF_IMM14_X1
1497  {  0,  1, 0,  8, 0}, // R_TILEGX_MMSTART_X0
1498  {  0,  1, 0,  8, 0}, // R_TILEGX_MMEND_X0
1499  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X0
1500  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X1
1501  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y0
1502  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y1
1503  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0
1504  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0
1505  { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1
1506  { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1
1507  { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2
1508  { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2
1509  { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3
1510  { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3
1511  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST
1512  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST
1513  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST
1514  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST
1515  { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST
1516  { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST
1517  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL
1518  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL
1519  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL
1520  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL
1521  { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL
1522  { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL
1523  { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL
1524  { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL
1525  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL
1526  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL
1527  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL
1528  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL
1529  { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL
1530  { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL
1531  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT
1532  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT
1533  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL
1534  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL
1535  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL
1536  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL
1537  { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL
1538  { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL
1539  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT
1540  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT
1541  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT
1542  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT
1543  { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT
1544  { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT
1545  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD
1546  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD
1547  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE
1548  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE
1549  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
1550  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
1551  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
1552  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE
1553  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD
1554  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD
1555  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD
1556  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD
1557  {  0,  0, 0,  0, 0}, // R_TILEGX_IRELATIVE
1558  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1559  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE
1560  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE
1561  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL
1562  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL
1563  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL
1564  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL
1565  { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL
1566  { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL
1567  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE
1568  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE
1569  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE
1570  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE
1571  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1572  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1573  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD64
1574  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF64
1575  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF64
1576  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD32
1577  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF32
1578  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF32
1579  {  3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL
1580  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD
1581  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD
1582  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD
1583  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD
1584  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_IE_LOAD
1585  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD
1586  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD
1587  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD
1588  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD
1589  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTINHERIT
1590  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTENTRY
1591};
1592
1593template<>
1594const Tilegx_relocate_functions<64, true>::Tilegx_howto
1595Tilegx_relocate_functions<64, true>::howto[elfcpp::R_TILEGX_NUM] =
1596{
1597  {  0,  0, 0,  0, 0}, // R_TILEGX_NONE
1598  {  0,  0, 0, 64, 0}, // R_TILEGX_64
1599  {  0,  0, 0, 32, 0}, // R_TILEGX_32
1600  {  0,  0, 0, 16, 0}, // R_TILEGX_16
1601  {  0,  0, 0,  8, 0}, // R_TILEGX_8
1602  {  0,  0, 1, 64, 0}, // R_TILEGX_64_PCREL
1603  {  0,  0, 1, 32, 0}, // R_TILEGX_32_PCREL
1604  {  0,  0, 1, 16, 0}, // R_TILEGX_16_PCREL
1605  {  0,  0, 1,  8, 0}, // R_TILEGX_8_PCREL
1606  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0
1607  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1
1608  { 32,  0, 0,  0, 0}, // R_TILEGX_HW2
1609  { 48,  0, 0,  0, 0}, // R_TILEGX_HW3
1610  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0_LAST
1611  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1_LAST
1612  { 32,  0, 0,  0, 0}, // R_TILEGX_HW2_LAST
1613  {  0,  0, 0,  0, 0}, // R_TILEGX_COPY
1614  {  0,  0, 0,  8, 0}, // R_TILEGX_GLOB_DAT
1615  {  0,  0, 0,  0, 0}, // R_TILEGX_JMP_SLOT
1616  {  0,  0, 0,  0, 0}, // R_TILEGX_RELATIVE
1617  {  3,  1, 1,  0, 0}, // R_TILEGX_BROFF_X1
1618  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1
1619  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT
1620  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X0
1621  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y0
1622  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X1
1623  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y1
1624  {  0,  1, 0,  8, 0}, // R_TILEGX_DEST_IMM8_X1
1625  {  0,  1, 0,  8, 0}, // R_TILEGX_MT_IMM14_X1
1626  {  0,  1, 0,  8, 0}, // R_TILEGX_MF_IMM14_X1
1627  {  0,  1, 0,  8, 0}, // R_TILEGX_MMSTART_X0
1628  {  0,  1, 0,  8, 0}, // R_TILEGX_MMEND_X0
1629  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X0
1630  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X1
1631  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y0
1632  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y1
1633  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0
1634  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0
1635  { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1
1636  { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1
1637  { 32, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2
1638  { 32, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2
1639  { 48, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3
1640  { 48, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3
1641  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST
1642  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST
1643  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST
1644  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST
1645  { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST
1646  { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST
1647  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL
1648  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL
1649  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL
1650  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL
1651  { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL
1652  { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL
1653  { 48, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL
1654  { 48, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL
1655  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL
1656  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL
1657  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL
1658  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL
1659  { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL
1660  { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL
1661  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT
1662  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT
1663  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL
1664  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL
1665  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL
1666  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL
1667  { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL
1668  { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL
1669  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT
1670  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT
1671  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT
1672  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT
1673  { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT
1674  { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT
1675  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD
1676  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD
1677  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE
1678  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE
1679  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
1680  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
1681  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
1682  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE
1683  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD
1684  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD
1685  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD
1686  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD
1687  {  0,  0, 0,  0, 0}, // R_TILEGX_IRELATIVE
1688  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1689  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE
1690  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE
1691  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL
1692  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL
1693  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL
1694  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL
1695  { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL
1696  { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL
1697  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE
1698  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE
1699  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE
1700  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE
1701  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1702  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1703  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD64
1704  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF64
1705  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF64
1706  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD32
1707  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF32
1708  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF32
1709  {  3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL
1710  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD
1711  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD
1712  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD
1713  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD
1714  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_IE_LOAD
1715  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD
1716  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD
1717  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD
1718  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD
1719  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTINHERIT
1720  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTENTRY
1721};
1722
1723template<>
1724const Tilegx_relocate_functions<32, true>::Tilegx_howto
1725Tilegx_relocate_functions<32, true>::howto[elfcpp::R_TILEGX_NUM] =
1726{
1727  {  0,  0, 0,  0, 0}, // R_TILEGX_NONE
1728  {  0,  0, 0, 64, 0}, // R_TILEGX_64
1729  {  0,  0, 0, 32, 0}, // R_TILEGX_32
1730  {  0,  0, 0, 16, 0}, // R_TILEGX_16
1731  {  0,  0, 0,  8, 0}, // R_TILEGX_8
1732  {  0,  0, 1, 64, 0}, // R_TILEGX_64_PCREL
1733  {  0,  0, 1, 32, 0}, // R_TILEGX_32_PCREL
1734  {  0,  0, 1, 16, 0}, // R_TILEGX_16_PCREL
1735  {  0,  0, 1,  8, 0}, // R_TILEGX_8_PCREL
1736  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0
1737  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1
1738  { 31,  0, 0,  0, 0}, // R_TILEGX_HW2
1739  { 31,  0, 0,  0, 0}, // R_TILEGX_HW3
1740  {  0,  0, 0,  0, 0}, // R_TILEGX_HW0_LAST
1741  { 16,  0, 0,  0, 0}, // R_TILEGX_HW1_LAST
1742  { 31,  0, 0,  0, 0}, // R_TILEGX_HW2_LAST
1743  {  0,  0, 0,  0, 0}, // R_TILEGX_COPY
1744  {  0,  0, 0,  8, 0}, // R_TILEGX_GLOB_DAT
1745  {  0,  0, 0,  0, 0}, // R_TILEGX_JMP_SLOT
1746  {  0,  0, 0,  0, 0}, // R_TILEGX_RELATIVE
1747  {  3,  1, 1,  0, 0}, // R_TILEGX_BROFF_X1
1748  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1
1749  {  3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT
1750  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X0
1751  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y0
1752  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_X1
1753  {  0,  1, 0,  8, 0}, // R_TILEGX_IMM8_Y1
1754  {  0,  1, 0,  8, 0}, // R_TILEGX_DEST_IMM8_X1
1755  {  0,  1, 0,  8, 0}, // R_TILEGX_MT_IMM14_X1
1756  {  0,  1, 0,  8, 0}, // R_TILEGX_MF_IMM14_X1
1757  {  0,  1, 0,  8, 0}, // R_TILEGX_MMSTART_X0
1758  {  0,  1, 0,  8, 0}, // R_TILEGX_MMEND_X0
1759  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X0
1760  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_X1
1761  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y0
1762  {  0,  1, 0,  8, 0}, // R_TILEGX_SHAMT_Y1
1763  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0
1764  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0
1765  { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1
1766  { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1
1767  { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2
1768  { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2
1769  { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3
1770  { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3
1771  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST
1772  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST
1773  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST
1774  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST
1775  { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST
1776  { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST
1777  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL
1778  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL
1779  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL
1780  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL
1781  { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL
1782  { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL
1783  { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL
1784  { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL
1785  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL
1786  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL
1787  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL
1788  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL
1789  { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL
1790  { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL
1791  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT
1792  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT
1793  {  0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL
1794  {  0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL
1795  { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL
1796  { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL
1797  { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL
1798  { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL
1799  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT
1800  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT
1801  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT
1802  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT
1803  { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT
1804  { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT
1805  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD
1806  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD
1807  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE
1808  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE
1809  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
1810  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
1811  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
1812  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE
1813  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD
1814  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD
1815  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD
1816  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD
1817  {  0,  0, 0,  0, 0}, // R_TILEGX_IRELATIVE
1818  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1819  {  0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE
1820  {  0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE
1821  {  0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL
1822  {  0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL
1823  { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL
1824  { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL
1825  { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL
1826  { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL
1827  {  0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE
1828  {  0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE
1829  { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE
1830  { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE
1831  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1832  {  0,  0, 0,  0, 0}, // R_TILEGX_INVALID
1833  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD64
1834  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF64
1835  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF64
1836  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPMOD32
1837  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_DTPOFF32
1838  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_TPOFF32
1839  {  3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL
1840  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD
1841  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD
1842  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD
1843  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD
1844  {  0,  0, 0,  0, 0}, // R_TILEGX_TLS_IE_LOAD
1845  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD
1846  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD
1847  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD
1848  {  0,  0, 0,  0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD
1849  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTINHERIT
1850  {  0,  0, 0,  0, 0}, // R_TILEGX_GNU_VTENTRY
1851};
1852
1853// Get the GOT section, creating it if necessary.
1854
1855template<int size, bool big_endian>
1856Output_data_got<size, big_endian>*
1857Target_tilegx<size, big_endian>::got_section(Symbol_table* symtab,
1858                                             Layout* layout)
1859{
1860  if (this->got_ == NULL)
1861    {
1862      gold_assert(symtab != NULL && layout != NULL);
1863
1864      // When using -z now, we can treat .got.plt as a relro section.
1865      // Without -z now, it is modified after program startup by lazy
1866      // PLT relocations.
1867      bool is_got_plt_relro = parameters->options().now();
1868      Output_section_order got_order = (is_got_plt_relro
1869                                        ? ORDER_RELRO
1870                                        : ORDER_RELRO_LAST);
1871      Output_section_order got_plt_order = (is_got_plt_relro
1872                                            ? ORDER_RELRO
1873                                            : ORDER_NON_RELRO_FIRST);
1874
1875      this->got_ = new Output_data_got<size, big_endian>();
1876
1877      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1878                                      (elfcpp::SHF_ALLOC
1879                                       | elfcpp::SHF_WRITE),
1880                                      this->got_, got_order, true);
1881
1882      // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
1883      this->global_offset_table_ =
1884        symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
1885                                      Symbol_table::PREDEFINED,
1886                                      this->got_,
1887                                      0, 0, elfcpp::STT_OBJECT,
1888                                      elfcpp::STB_LOCAL,
1889                                      elfcpp::STV_HIDDEN, 0,
1890                                      false, false);
1891
1892      if (parameters->options().shared()) {
1893        // we need to keep the address of .dynamic section in the
1894        // first got entry for .so
1895        this->tilegx_dynamic_ =
1896          symtab->define_in_output_data("_TILEGX_DYNAMIC_", NULL,
1897                                        Symbol_table::PREDEFINED,
1898                                        layout->dynamic_section(),
1899                                        0, 0, elfcpp::STT_OBJECT,
1900                                        elfcpp::STB_LOCAL,
1901                                        elfcpp::STV_HIDDEN, 0,
1902                                        false, false);
1903
1904        this->got_->add_global(this->tilegx_dynamic_, GOT_TYPE_STANDARD);
1905      } else
1906        // for executable, just set the first entry to zero.
1907        this->got_->set_current_data_size(size / 8);
1908
1909      this->got_plt_ = new Output_data_space(size / 8, "** GOT PLT");
1910      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
1911                                      (elfcpp::SHF_ALLOC
1912                                       | elfcpp::SHF_WRITE),
1913                                      this->got_plt_, got_plt_order,
1914                                      is_got_plt_relro);
1915
1916      // The first two entries are reserved.
1917      this->got_plt_->set_current_data_size
1918             (TILEGX_GOTPLT_RESERVE_COUNT * (size / 8));
1919
1920      if (!is_got_plt_relro)
1921        {
1922          // Those bytes can go into the relro segment.
1923          layout->increase_relro(size / 8);
1924        }
1925
1926
1927      // If there are any IRELATIVE relocations, they get GOT entries
1928      // in .got.plt after the jump slot entries.
1929      this->got_irelative_
1930         = new Output_data_space(size / 8, "** GOT IRELATIVE PLT");
1931      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
1932                                      (elfcpp::SHF_ALLOC
1933                                       | elfcpp::SHF_WRITE),
1934                                      this->got_irelative_,
1935                                      got_plt_order, is_got_plt_relro);
1936    }
1937
1938  return this->got_;
1939}
1940
1941// Get the dynamic reloc section, creating it if necessary.
1942
1943template<int size, bool big_endian>
1944typename Target_tilegx<size, big_endian>::Reloc_section*
1945Target_tilegx<size, big_endian>::rela_dyn_section(Layout* layout)
1946{
1947  if (this->rela_dyn_ == NULL)
1948    {
1949      gold_assert(layout != NULL);
1950      this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
1951      layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
1952                                      elfcpp::SHF_ALLOC, this->rela_dyn_,
1953                                      ORDER_DYNAMIC_RELOCS, false);
1954    }
1955  return this->rela_dyn_;
1956}
1957
1958// Get the section to use for IRELATIVE relocs, creating it if
1959// necessary.  These go in .rela.dyn, but only after all other dynamic
1960// relocations.  They need to follow the other dynamic relocations so
1961// that they can refer to global variables initialized by those
1962// relocs.
1963
1964template<int size, bool big_endian>
1965typename Target_tilegx<size, big_endian>::Reloc_section*
1966Target_tilegx<size, big_endian>::rela_irelative_section(Layout* layout)
1967{
1968  if (this->rela_irelative_ == NULL)
1969    {
1970      // Make sure we have already created the dynamic reloc section.
1971      this->rela_dyn_section(layout);
1972      this->rela_irelative_ = new Reloc_section(false);
1973      layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
1974                                      elfcpp::SHF_ALLOC, this->rela_irelative_,
1975                                      ORDER_DYNAMIC_RELOCS, false);
1976      gold_assert(this->rela_dyn_->output_section()
1977                  == this->rela_irelative_->output_section());
1978    }
1979  return this->rela_irelative_;
1980}
1981
1982// Initialize the PLT section.
1983
1984template<int size, bool big_endian>
1985void
1986Output_data_plt_tilegx<size, big_endian>::init(Layout* layout)
1987{
1988  this->rel_ = new Reloc_section(false);
1989  layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
1990                                  elfcpp::SHF_ALLOC, this->rel_,
1991                                  ORDER_DYNAMIC_PLT_RELOCS, false);
1992}
1993
1994template<int size, bool big_endian>
1995void
1996Output_data_plt_tilegx<size, big_endian>::do_adjust_output_section(
1997  Output_section* os)
1998{
1999  os->set_entsize(this->get_plt_entry_size());
2000}
2001
2002// Add an entry to the PLT.
2003
2004template<int size, bool big_endian>
2005void
2006Output_data_plt_tilegx<size, big_endian>::add_entry(Symbol_table* symtab,
2007  Layout* layout, Symbol* gsym)
2008{
2009  gold_assert(!gsym->has_plt_offset());
2010
2011  unsigned int plt_index;
2012  off_t plt_offset;
2013  section_offset_type got_offset;
2014
2015  unsigned int* pcount;
2016  unsigned int reserved;
2017  Output_data_space* got;
2018  if (gsym->type() == elfcpp::STT_GNU_IFUNC
2019      && gsym->can_use_relative_reloc(false))
2020    {
2021      pcount = &this->irelative_count_;
2022      reserved = 0;
2023      got = this->got_irelative_;
2024    }
2025  else
2026    {
2027      pcount = &this->count_;
2028      reserved = TILEGX_GOTPLT_RESERVE_COUNT;
2029      got = this->got_plt_;
2030    }
2031
2032  if (!this->is_data_size_valid())
2033    {
2034      plt_index = *pcount;
2035
2036      // TILEGX .plt section layout
2037      //
2038      //  ----
2039      //   plt_header
2040      //  ----
2041      //   plt stub
2042      //  ----
2043      //   ...
2044      //  ----
2045      //
2046      // TILEGX .got.plt section layout
2047      //
2048      //  ----
2049      //  reserv1
2050      //  ----
2051      //  reserv2
2052      //  ----
2053      //   entries for normal function
2054      //  ----
2055      //   ...
2056      //  ----
2057      //   entries for ifunc
2058      //  ----
2059      //   ...
2060      //  ----
2061      if (got == this->got_irelative_)
2062        plt_offset = plt_index * this->get_plt_entry_size();
2063      else
2064        plt_offset = (plt_index + 1) * this->get_plt_entry_size();
2065
2066      ++*pcount;
2067
2068      got_offset = (plt_index + reserved) * (size / 8);
2069      gold_assert(got_offset == got->current_data_size());
2070
2071      // Every PLT entry needs a GOT entry which points back to the PLT
2072      // entry (this will be changed by the dynamic linker, normally
2073      // lazily when the function is called).
2074      got->set_current_data_size(got_offset + size / 8);
2075    }
2076  else
2077    {
2078      // FIXME: This is probably not correct for IRELATIVE relocs.
2079
2080      // For incremental updates, find an available slot.
2081      plt_offset = this->free_list_.allocate(this->get_plt_entry_size(),
2082                                             this->get_plt_entry_size(), 0);
2083      if (plt_offset == -1)
2084        gold_fallback(_("out of patch space (PLT);"
2085                        " relink with --incremental-full"));
2086
2087      // The GOT and PLT entries have a 1-1 correspondance, so the GOT offset
2088      // can be calculated from the PLT index, adjusting for the three
2089      // reserved entries at the beginning of the GOT.
2090      plt_index = plt_offset / this->get_plt_entry_size() - 1;
2091      got_offset = (plt_index + reserved) * (size / 8);
2092    }
2093
2094  gsym->set_plt_offset(plt_offset);
2095
2096  // Every PLT entry needs a reloc.
2097  this->add_relocation(symtab, layout, gsym, got_offset);
2098
2099  // Note that we don't need to save the symbol.  The contents of the
2100  // PLT are independent of which symbols are used.  The symbols only
2101  // appear in the relocations.
2102}
2103
2104// Add an entry to the PLT for a local STT_GNU_IFUNC symbol.  Return
2105// the PLT offset.
2106
2107template<int size, bool big_endian>
2108unsigned int
2109Output_data_plt_tilegx<size, big_endian>::add_local_ifunc_entry(
2110    Symbol_table* symtab,
2111    Layout* layout,
2112    Sized_relobj_file<size, big_endian>* relobj,
2113    unsigned int local_sym_index)
2114{
2115  unsigned int plt_offset =
2116    this->irelative_count_ * this->get_plt_entry_size();
2117  ++this->irelative_count_;
2118
2119  section_offset_type got_offset = this->got_irelative_->current_data_size();
2120
2121  // Every PLT entry needs a GOT entry which points back to the PLT
2122  // entry.
2123  this->got_irelative_->set_current_data_size(got_offset + size / 8);
2124
2125  // Every PLT entry needs a reloc.
2126  Reloc_section* rela = this->rela_irelative(symtab, layout);
2127  rela->add_symbolless_local_addend(relobj, local_sym_index,
2128                                    elfcpp::R_TILEGX_IRELATIVE,
2129                                    this->got_irelative_, got_offset, 0);
2130
2131  return plt_offset;
2132}
2133
2134// Add the relocation for a PLT entry.
2135
2136template<int size, bool big_endian>
2137void
2138Output_data_plt_tilegx<size, big_endian>::add_relocation(Symbol_table* symtab,
2139                                             Layout* layout,
2140                                             Symbol* gsym,
2141                                             unsigned int got_offset)
2142{
2143  if (gsym->type() == elfcpp::STT_GNU_IFUNC
2144      && gsym->can_use_relative_reloc(false))
2145    {
2146      Reloc_section* rela = this->rela_irelative(symtab, layout);
2147      rela->add_symbolless_global_addend(gsym, elfcpp::R_TILEGX_IRELATIVE,
2148                                         this->got_irelative_, got_offset, 0);
2149    }
2150  else
2151    {
2152      gsym->set_needs_dynsym_entry();
2153      this->rel_->add_global(gsym, elfcpp::R_TILEGX_JMP_SLOT, this->got_plt_,
2154                             got_offset, 0);
2155    }
2156}
2157
2158// Return where the IRELATIVE relocations should go in the PLT.  These
2159// follow the JUMP_SLOT and the TLSDESC relocations.
2160
2161template<int size, bool big_endian>
2162typename Output_data_plt_tilegx<size, big_endian>::Reloc_section*
2163Output_data_plt_tilegx<size, big_endian>::rela_irelative(Symbol_table* symtab,
2164                                                         Layout* layout)
2165{
2166  if (this->irelative_rel_ == NULL)
2167    {
2168      // case we see any later on.
2169      this->irelative_rel_ = new Reloc_section(false);
2170      layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
2171                                      elfcpp::SHF_ALLOC, this->irelative_rel_,
2172                                      ORDER_DYNAMIC_PLT_RELOCS, false);
2173      gold_assert(this->irelative_rel_->output_section()
2174                  == this->rel_->output_section());
2175
2176      if (parameters->doing_static_link())
2177        {
2178          // A statically linked executable will only have a .rela.plt
2179          // section to hold R_TILEGX_IRELATIVE relocs for
2180          // STT_GNU_IFUNC symbols.  The library will use these
2181          // symbols to locate the IRELATIVE relocs at program startup
2182          // time.
2183          symtab->define_in_output_data("__rela_iplt_start", NULL,
2184                                        Symbol_table::PREDEFINED,
2185                                        this->irelative_rel_, 0, 0,
2186                                        elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
2187                                        elfcpp::STV_HIDDEN, 0, false, true);
2188          symtab->define_in_output_data("__rela_iplt_end", NULL,
2189                                        Symbol_table::PREDEFINED,
2190                                        this->irelative_rel_, 0, 0,
2191                                        elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
2192                                        elfcpp::STV_HIDDEN, 0, true, true);
2193        }
2194    }
2195  return this->irelative_rel_;
2196}
2197
2198// Return the PLT address to use for a global symbol.
2199
2200template<int size, bool big_endian>
2201uint64_t
2202Output_data_plt_tilegx<size, big_endian>::address_for_global(
2203  const Symbol* gsym)
2204{
2205  uint64_t offset = 0;
2206  if (gsym->type() == elfcpp::STT_GNU_IFUNC
2207      && gsym->can_use_relative_reloc(false))
2208    offset = (this->count_ + 1) * this->get_plt_entry_size();
2209  return this->address() + offset + gsym->plt_offset();
2210}
2211
2212// Return the PLT address to use for a local symbol.  These are always
2213// IRELATIVE relocs.
2214
2215template<int size, bool big_endian>
2216uint64_t
2217Output_data_plt_tilegx<size, big_endian>::address_for_local(
2218    const Relobj* object,
2219    unsigned int r_sym)
2220{
2221  return (this->address()
2222	  + (this->count_ + 1) * this->get_plt_entry_size()
2223	  + object->local_plt_offset(r_sym));
2224}
2225
2226// Set the final size.
2227template<int size, bool big_endian>
2228void
2229Output_data_plt_tilegx<size, big_endian>::set_final_data_size()
2230{
2231  unsigned int count = this->count_ + this->irelative_count_;
2232  this->set_data_size((count + 1) * this->get_plt_entry_size());
2233}
2234
2235// The first entry in the PLT for an executable.
2236template<>
2237const unsigned char
2238Output_data_plt_tilegx<64, false>::first_plt_entry[plt_entry_size] =
2239{
2240  0x00, 0x30, 0x48, 0x51,
2241  0x6e, 0x43, 0xa0, 0x18, // { ld_add r28, r27, 8 }
2242  0x00, 0x30, 0xbc, 0x35,
2243  0x00, 0x40, 0xde, 0x9e, // { ld r27, r27 }
2244  0xff, 0xaf, 0x30, 0x40,
2245  0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 }
2246  // padding
2247  0x00, 0x00, 0x00, 0x00,
2248  0x00, 0x00, 0x00, 0x00,
2249  0x00, 0x00, 0x00, 0x00,
2250  0x00, 0x00, 0x00, 0x00
2251};
2252
2253template<>
2254const unsigned char
2255Output_data_plt_tilegx<32, false>::first_plt_entry[plt_entry_size] =
2256{
2257  0x00, 0x30, 0x48, 0x51,
2258  0x6e, 0x23, 0x58, 0x18, // { ld4s_add r28, r27, 4 }
2259  0x00, 0x30, 0xbc, 0x35,
2260  0x00, 0x40, 0xde, 0x9c, // { ld4s r27, r27 }
2261  0xff, 0xaf, 0x30, 0x40,
2262  0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 }
2263  // padding
2264  0x00, 0x00, 0x00, 0x00,
2265  0x00, 0x00, 0x00, 0x00,
2266  0x00, 0x00, 0x00, 0x00,
2267  0x00, 0x00, 0x00, 0x00
2268};
2269
2270template<>
2271const unsigned char
2272Output_data_plt_tilegx<64, true>::first_plt_entry[plt_entry_size] =
2273{
2274  0x00, 0x30, 0x48, 0x51,
2275  0x6e, 0x43, 0xa0, 0x18, // { ld_add r28, r27, 8 }
2276  0x00, 0x30, 0xbc, 0x35,
2277  0x00, 0x40, 0xde, 0x9e, // { ld r27, r27 }
2278  0xff, 0xaf, 0x30, 0x40,
2279  0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 }
2280  // padding
2281  0x00, 0x00, 0x00, 0x00,
2282  0x00, 0x00, 0x00, 0x00,
2283  0x00, 0x00, 0x00, 0x00,
2284  0x00, 0x00, 0x00, 0x00
2285};
2286
2287template<>
2288const unsigned char
2289Output_data_plt_tilegx<32, true>::first_plt_entry[plt_entry_size] =
2290{
2291  0x00, 0x30, 0x48, 0x51,
2292  0x6e, 0x23, 0x58, 0x18, // { ld4s_add r28, r27, 4 }
2293  0x00, 0x30, 0xbc, 0x35,
2294  0x00, 0x40, 0xde, 0x9c, // { ld4s r27, r27 }
2295  0xff, 0xaf, 0x30, 0x40,
2296  0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 }
2297  // padding
2298  0x00, 0x00, 0x00, 0x00,
2299  0x00, 0x00, 0x00, 0x00,
2300  0x00, 0x00, 0x00, 0x00,
2301  0x00, 0x00, 0x00, 0x00
2302};
2303
2304template<int size, bool big_endian>
2305void
2306Output_data_plt_tilegx<size, big_endian>::fill_first_plt_entry(
2307  unsigned char* pov)
2308{
2309  memcpy(pov, first_plt_entry, plt_entry_size);
2310}
2311
2312// Subsequent entries in the PLT for an executable.
2313
2314template<>
2315const unsigned char
2316Output_data_plt_tilegx<64, false>::plt_entry[plt_entry_size] =
2317{
2318  0xdc, 0x0f, 0x00, 0x10,
2319  0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 }
2320  0xdb, 0x0f, 0x00, 0x10,
2321  0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 }
2322  0x9c, 0xc6, 0x0d, 0xd0,
2323  0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 }
2324  0x9b, 0xb6, 0xc5, 0xad,
2325  0xff, 0x57, 0xe0, 0x8e, // { add r27, r26, r27 ; info 10 ; ld r28, r28 }
2326  0xdd, 0x0f, 0x00, 0x70,
2327  0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 }
2328
2329};
2330
2331template<>
2332const unsigned char
2333Output_data_plt_tilegx<32, false>::plt_entry[plt_entry_size] =
2334{
2335  0xdc, 0x0f, 0x00, 0x10,
2336  0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 }
2337  0xdb, 0x0f, 0x00, 0x10,
2338  0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 }
2339  0x9c, 0xc6, 0x0d, 0xd0,
2340  0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 }
2341  0x9b, 0xb6, 0xc5, 0xad,
2342  0xff, 0x57, 0xe0, 0x8c, // { add r27, r26, r27 ; info 10 ; ld4s r28, r28 }
2343  0xdd, 0x0f, 0x00, 0x70,
2344  0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 }
2345};
2346
2347template<>
2348const unsigned char
2349Output_data_plt_tilegx<64, true>::plt_entry[plt_entry_size] =
2350{
2351  0xdc, 0x0f, 0x00, 0x10,
2352  0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 }
2353  0xdb, 0x0f, 0x00, 0x10,
2354  0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 }
2355  0x9c, 0xc6, 0x0d, 0xd0,
2356  0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 }
2357  0x9b, 0xb6, 0xc5, 0xad,
2358  0xff, 0x57, 0xe0, 0x8e, // { add r27, r26, r27 ; info 10 ; ld r28, r28 }
2359  0xdd, 0x0f, 0x00, 0x70,
2360  0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 }
2361
2362};
2363
2364template<>
2365const unsigned char
2366Output_data_plt_tilegx<32, true>::plt_entry[plt_entry_size] =
2367{
2368  0xdc, 0x0f, 0x00, 0x10,
2369  0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 }
2370  0xdb, 0x0f, 0x00, 0x10,
2371  0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 }
2372  0x9c, 0xc6, 0x0d, 0xd0,
2373  0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 }
2374  0x9b, 0xb6, 0xc5, 0xad,
2375  0xff, 0x57, 0xe0, 0x8c, // { add r27, r26, r27 ; info 10 ; ld4s r28, r28 }
2376  0xdd, 0x0f, 0x00, 0x70,
2377  0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 }
2378};
2379
2380template<int size, bool big_endian>
2381void
2382Output_data_plt_tilegx<size, big_endian>::fill_plt_entry(
2383                 unsigned char* pov,
2384                 typename elfcpp::Elf_types<size>::Elf_Addr gotplt_base,
2385                 unsigned int got_offset,
2386                 typename elfcpp::Elf_types<size>::Elf_Addr plt_base,
2387                 unsigned int plt_offset, unsigned int plt_index)
2388{
2389
2390  const uint32_t TILEGX_IMM16_MASK = 0xFFFF;
2391  const uint32_t TILEGX_X0_IMM16_BITOFF = 12;
2392  const uint32_t TILEGX_X1_IMM16_BITOFF = 43;
2393
2394  typedef typename elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::Valtype
2395    Valtype;
2396  memcpy(pov, plt_entry, plt_entry_size);
2397
2398  // first bundle in plt stub - x0
2399  Valtype* wv = reinterpret_cast<Valtype*>(pov);
2400  Valtype val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv);
2401  Valtype reloc =
2402    ((gotplt_base + got_offset) - (plt_base + plt_offset + 8)) >> 16;
2403  elfcpp::Elf_Xword dst_mask =
2404    (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X0_IMM16_BITOFF;
2405  val &= ~dst_mask;
2406  reloc &= TILEGX_IMM16_MASK;
2407  elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv,
2408    val | (reloc<<TILEGX_X0_IMM16_BITOFF));
2409
2410  // second bundle in plt stub - x1
2411  wv = reinterpret_cast<Valtype*>(pov + 8);
2412  val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv);
2413  reloc = (gotplt_base + got_offset) - (plt_base + plt_offset + 8);
2414  dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X1_IMM16_BITOFF;
2415  val &= ~dst_mask;
2416  reloc &= TILEGX_IMM16_MASK;
2417  elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv,
2418    val | (reloc<<TILEGX_X1_IMM16_BITOFF));
2419
2420  // second bundle in plt stub - x0
2421  wv = reinterpret_cast<Valtype*>(pov + 8);
2422  val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv);
2423  reloc = (gotplt_base - (plt_base + plt_offset + 8)) >> 16;
2424  dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X0_IMM16_BITOFF;
2425  val &= ~dst_mask;
2426  reloc &= TILEGX_IMM16_MASK;
2427  elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv,
2428    val | (reloc<<TILEGX_X0_IMM16_BITOFF));
2429
2430  // third bundle in plt stub - x1
2431  wv = reinterpret_cast<Valtype*>(pov + 16);
2432  val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv);
2433  reloc = gotplt_base - (plt_base + plt_offset + 8);
2434  dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X1_IMM16_BITOFF;
2435  val &= ~dst_mask;
2436  reloc &= TILEGX_IMM16_MASK;
2437  elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv,
2438    val | (reloc<<TILEGX_X1_IMM16_BITOFF));
2439
2440  // fifth bundle in plt stub - carry plt_index x0
2441  wv = reinterpret_cast<Valtype*>(pov + 32);
2442  val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv);
2443  dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X0_IMM16_BITOFF;
2444  val &= ~dst_mask;
2445  plt_index &= TILEGX_IMM16_MASK;
2446  elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv,
2447    val | (plt_index<<TILEGX_X0_IMM16_BITOFF));
2448
2449}
2450
2451// Write out the PLT.  This uses the hand-coded instructions above.
2452
2453template<int size, bool big_endian>
2454void
2455Output_data_plt_tilegx<size, big_endian>::do_write(Output_file* of)
2456{
2457  const off_t offset = this->offset();
2458  const section_size_type oview_size =
2459    convert_to_section_size_type(this->data_size());
2460  unsigned char* const oview = of->get_output_view(offset, oview_size);
2461
2462  const off_t got_file_offset = this->got_plt_->offset();
2463  gold_assert(parameters->incremental_update()
2464              || (got_file_offset + this->got_plt_->data_size()
2465                  == this->got_irelative_->offset()));
2466  const section_size_type got_size =
2467    convert_to_section_size_type(this->got_plt_->data_size()
2468                                 + this->got_irelative_->data_size());
2469  unsigned char* const got_view = of->get_output_view(got_file_offset,
2470                                                      got_size);
2471
2472  unsigned char* pov = oview;
2473
2474  // The base address of the .plt section.
2475  typename elfcpp::Elf_types<size>::Elf_Addr plt_address = this->address();
2476  typename elfcpp::Elf_types<size>::Elf_Addr got_address =
2477    this->got_plt_->address();
2478
2479  this->fill_first_plt_entry(pov);
2480  pov += this->get_plt_entry_size();
2481
2482  unsigned char* got_pov = got_view;
2483
2484  // first entry of .got.plt are set to -1
2485  // second entry of .got.plt are set to 0
2486  memset(got_pov, 0xff, size / 8);
2487  got_pov += size / 8;
2488  memset(got_pov, 0x0, size / 8);
2489  got_pov += size / 8;
2490
2491  unsigned int plt_offset = this->get_plt_entry_size();
2492  const unsigned int count = this->count_ + this->irelative_count_;
2493  unsigned int got_offset = (size / 8) * TILEGX_GOTPLT_RESERVE_COUNT;
2494  for (unsigned int plt_index = 0;
2495       plt_index < count;
2496       ++plt_index,
2497         pov += this->get_plt_entry_size(),
2498         got_pov += size / 8,
2499         plt_offset += this->get_plt_entry_size(),
2500         got_offset += size / 8)
2501    {
2502      // Set and adjust the PLT entry itself.
2503      this->fill_plt_entry(pov, got_address, got_offset,
2504                           plt_address, plt_offset, plt_index);
2505
2506      // Initialize entry in .got.plt to plt start address
2507      elfcpp::Swap<size, big_endian>::writeval(got_pov, plt_address);
2508    }
2509
2510  gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
2511  gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
2512
2513  of->write_output_view(offset, oview_size, oview);
2514  of->write_output_view(got_file_offset, got_size, got_view);
2515}
2516
2517// Create the PLT section.
2518
2519template<int size, bool big_endian>
2520void
2521Target_tilegx<size, big_endian>::make_plt_section(Symbol_table* symtab,
2522                                                  Layout* layout)
2523{
2524  if (this->plt_ == NULL)
2525    {
2526      // Create the GOT sections first.
2527      this->got_section(symtab, layout);
2528
2529      // Ensure that .rela.dyn always appears before .rela.plt,
2530      // because on TILE-Gx, .rela.dyn needs to include .rela.plt
2531      // in it's range.
2532      this->rela_dyn_section(layout);
2533
2534      this->plt_ = new Output_data_plt_tilegx<size, big_endian>(layout,
2535        TILEGX_INST_BUNDLE_SIZE, this->got_, this->got_plt_,
2536        this->got_irelative_);
2537
2538      layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
2539                                      (elfcpp::SHF_ALLOC
2540                                       | elfcpp::SHF_EXECINSTR),
2541                                      this->plt_, ORDER_NON_RELRO_FIRST,
2542                                      false);
2543
2544      // Make the sh_info field of .rela.plt point to .plt.
2545      Output_section* rela_plt_os = this->plt_->rela_plt()->output_section();
2546      rela_plt_os->set_info_section(this->plt_->output_section());
2547    }
2548}
2549
2550// Create a PLT entry for a global symbol.
2551
2552template<int size, bool big_endian>
2553void
2554Target_tilegx<size, big_endian>::make_plt_entry(Symbol_table* symtab,
2555                                                Layout* layout, Symbol* gsym)
2556{
2557  if (gsym->has_plt_offset())
2558    return;
2559
2560  if (this->plt_ == NULL)
2561    this->make_plt_section(symtab, layout);
2562
2563  this->plt_->add_entry(symtab, layout, gsym);
2564}
2565
2566// Make a PLT entry for a local STT_GNU_IFUNC symbol.
2567
2568template<int size, bool big_endian>
2569void
2570Target_tilegx<size, big_endian>::make_local_ifunc_plt_entry(
2571    Symbol_table* symtab, Layout* layout,
2572    Sized_relobj_file<size, big_endian>* relobj,
2573    unsigned int local_sym_index)
2574{
2575  if (relobj->local_has_plt_offset(local_sym_index))
2576    return;
2577  if (this->plt_ == NULL)
2578    this->make_plt_section(symtab, layout);
2579  unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout,
2580                                                              relobj,
2581                                                              local_sym_index);
2582  relobj->set_local_plt_offset(local_sym_index, plt_offset);
2583}
2584
2585// Return the number of entries in the PLT.
2586
2587template<int size, bool big_endian>
2588unsigned int
2589Target_tilegx<size, big_endian>::plt_entry_count() const
2590{
2591  if (this->plt_ == NULL)
2592    return 0;
2593  return this->plt_->entry_count();
2594}
2595
2596// Return the offset of the first non-reserved PLT entry.
2597
2598template<int size, bool big_endian>
2599unsigned int
2600Target_tilegx<size, big_endian>::first_plt_entry_offset() const
2601{
2602  return this->plt_->first_plt_entry_offset();
2603}
2604
2605// Return the size of each PLT entry.
2606
2607template<int size, bool big_endian>
2608unsigned int
2609Target_tilegx<size, big_endian>::plt_entry_size() const
2610{
2611  return this->plt_->get_plt_entry_size();
2612}
2613
2614// Create the GOT and PLT sections for an incremental update.
2615
2616template<int size, bool big_endian>
2617Output_data_got_base*
2618Target_tilegx<size, big_endian>::init_got_plt_for_update(Symbol_table* symtab,
2619                                       Layout* layout,
2620                                       unsigned int got_count,
2621                                       unsigned int plt_count)
2622{
2623  gold_assert(this->got_ == NULL);
2624
2625  this->got_ =
2626    new Output_data_got<size, big_endian>((got_count
2627                                           + TILEGX_GOT_RESERVE_COUNT)
2628                                          * (size / 8));
2629  layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
2630                                  (elfcpp::SHF_ALLOC
2631                                   | elfcpp::SHF_WRITE),
2632                                  this->got_, ORDER_RELRO_LAST,
2633                                  true);
2634
2635  // Define _GLOBAL_OFFSET_TABLE_ at the start of the GOT.
2636  this->global_offset_table_ =
2637    symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
2638                                  Symbol_table::PREDEFINED,
2639                                  this->got_,
2640                                  0, 0, elfcpp::STT_OBJECT,
2641                                  elfcpp::STB_LOCAL,
2642                                  elfcpp::STV_HIDDEN, 0,
2643                                  false, false);
2644
2645  if (parameters->options().shared()) {
2646    this->tilegx_dynamic_ =
2647            symtab->define_in_output_data("_TILEGX_DYNAMIC_", NULL,
2648                            Symbol_table::PREDEFINED,
2649                            layout->dynamic_section(),
2650                            0, 0, elfcpp::STT_OBJECT,
2651                            elfcpp::STB_LOCAL,
2652                            elfcpp::STV_HIDDEN, 0,
2653                            false, false);
2654
2655    this->got_->add_global(this->tilegx_dynamic_, GOT_TYPE_STANDARD);
2656  } else
2657    this->got_->set_current_data_size(size / 8);
2658
2659  // Add the two reserved entries.
2660  this->got_plt_
2661     = new Output_data_space((plt_count + TILEGX_GOTPLT_RESERVE_COUNT)
2662                              * (size / 8), size / 8, "** GOT PLT");
2663  layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
2664                                  (elfcpp::SHF_ALLOC
2665                                   | elfcpp::SHF_WRITE),
2666                                  this->got_plt_, ORDER_NON_RELRO_FIRST,
2667                                  false);
2668
2669  // If there are any IRELATIVE relocations, they get GOT entries in
2670  // .got.plt after the jump slot.
2671  this->got_irelative_
2672     = new Output_data_space(0, size / 8, "** GOT IRELATIVE PLT");
2673  layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
2674                                  elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
2675                                  this->got_irelative_,
2676                                  ORDER_NON_RELRO_FIRST, false);
2677
2678  // Create the PLT section.
2679  this->plt_ = new Output_data_plt_tilegx<size, big_endian>(layout,
2680    this->plt_entry_size(), this->got_, this->got_plt_, this->got_irelative_,
2681    plt_count);
2682
2683  layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
2684                                  elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR,
2685                                  this->plt_, ORDER_PLT, false);
2686
2687  // Make the sh_info field of .rela.plt point to .plt.
2688  Output_section* rela_plt_os = this->plt_->rela_plt()->output_section();
2689  rela_plt_os->set_info_section(this->plt_->output_section());
2690
2691  // Create the rela_dyn section.
2692  this->rela_dyn_section(layout);
2693
2694  return this->got_;
2695}
2696
2697// Reserve a GOT entry for a local symbol, and regenerate any
2698// necessary dynamic relocations.
2699
2700template<int size, bool big_endian>
2701void
2702Target_tilegx<size, big_endian>::reserve_local_got_entry(
2703    unsigned int got_index,
2704    Sized_relobj<size, big_endian>* obj,
2705    unsigned int r_sym,
2706    unsigned int got_type)
2707{
2708  unsigned int got_offset = (got_index + TILEGX_GOT_RESERVE_COUNT)
2709                            * (size / 8);
2710  Reloc_section* rela_dyn = this->rela_dyn_section(NULL);
2711
2712  this->got_->reserve_local(got_index, obj, r_sym, got_type);
2713  switch (got_type)
2714    {
2715    case GOT_TYPE_STANDARD:
2716      if (parameters->options().output_is_position_independent())
2717        rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_TILEGX_RELATIVE,
2718                                     this->got_, got_offset, 0, false);
2719      break;
2720    case GOT_TYPE_TLS_OFFSET:
2721      rela_dyn->add_local(obj, r_sym,
2722                          size == 32 ? elfcpp::R_TILEGX_TLS_DTPOFF32
2723                                       : elfcpp::R_TILEGX_TLS_DTPOFF64,
2724                          this->got_, got_offset, 0);
2725      break;
2726    case GOT_TYPE_TLS_PAIR:
2727      this->got_->reserve_slot(got_index + 1);
2728      rela_dyn->add_local(obj, r_sym,
2729                          size == 32 ? elfcpp::R_TILEGX_TLS_DTPMOD32
2730                                       : elfcpp::R_TILEGX_TLS_DTPMOD64,
2731                          this->got_, got_offset, 0);
2732      break;
2733    case GOT_TYPE_TLS_DESC:
2734      gold_fatal(_("TLS_DESC not yet supported for incremental linking"));
2735      break;
2736    default:
2737      gold_unreachable();
2738    }
2739}
2740
2741// Reserve a GOT entry for a global symbol, and regenerate any
2742// necessary dynamic relocations.
2743
2744template<int size, bool big_endian>
2745void
2746Target_tilegx<size, big_endian>::reserve_global_got_entry(
2747  unsigned int got_index, Symbol* gsym, unsigned int got_type)
2748{
2749  unsigned int got_offset = (got_index + TILEGX_GOT_RESERVE_COUNT)
2750                            * (size / 8);
2751  Reloc_section* rela_dyn = this->rela_dyn_section(NULL);
2752
2753  this->got_->reserve_global(got_index, gsym, got_type);
2754  switch (got_type)
2755    {
2756    case GOT_TYPE_STANDARD:
2757      if (!gsym->final_value_is_known())
2758        {
2759          if (gsym->is_from_dynobj()
2760              || gsym->is_undefined()
2761              || gsym->is_preemptible()
2762              || gsym->type() == elfcpp::STT_GNU_IFUNC)
2763            rela_dyn->add_global(gsym, elfcpp::R_TILEGX_GLOB_DAT,
2764                                 this->got_, got_offset, 0);
2765          else
2766            rela_dyn->add_global_relative(gsym, elfcpp::R_TILEGX_RELATIVE,
2767                                          this->got_, got_offset, 0, false);
2768        }
2769      break;
2770    case GOT_TYPE_TLS_OFFSET:
2771      rela_dyn->add_global_relative(gsym,
2772                                    size == 32 ? elfcpp::R_TILEGX_TLS_TPOFF32
2773                                               : elfcpp::R_TILEGX_TLS_TPOFF64,
2774                                    this->got_, got_offset, 0, false);
2775      break;
2776    case GOT_TYPE_TLS_PAIR:
2777      this->got_->reserve_slot(got_index + 1);
2778      rela_dyn->add_global_relative(gsym,
2779                                    size == 32 ? elfcpp::R_TILEGX_TLS_DTPMOD32
2780                                               : elfcpp::R_TILEGX_TLS_DTPMOD64,
2781                                    this->got_, got_offset, 0, false);
2782      rela_dyn->add_global_relative(gsym,
2783                                    size == 32 ? elfcpp::R_TILEGX_TLS_DTPOFF32
2784                                               : elfcpp::R_TILEGX_TLS_DTPOFF64,
2785                                    this->got_, got_offset + size / 8,
2786                                    0, false);
2787      break;
2788    case GOT_TYPE_TLS_DESC:
2789      gold_fatal(_("TLS_DESC not yet supported for TILEGX"));
2790      break;
2791    default:
2792      gold_unreachable();
2793    }
2794}
2795
2796// Register an existing PLT entry for a global symbol.
2797
2798template<int size, bool big_endian>
2799void
2800Target_tilegx<size, big_endian>::register_global_plt_entry(
2801  Symbol_table* symtab, Layout* layout, unsigned int plt_index, Symbol* gsym)
2802{
2803  gold_assert(this->plt_ != NULL);
2804  gold_assert(!gsym->has_plt_offset());
2805
2806  this->plt_->reserve_slot(plt_index);
2807
2808  gsym->set_plt_offset((plt_index + 1) * this->plt_entry_size());
2809
2810  unsigned int got_offset = (plt_index + 2) * (size / 8);
2811  this->plt_->add_relocation(symtab, layout, gsym, got_offset);
2812}
2813
2814// Force a COPY relocation for a given symbol.
2815
2816template<int size, bool big_endian>
2817void
2818Target_tilegx<size, big_endian>::emit_copy_reloc(
2819    Symbol_table* symtab, Symbol* sym, Output_section* os, off_t offset)
2820{
2821  this->copy_relocs_.emit_copy_reloc(symtab,
2822                                     symtab->get_sized_symbol<size>(sym),
2823                                     os,
2824                                     offset,
2825                                     this->rela_dyn_section(NULL));
2826}
2827
2828// Create a GOT entry for the TLS module index.
2829
2830template<int size, bool big_endian>
2831unsigned int
2832Target_tilegx<size, big_endian>::got_mod_index_entry(Symbol_table* symtab,
2833                                  Layout* layout,
2834                                  Sized_relobj_file<size, big_endian>* object)
2835{
2836  if (this->got_mod_index_offset_ == -1U)
2837    {
2838      gold_assert(symtab != NULL && layout != NULL && object != NULL);
2839      Reloc_section* rela_dyn = this->rela_dyn_section(layout);
2840      Output_data_got<size, big_endian>* got
2841         = this->got_section(symtab, layout);
2842      unsigned int got_offset = got->add_constant(0);
2843      rela_dyn->add_local(object, 0,
2844                          size == 32 ? elfcpp::R_TILEGX_TLS_DTPMOD32
2845                                       : elfcpp::R_TILEGX_TLS_DTPMOD64, got,
2846                          got_offset, 0);
2847      got->add_constant(0);
2848      this->got_mod_index_offset_ = got_offset;
2849    }
2850  return this->got_mod_index_offset_;
2851}
2852
2853// Optimize the TLS relocation type based on what we know about the
2854// symbol.  IS_FINAL is true if the final address of this symbol is
2855// known at link time.
2856//
2857// the transformation rules is described below:
2858//
2859//   compiler GD reference
2860//    |
2861//    V
2862//     moveli      tmp, hw1_last_tls_gd(x)     X0/X1
2863//     shl16insli  r0,  tmp, hw0_tls_gd(x)     X0/X1
2864//     addi        r0, got, tls_add(x)         Y0/Y1/X0/X1
2865//     jal         tls_gd_call(x)              X1
2866//     addi        adr, r0,  tls_gd_add(x)     Y0/Y1/X0/X1
2867//
2868//     linker tranformation of GD insn sequence
2869//      |
2870//      V
2871//      ==> GD:
2872//       moveli      tmp, hw1_last_tls_gd(x)     X0/X1
2873//       shl16insli  r0,  tmp, hw0_tls_gd(x)     X0/X1
2874//       add         r0,  got, r0                Y0/Y1/X0/X1
2875//       jal         plt(__tls_get_addr)         X1
2876//       move        adr, r0                     Y0/Y1/X0/X1
2877//      ==> IE:
2878//       moveli      tmp, hw1_last_tls_ie(x)     X0/X1
2879//       shl16insli  r0,  tmp, hw0_tls_ie(x)     X0/X1
2880//       add         r0,  got, r0                Y0/Y1/X0/X1
2881//       ld          r0,  r0                     X1
2882//       add         adr, r0, tp                 Y0/Y1/X0/X1
2883//      ==> LE:
2884//       moveli      tmp, hw1_last_tls_le(x)     X0/X1
2885//       shl16insli  r0,  tmp, hw0_tls_le(x)     X0/X1
2886//       move        r0,  r0                     Y0/Y1/X0/X1
2887//       move        r0,  r0                     Y0/Y1/X0/X1
2888//       add         adr, r0, tp                 Y0/Y1/X0/X1
2889//
2890//
2891//   compiler IE reference
2892//    |
2893//    V
2894//     moveli      tmp, hw1_last_tls_ie(x)     X0/X1
2895//     shl16insli  tmp, tmp, hw0_tls_ie(x)     X0/X1
2896//     addi        tmp, got, tls_add(x)        Y0/Y1/X0/X1
2897//     ld_tls      tmp, tmp, tls_ie_load(x)    X1
2898//     add         adr, tmp, tp                Y0/Y1/X0/X1
2899//
2900//     linker transformation for IE insn sequence
2901//      |
2902//      V
2903//      ==> IE:
2904//       moveli      tmp, hw1_last_tls_ie(x)     X0/X1
2905//       shl16insli  tmp, tmp, hw0_tls_ie(x)     X0/X1
2906//       add         tmp, got, tmp               Y0/Y1/X0/X1
2907//       ld          tmp, tmp                    X1
2908//       add         adr, tmp, tp                Y0/Y1/X0/X1
2909//      ==> LE:
2910//       moveli      tmp, hw1_last_tls_le(x)     X0/X1
2911//       shl16insli  tmp, tmp, hw0_tls_le(x)     X0/X1
2912//       move        tmp, tmp                    Y0/Y1/X0/X1
2913//       move        tmp, tmp                    Y0/Y1/X0/X1
2914//
2915//
2916//   compiler LE reference
2917//    |
2918//    V
2919//     moveli        tmp, hw1_last_tls_le(x)     X0/X1
2920//     shl16insli    tmp, tmp, hw0_tls_le(x)     X0/X1
2921//     add           adr, tmp, tp                Y0/Y1/X0/X1
2922
2923template<int size, bool big_endian>
2924tls::Tls_optimization
2925Target_tilegx<size, big_endian>::optimize_tls_reloc(bool is_final, int r_type)
2926{
2927  // If we are generating a shared library, then we can't do anything
2928  // in the linker.
2929  if (parameters->options().shared())
2930    return tls::TLSOPT_NONE;
2931
2932  switch (r_type)
2933    {
2934    // unique GD relocations
2935    case elfcpp::R_TILEGX_TLS_GD_CALL:
2936    case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
2937    case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
2938    case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
2939    case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
2940    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
2941    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
2942    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
2943    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
2944    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
2945    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
2946      // These are General-Dynamic which permits fully general TLS
2947      // access.  Since we know that we are generating an executable,
2948      // we can convert this to Initial-Exec.  If we also know that
2949      // this is a local symbol, we can further switch to Local-Exec.
2950      if (is_final)
2951        return tls::TLSOPT_TO_LE;
2952      return tls::TLSOPT_TO_IE;
2953
2954    // unique IE relocations
2955    case elfcpp::R_TILEGX_TLS_IE_LOAD:
2956    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
2957    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
2958    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
2959    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
2960    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
2961    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
2962      // These are Initial-Exec relocs which get the thread offset
2963      // from the GOT.  If we know that we are linking against the
2964      // local symbol, we can switch to Local-Exec, which links the
2965      // thread offset into the instruction.
2966      if (is_final)
2967        return tls::TLSOPT_TO_LE;
2968      return tls::TLSOPT_NONE;
2969
2970    // could be created for both GD and IE
2971    // but they are expanded into the same
2972    // instruction in GD and IE.
2973    case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
2974    case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
2975    case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
2976    case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
2977      if (is_final)
2978        return tls::TLSOPT_TO_LE;
2979      return tls::TLSOPT_NONE;
2980
2981    // unique LE relocations
2982    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
2983    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
2984    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
2985    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
2986    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
2987    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
2988      // When we already have Local-Exec, there is nothing further we
2989      // can do.
2990      return tls::TLSOPT_NONE;
2991
2992    default:
2993      gold_unreachable();
2994    }
2995}
2996
2997// Get the Reference_flags for a particular relocation.
2998
2999template<int size, bool big_endian>
3000int
3001Target_tilegx<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
3002{
3003  switch (r_type)
3004    {
3005    case elfcpp::R_TILEGX_NONE:
3006    case elfcpp::R_TILEGX_GNU_VTINHERIT:
3007    case elfcpp::R_TILEGX_GNU_VTENTRY:
3008      // No symbol reference.
3009      return 0;
3010
3011    case elfcpp::R_TILEGX_64:
3012    case elfcpp::R_TILEGX_32:
3013    case elfcpp::R_TILEGX_16:
3014    case elfcpp::R_TILEGX_8:
3015      return Symbol::ABSOLUTE_REF;
3016
3017    case elfcpp::R_TILEGX_BROFF_X1:
3018    case elfcpp::R_TILEGX_64_PCREL:
3019    case elfcpp::R_TILEGX_32_PCREL:
3020    case elfcpp::R_TILEGX_16_PCREL:
3021    case elfcpp::R_TILEGX_8_PCREL:
3022    case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL:
3023    case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL:
3024    case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL:
3025    case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL:
3026    case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL:
3027    case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL:
3028    case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL:
3029    case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL:
3030    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
3031    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
3032    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
3033    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
3034    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
3035    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
3036      return Symbol::RELATIVE_REF;
3037
3038    case elfcpp::R_TILEGX_JUMPOFF_X1:
3039    case elfcpp::R_TILEGX_JUMPOFF_X1_PLT:
3040    case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
3041    case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
3042    case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
3043    case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
3044    case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
3045    case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
3046    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
3047    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
3048    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
3049    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
3050    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
3051    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
3052      return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
3053
3054    case elfcpp::R_TILEGX_IMM16_X0_HW0:
3055    case elfcpp::R_TILEGX_IMM16_X1_HW0:
3056    case elfcpp::R_TILEGX_IMM16_X0_HW1:
3057    case elfcpp::R_TILEGX_IMM16_X1_HW1:
3058    case elfcpp::R_TILEGX_IMM16_X0_HW2:
3059    case elfcpp::R_TILEGX_IMM16_X1_HW2:
3060    case elfcpp::R_TILEGX_IMM16_X0_HW3:
3061    case elfcpp::R_TILEGX_IMM16_X1_HW3:
3062    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST:
3063    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST:
3064    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST:
3065    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST:
3066    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST:
3067    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST:
3068      return Symbol::ABSOLUTE_REF;
3069
3070    case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT:
3071    case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT:
3072    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT:
3073    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT:
3074    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT:
3075    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT:
3076      // Absolute in GOT.
3077      return Symbol::ABSOLUTE_REF;
3078
3079    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
3080    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
3081    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
3082    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
3083    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
3084    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
3085    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
3086    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
3087    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
3088    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
3089    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
3090    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
3091    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
3092    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
3093    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
3094    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
3095    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
3096    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
3097    case elfcpp::R_TILEGX_TLS_DTPOFF64:
3098    case elfcpp::R_TILEGX_TLS_DTPMOD32:
3099    case elfcpp::R_TILEGX_TLS_DTPOFF32:
3100    case elfcpp::R_TILEGX_TLS_TPOFF32:
3101    case elfcpp::R_TILEGX_TLS_GD_CALL:
3102    case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
3103    case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
3104    case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
3105    case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
3106    case elfcpp::R_TILEGX_TLS_IE_LOAD:
3107    case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
3108    case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
3109    case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
3110    case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
3111      return Symbol::TLS_REF;
3112
3113    case elfcpp::R_TILEGX_COPY:
3114    case elfcpp::R_TILEGX_GLOB_DAT:
3115    case elfcpp::R_TILEGX_JMP_SLOT:
3116    case elfcpp::R_TILEGX_RELATIVE:
3117    case elfcpp::R_TILEGX_TLS_TPOFF64:
3118    case elfcpp::R_TILEGX_TLS_DTPMOD64:
3119    default:
3120      // Not expected.  We will give an error later.
3121      return 0;
3122    }
3123}
3124
3125// Report an unsupported relocation against a local symbol.
3126
3127template<int size, bool big_endian>
3128void
3129Target_tilegx<size, big_endian>::Scan::unsupported_reloc_local(
3130     Sized_relobj_file<size, big_endian>* object,
3131     unsigned int r_type)
3132{
3133  gold_error(_("%s: unsupported reloc %u against local symbol"),
3134             object->name().c_str(), r_type);
3135}
3136
3137// We are about to emit a dynamic relocation of type R_TYPE.  If the
3138// dynamic linker does not support it, issue an error.
3139template<int size, bool big_endian>
3140void
3141Target_tilegx<size, big_endian>::Scan::check_non_pic(Relobj* object,
3142                                                     unsigned int r_type)
3143{
3144  switch (r_type)
3145    {
3146      // These are the relocation types supported by glibc for tilegx
3147      // which should always work.
3148    case elfcpp::R_TILEGX_RELATIVE:
3149    case elfcpp::R_TILEGX_GLOB_DAT:
3150    case elfcpp::R_TILEGX_JMP_SLOT:
3151    case elfcpp::R_TILEGX_TLS_DTPMOD64:
3152    case elfcpp::R_TILEGX_TLS_DTPOFF64:
3153    case elfcpp::R_TILEGX_TLS_TPOFF64:
3154    case elfcpp::R_TILEGX_8:
3155    case elfcpp::R_TILEGX_16:
3156    case elfcpp::R_TILEGX_32:
3157    case elfcpp::R_TILEGX_64:
3158    case elfcpp::R_TILEGX_COPY:
3159    case elfcpp::R_TILEGX_IMM16_X0_HW0:
3160    case elfcpp::R_TILEGX_IMM16_X1_HW0:
3161    case elfcpp::R_TILEGX_IMM16_X0_HW1:
3162    case elfcpp::R_TILEGX_IMM16_X1_HW1:
3163    case elfcpp::R_TILEGX_IMM16_X0_HW2:
3164    case elfcpp::R_TILEGX_IMM16_X1_HW2:
3165    case elfcpp::R_TILEGX_IMM16_X0_HW3:
3166    case elfcpp::R_TILEGX_IMM16_X1_HW3:
3167    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST:
3168    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST:
3169    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST:
3170    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST:
3171    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST:
3172    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST:
3173    case elfcpp::R_TILEGX_BROFF_X1:
3174    case elfcpp::R_TILEGX_JUMPOFF_X1:
3175    case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL:
3176    case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL:
3177    case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL:
3178    case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL:
3179    case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL:
3180    case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL:
3181    case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL:
3182    case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL:
3183    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
3184    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
3185    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
3186    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
3187    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
3188    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
3189      return;
3190
3191    default:
3192      // This prevents us from issuing more than one error per reloc
3193      // section.  But we can still wind up issuing more than one
3194      // error per object file.
3195      if (this->issued_non_pic_error_)
3196        return;
3197      gold_assert(parameters->options().output_is_position_independent());
3198      object->error(_("requires unsupported dynamic reloc %u; "
3199                      "recompile with -fPIC"),
3200                    r_type);
3201      this->issued_non_pic_error_ = true;
3202      return;
3203
3204    case elfcpp::R_TILEGX_NONE:
3205      gold_unreachable();
3206    }
3207}
3208
3209// Return whether we need to make a PLT entry for a relocation of the
3210// given type against a STT_GNU_IFUNC symbol.
3211
3212template<int size, bool big_endian>
3213bool
3214Target_tilegx<size, big_endian>::Scan::reloc_needs_plt_for_ifunc(
3215     Sized_relobj_file<size, big_endian>* object, unsigned int r_type)
3216{
3217  int flags = Scan::get_reference_flags(r_type);
3218  if (flags & Symbol::TLS_REF)
3219    gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
3220               object->name().c_str(), r_type);
3221  return flags != 0;
3222}
3223
3224// Scan a relocation for a local symbol.
3225
3226template<int size, bool big_endian>
3227inline void
3228Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab,
3229                                 Layout* layout,
3230                                 Target_tilegx<size, big_endian>* target,
3231                                 Sized_relobj_file<size, big_endian>* object,
3232                                 unsigned int data_shndx,
3233                                 Output_section* output_section,
3234                                 const elfcpp::Rela<size, big_endian>& reloc,
3235                                 unsigned int r_type,
3236                                 const elfcpp::Sym<size, big_endian>& lsym,
3237                                 bool is_discarded)
3238{
3239  if (is_discarded)
3240    return;
3241
3242  // A local STT_GNU_IFUNC symbol may require a PLT entry.
3243  bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
3244  if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type))
3245    {
3246      unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3247      target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
3248    }
3249
3250  switch (r_type)
3251    {
3252    case elfcpp::R_TILEGX_NONE:
3253    case elfcpp::R_TILEGX_GNU_VTINHERIT:
3254    case elfcpp::R_TILEGX_GNU_VTENTRY:
3255      break;
3256
3257    // If building a shared library (or a position-independent
3258    // executable), because the runtime address needs plus
3259    // the module base address, so generate a R_TILEGX_RELATIVE.
3260    case elfcpp::R_TILEGX_32:
3261    case elfcpp::R_TILEGX_64:
3262      if (parameters->options().output_is_position_independent())
3263        {
3264          unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3265          Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3266          rela_dyn->add_local_relative(object, r_sym,
3267                                       elfcpp::R_TILEGX_RELATIVE,
3268                                       output_section, data_shndx,
3269                                       reloc.get_r_offset(),
3270                                       reloc.get_r_addend(), is_ifunc);
3271        }
3272      break;
3273
3274    // If building a shared library (or a position-independent
3275    // executable), we need to create a dynamic relocation for this
3276    // location.
3277    case elfcpp::R_TILEGX_8:
3278    case elfcpp::R_TILEGX_16:
3279    case elfcpp::R_TILEGX_IMM16_X0_HW0:
3280    case elfcpp::R_TILEGX_IMM16_X1_HW0:
3281    case elfcpp::R_TILEGX_IMM16_X0_HW1:
3282    case elfcpp::R_TILEGX_IMM16_X1_HW1:
3283    case elfcpp::R_TILEGX_IMM16_X0_HW2:
3284    case elfcpp::R_TILEGX_IMM16_X1_HW2:
3285    case elfcpp::R_TILEGX_IMM16_X0_HW3:
3286    case elfcpp::R_TILEGX_IMM16_X1_HW3:
3287    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST:
3288    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST:
3289    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST:
3290    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST:
3291    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST:
3292    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST:
3293      if (parameters->options().output_is_position_independent())
3294        {
3295          this->check_non_pic(object, r_type);
3296
3297          Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3298          unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3299          if (lsym.get_st_type() != elfcpp::STT_SECTION)
3300            rela_dyn->add_local(object, r_sym, r_type, output_section,
3301                                data_shndx, reloc.get_r_offset(),
3302                                reloc.get_r_addend());
3303          else
3304            {
3305              gold_assert(lsym.get_st_value() == 0);
3306              rela_dyn->add_symbolless_local_addend(object, r_sym, r_type,
3307                                                    output_section,
3308                                                    data_shndx,
3309                                                    reloc.get_r_offset(),
3310                                                    reloc.get_r_addend());
3311
3312            }
3313        }
3314      break;
3315
3316    // R_TILEGX_JUMPOFF_X1_PLT against local symbol
3317    // may happen for ifunc case.
3318    case elfcpp::R_TILEGX_JUMPOFF_X1_PLT:
3319    case elfcpp::R_TILEGX_JUMPOFF_X1:
3320    case elfcpp::R_TILEGX_64_PCREL:
3321    case elfcpp::R_TILEGX_32_PCREL:
3322    case elfcpp::R_TILEGX_16_PCREL:
3323    case elfcpp::R_TILEGX_8_PCREL:
3324    case elfcpp::R_TILEGX_BROFF_X1:
3325    case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL:
3326    case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL:
3327    case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL:
3328    case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL:
3329    case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL:
3330    case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL:
3331    case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL:
3332    case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL:
3333    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
3334    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
3335    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
3336    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
3337    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
3338    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
3339    case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
3340    case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
3341    case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
3342    case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
3343    case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
3344    case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
3345    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
3346    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
3347    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
3348    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
3349    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
3350    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
3351      break;
3352
3353    case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT:
3354    case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT:
3355    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT:
3356    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT:
3357    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT:
3358    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT:
3359      {
3360        // The symbol requires a GOT entry.
3361        Output_data_got<size, big_endian>* got
3362           = target->got_section(symtab, layout);
3363        unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3364
3365        // For a STT_GNU_IFUNC symbol we want the PLT offset.  That
3366        // lets function pointers compare correctly with shared
3367        // libraries.  Otherwise we would need an IRELATIVE reloc.
3368        bool is_new;
3369        if (is_ifunc)
3370          is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
3371        else
3372          is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
3373        if (is_new)
3374          {
3375            // tilegx dynamic linker will not update local got entry,
3376            // so, if we are generating a shared object, we need to add a
3377            // dynamic relocation for this symbol's GOT entry to inform
3378            // dynamic linker plus the load base explicitly.
3379            if (parameters->options().output_is_position_independent())
3380              {
3381               unsigned int got_offset
3382                  = object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
3383
3384                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3385                rela_dyn->add_local_relative(object, r_sym,
3386                                             r_type,
3387                                             got, got_offset, 0, is_ifunc);
3388              }
3389          }
3390      }
3391      break;
3392
3393    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
3394    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
3395    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
3396    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
3397    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
3398    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
3399    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
3400    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
3401    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
3402    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
3403    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
3404    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
3405    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
3406    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
3407    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
3408    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
3409    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
3410    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
3411    case elfcpp::R_TILEGX_TLS_GD_CALL:
3412    case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
3413    case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
3414    case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
3415    case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
3416    case elfcpp::R_TILEGX_TLS_IE_LOAD:
3417    case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
3418    case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
3419    case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
3420    case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
3421      {
3422         bool output_is_shared = parameters->options().shared();
3423         const tls::Tls_optimization opt_t =
3424          Target_tilegx<size, big_endian>::optimize_tls_reloc(
3425            !output_is_shared, r_type);
3426
3427         switch (r_type)
3428           {
3429             case elfcpp::R_TILEGX_TLS_GD_CALL:
3430               // FIXME: predefine __tls_get_addr
3431               //
3432               // R_TILEGX_TLS_GD_CALL implicitly reference __tls_get_addr,
3433               // while all other target, x86/arm/mips/powerpc/sparc
3434               // generate tls relocation against __tls_get_addr explicitly,
3435               // so for TILEGX, we need the following hack.
3436               if (opt_t == tls::TLSOPT_NONE) {
3437                 if (!target->tls_get_addr_sym_defined_) {
3438                   Symbol* sym = NULL;
3439                   options::parse_set(NULL, "__tls_get_addr",
3440                                     (gold::options::String_set*)
3441                                     &parameters->options().undefined());
3442                   symtab->add_undefined_symbols_from_command_line(layout);
3443                   target->tls_get_addr_sym_defined_ = true;
3444                   sym = symtab->lookup("__tls_get_addr");
3445                   sym->set_in_reg();
3446                 }
3447                 target->make_plt_entry(symtab, layout,
3448                                        symtab->lookup("__tls_get_addr"));
3449               }
3450               break;
3451
3452             // only make effect when applying relocation
3453             case elfcpp::R_TILEGX_TLS_IE_LOAD:
3454             case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
3455             case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
3456             case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
3457             case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
3458             case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
3459             case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
3460             case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
3461             case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
3462               break;
3463
3464             // GD: requires two GOT entry for module index and offset
3465             // IE: requires one GOT entry for tp-relative offset
3466             // LE: shouldn't happen for global symbol
3467             case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
3468             case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
3469             case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
3470             case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
3471             case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
3472             case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
3473               {
3474                 if (opt_t == tls::TLSOPT_NONE) {
3475                   Output_data_got<size, big_endian> *got
3476                      = target->got_section(symtab, layout);
3477                   unsigned int r_sym
3478                      = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3479                   unsigned int shndx = lsym.get_st_shndx();
3480                   bool is_ordinary;
3481                   shndx = object->adjust_sym_shndx(r_sym, shndx,
3482                                                    &is_ordinary);
3483                   if (!is_ordinary)
3484                     object->error(_("local symbol %u has bad shndx %u"),
3485                                   r_sym, shndx);
3486                   else
3487                     got->add_local_pair_with_rel(object, r_sym, shndx,
3488                                           GOT_TYPE_TLS_PAIR,
3489                                           target->rela_dyn_section(layout),
3490                                           size == 32
3491                                           ? elfcpp::R_TILEGX_TLS_DTPMOD32
3492                                           : elfcpp::R_TILEGX_TLS_DTPMOD64);
3493                  } else if (opt_t == tls::TLSOPT_TO_IE) {
3494                    Output_data_got<size, big_endian>* got
3495                       = target->got_section(symtab, layout);
3496                    Reloc_section* rela_dyn
3497                       = target->rela_dyn_section(layout);
3498                    unsigned int r_sym
3499                       = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3500                    unsigned int off = got->add_constant(0);
3501                    object->set_local_got_offset(r_sym,
3502                                                 GOT_TYPE_TLS_OFFSET,off);
3503                    rela_dyn->add_symbolless_local_addend(object, r_sym,
3504                                            size == 32
3505                                            ? elfcpp::R_TILEGX_TLS_TPOFF32
3506                                            : elfcpp::R_TILEGX_TLS_TPOFF64,
3507                                            got, off, 0);
3508                  } else if (opt_t != tls::TLSOPT_TO_LE)
3509                    // only TO_LE is allowed for local symbol
3510                    unsupported_reloc_local(object, r_type);
3511               }
3512               break;
3513
3514             // IE
3515             case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
3516             case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
3517             case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
3518             case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
3519             case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
3520             case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
3521               {
3522                 layout->set_has_static_tls();
3523                 if (opt_t == tls::TLSOPT_NONE) {
3524                   Output_data_got<size, big_endian>* got
3525                      = target->got_section(symtab, layout);
3526                   Reloc_section* rela_dyn
3527                      = target->rela_dyn_section(layout);
3528                   unsigned int r_sym
3529                      = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3530                   unsigned int off = got->add_constant(0);
3531                   object->set_local_got_offset(r_sym,
3532                                                GOT_TYPE_TLS_OFFSET, off);
3533                   rela_dyn->add_symbolless_local_addend(object, r_sym,
3534                                            size == 32
3535                                            ? elfcpp::R_TILEGX_TLS_TPOFF32
3536                                            : elfcpp::R_TILEGX_TLS_TPOFF64,
3537                                            got, off, 0);
3538                 } else if (opt_t != tls::TLSOPT_TO_LE)
3539                   unsupported_reloc_local(object, r_type);
3540               }
3541               break;
3542
3543             // LE
3544             case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
3545             case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
3546             case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
3547             case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
3548             case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
3549             case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
3550               layout->set_has_static_tls();
3551               if (parameters->options().shared()) {
3552                 // defer to dynamic linker
3553                 gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
3554                 unsigned int r_sym
3555                    = elfcpp::elf_r_sym<size>(reloc.get_r_info());
3556                 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3557                 rela_dyn->add_symbolless_local_addend(object, r_sym, r_type,
3558                                                  output_section, data_shndx,
3559                                                  reloc.get_r_offset(), 0);
3560               }
3561               break;
3562
3563             default:
3564               gold_unreachable();
3565           }
3566      }
3567      break;
3568
3569    case elfcpp::R_TILEGX_COPY:
3570    case elfcpp::R_TILEGX_GLOB_DAT:
3571    case elfcpp::R_TILEGX_JMP_SLOT:
3572    case elfcpp::R_TILEGX_RELATIVE:
3573      // These are outstanding tls relocs, which are unexpected when linking
3574    case elfcpp::R_TILEGX_TLS_TPOFF32:
3575    case elfcpp::R_TILEGX_TLS_TPOFF64:
3576    case elfcpp::R_TILEGX_TLS_DTPMOD32:
3577    case elfcpp::R_TILEGX_TLS_DTPMOD64:
3578    case elfcpp::R_TILEGX_TLS_DTPOFF32:
3579    case elfcpp::R_TILEGX_TLS_DTPOFF64:
3580      gold_error(_("%s: unexpected reloc %u in object file"),
3581                 object->name().c_str(), r_type);
3582      break;
3583
3584    default:
3585      gold_error(_("%s: unsupported reloc %u against local symbol"),
3586                 object->name().c_str(), r_type);
3587      break;
3588    }
3589}
3590
3591
3592// Report an unsupported relocation against a global symbol.
3593
3594template<int size, bool big_endian>
3595void
3596Target_tilegx<size, big_endian>::Scan::unsupported_reloc_global(
3597    Sized_relobj_file<size, big_endian>* object,
3598    unsigned int r_type,
3599    Symbol* gsym)
3600{
3601  gold_error(_("%s: unsupported reloc %u against global symbol %s"),
3602             object->name().c_str(), r_type, gsym->demangled_name().c_str());
3603}
3604
3605// Returns true if this relocation type could be that of a function pointer.
3606template<int size, bool big_endian>
3607inline bool
3608Target_tilegx<size, big_endian>::Scan::possible_function_pointer_reloc(
3609  unsigned int r_type)
3610{
3611  switch (r_type)
3612    {
3613      case elfcpp::R_TILEGX_IMM16_X0_HW0:
3614      case elfcpp::R_TILEGX_IMM16_X1_HW0:
3615      case elfcpp::R_TILEGX_IMM16_X0_HW1:
3616      case elfcpp::R_TILEGX_IMM16_X1_HW1:
3617      case elfcpp::R_TILEGX_IMM16_X0_HW2:
3618      case elfcpp::R_TILEGX_IMM16_X1_HW2:
3619      case elfcpp::R_TILEGX_IMM16_X0_HW3:
3620      case elfcpp::R_TILEGX_IMM16_X1_HW3:
3621      case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST:
3622      case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST:
3623      case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST:
3624      case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST:
3625      case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST:
3626      case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST:
3627      case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL:
3628      case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL:
3629      case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL:
3630      case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL:
3631      case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL:
3632      case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL:
3633      case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL:
3634      case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL:
3635      case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
3636      case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
3637      case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
3638      case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
3639      case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
3640      case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
3641      case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT:
3642      case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT:
3643      case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT:
3644      case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT:
3645      case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT:
3646      case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT:
3647      {
3648        return true;
3649      }
3650    }
3651  return false;
3652}
3653
3654// For safe ICF, scan a relocation for a local symbol to check if it
3655// corresponds to a function pointer being taken.  In that case mark
3656// the function whose pointer was taken as not foldable.
3657
3658template<int size, bool big_endian>
3659inline bool
3660Target_tilegx<size, big_endian>::Scan::local_reloc_may_be_function_pointer(
3661  Symbol_table* ,
3662  Layout* ,
3663  Target_tilegx<size, big_endian>* ,
3664  Sized_relobj_file<size, big_endian>* ,
3665  unsigned int ,
3666  Output_section* ,
3667  const elfcpp::Rela<size, big_endian>& ,
3668  unsigned int r_type,
3669  const elfcpp::Sym<size, big_endian>&)
3670{
3671  return possible_function_pointer_reloc(r_type);
3672}
3673
3674// For safe ICF, scan a relocation for a global symbol to check if it
3675// corresponds to a function pointer being taken.  In that case mark
3676// the function whose pointer was taken as not foldable.
3677
3678template<int size, bool big_endian>
3679inline bool
3680Target_tilegx<size, big_endian>::Scan::global_reloc_may_be_function_pointer(
3681  Symbol_table*,
3682  Layout* ,
3683  Target_tilegx<size, big_endian>* ,
3684  Sized_relobj_file<size, big_endian>* ,
3685  unsigned int ,
3686  Output_section* ,
3687  const elfcpp::Rela<size, big_endian>& ,
3688  unsigned int r_type,
3689  Symbol* gsym)
3690{
3691  // GOT is not a function.
3692  if (strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
3693    return false;
3694
3695  // When building a shared library, do not fold symbols whose visibility
3696  // is hidden, internal or protected.
3697  return ((parameters->options().shared()
3698           && (gsym->visibility() == elfcpp::STV_INTERNAL
3699               || gsym->visibility() == elfcpp::STV_PROTECTED
3700               || gsym->visibility() == elfcpp::STV_HIDDEN))
3701          || possible_function_pointer_reloc(r_type));
3702}
3703
3704// Scan a relocation for a global symbol.
3705
3706template<int size, bool big_endian>
3707inline void
3708Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab,
3709                            Layout* layout,
3710                            Target_tilegx<size, big_endian>* target,
3711                            Sized_relobj_file<size, big_endian>* object,
3712                            unsigned int data_shndx,
3713                            Output_section* output_section,
3714                            const elfcpp::Rela<size, big_endian>& reloc,
3715                            unsigned int r_type,
3716                            Symbol* gsym)
3717{
3718  // A reference to _GLOBAL_OFFSET_TABLE_ implies that we need a got
3719  // section.  We check here to avoid creating a dynamic reloc against
3720  // _GLOBAL_OFFSET_TABLE_.
3721  if (!target->has_got_section()
3722      && strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
3723    target->got_section(symtab, layout);
3724
3725  // A STT_GNU_IFUNC symbol may require a PLT entry.
3726  if (gsym->type() == elfcpp::STT_GNU_IFUNC
3727      && this->reloc_needs_plt_for_ifunc(object, r_type))
3728    target->make_plt_entry(symtab, layout, gsym);
3729
3730  switch (r_type)
3731    {
3732    case elfcpp::R_TILEGX_NONE:
3733    case elfcpp::R_TILEGX_GNU_VTINHERIT:
3734    case elfcpp::R_TILEGX_GNU_VTENTRY:
3735      break;
3736
3737    case elfcpp::R_TILEGX_DEST_IMM8_X1:
3738    case elfcpp::R_TILEGX_IMM16_X0_HW0:
3739    case elfcpp::R_TILEGX_IMM16_X1_HW0:
3740    case elfcpp::R_TILEGX_IMM16_X0_HW1:
3741    case elfcpp::R_TILEGX_IMM16_X1_HW1:
3742    case elfcpp::R_TILEGX_IMM16_X0_HW2:
3743    case elfcpp::R_TILEGX_IMM16_X1_HW2:
3744    case elfcpp::R_TILEGX_IMM16_X0_HW3:
3745    case elfcpp::R_TILEGX_IMM16_X1_HW3:
3746    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST:
3747    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST:
3748    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST:
3749    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST:
3750    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST:
3751    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST:
3752    case elfcpp::R_TILEGX_64:
3753    case elfcpp::R_TILEGX_32:
3754    case elfcpp::R_TILEGX_16:
3755    case elfcpp::R_TILEGX_8:
3756      {
3757        // Make a PLT entry if necessary.
3758        if (gsym->needs_plt_entry())
3759          {
3760            target->make_plt_entry(symtab, layout, gsym);
3761            // Since this is not a PC-relative relocation, we may be
3762            // taking the address of a function. In that case we need to
3763            // set the entry in the dynamic symbol table to the address of
3764            // the PLT entry.
3765            if (gsym->is_from_dynobj() && !parameters->options().shared())
3766              gsym->set_needs_dynsym_value();
3767          }
3768        // Make a dynamic relocation if necessary.
3769        if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
3770          {
3771	    if (!parameters->options().output_is_position_independent()
3772		&& gsym->may_need_copy_reloc())
3773              {
3774                target->copy_reloc(symtab, layout, object,
3775                                   data_shndx, output_section, gsym, reloc);
3776              }
3777            else if (((size == 64 && r_type == elfcpp::R_TILEGX_64)
3778                      || (size == 32 && r_type == elfcpp::R_TILEGX_32))
3779                     && gsym->type() == elfcpp::STT_GNU_IFUNC
3780                     && gsym->can_use_relative_reloc(false)
3781                     && !gsym->is_from_dynobj()
3782                     && !gsym->is_undefined()
3783                     && !gsym->is_preemptible())
3784              {
3785                // Use an IRELATIVE reloc for a locally defined
3786                // STT_GNU_IFUNC symbol.  This makes a function
3787                // address in a PIE executable match the address in a
3788                // shared library that it links against.
3789                Reloc_section* rela_dyn =
3790                  target->rela_irelative_section(layout);
3791                unsigned int r_type = elfcpp::R_TILEGX_IRELATIVE;
3792                rela_dyn->add_symbolless_global_addend(gsym, r_type,
3793                                                   output_section, object,
3794                                                   data_shndx,
3795                                                   reloc.get_r_offset(),
3796                                                   reloc.get_r_addend());
3797              } else if ((r_type == elfcpp::R_TILEGX_64
3798                          || r_type == elfcpp::R_TILEGX_32)
3799                         && gsym->can_use_relative_reloc(false))
3800              {
3801                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3802                rela_dyn->add_global_relative(gsym, elfcpp::R_TILEGX_RELATIVE,
3803                                              output_section, object,
3804                                              data_shndx,
3805                                              reloc.get_r_offset(),
3806                                              reloc.get_r_addend(), false);
3807              }
3808            else
3809              {
3810                this->check_non_pic(object, r_type);
3811                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3812                rela_dyn->add_global(gsym, r_type, output_section, object,
3813                                     data_shndx, reloc.get_r_offset(),
3814                                     reloc.get_r_addend());
3815              }
3816          }
3817      }
3818      break;
3819
3820    case elfcpp::R_TILEGX_BROFF_X1:
3821    case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL:
3822    case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL:
3823    case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL:
3824    case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL:
3825    case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL:
3826    case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL:
3827    case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL:
3828    case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL:
3829    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
3830    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
3831    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
3832    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
3833    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
3834    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
3835    case elfcpp::R_TILEGX_64_PCREL:
3836    case elfcpp::R_TILEGX_32_PCREL:
3837    case elfcpp::R_TILEGX_16_PCREL:
3838    case elfcpp::R_TILEGX_8_PCREL:
3839      {
3840        // Make a PLT entry if necessary.
3841        if (gsym->needs_plt_entry())
3842          target->make_plt_entry(symtab, layout, gsym);
3843        // Make a dynamic relocation if necessary.
3844        if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
3845          {
3846	    if (parameters->options().output_is_executable()
3847		&& gsym->may_need_copy_reloc())
3848              {
3849                target->copy_reloc(symtab, layout, object,
3850                                   data_shndx, output_section, gsym, reloc);
3851              }
3852            else
3853              {
3854                this->check_non_pic(object, r_type);
3855                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3856                rela_dyn->add_global(gsym, r_type, output_section, object,
3857                                     data_shndx, reloc.get_r_offset(),
3858                                     reloc.get_r_addend());
3859              }
3860          }
3861      }
3862      break;
3863
3864    case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT:
3865    case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT:
3866    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT:
3867    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT:
3868    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT:
3869    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT:
3870      {
3871        // The symbol requires a GOT entry.
3872        Output_data_got<size, big_endian>* got
3873           = target->got_section(symtab, layout);
3874        if (gsym->final_value_is_known())
3875          {
3876            // For a STT_GNU_IFUNC symbol we want the PLT address.
3877            if (gsym->type() == elfcpp::STT_GNU_IFUNC)
3878              got->add_global_plt(gsym, GOT_TYPE_STANDARD);
3879            else
3880              got->add_global(gsym, GOT_TYPE_STANDARD);
3881          }
3882        else
3883          {
3884            // If this symbol is not fully resolved, we need to add a
3885            // dynamic relocation for it.
3886            Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3887
3888            // Use a GLOB_DAT rather than a RELATIVE reloc if:
3889            //
3890            // 1) The symbol may be defined in some other module.
3891            //
3892            // 2) We are building a shared library and this is a
3893            // protected symbol; using GLOB_DAT means that the dynamic
3894            // linker can use the address of the PLT in the main
3895            // executable when appropriate so that function address
3896            // comparisons work.
3897            //
3898            // 3) This is a STT_GNU_IFUNC symbol in position dependent
3899            // code, again so that function address comparisons work.
3900            if (gsym->is_from_dynobj()
3901                || gsym->is_undefined()
3902                || gsym->is_preemptible()
3903                || (gsym->visibility() == elfcpp::STV_PROTECTED
3904                    && parameters->options().shared())
3905                || (gsym->type() == elfcpp::STT_GNU_IFUNC
3906                    && parameters->options().output_is_position_independent()))
3907              got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rela_dyn,
3908                                       elfcpp::R_TILEGX_GLOB_DAT);
3909            else
3910              {
3911                // For a STT_GNU_IFUNC symbol we want to write the PLT
3912                // offset into the GOT, so that function pointer
3913                // comparisons work correctly.
3914                bool is_new;
3915                if (gsym->type() != elfcpp::STT_GNU_IFUNC)
3916                  is_new = got->add_global(gsym, GOT_TYPE_STANDARD);
3917                else
3918                  {
3919                    is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD);
3920                    // Tell the dynamic linker to use the PLT address
3921                    // when resolving relocations.
3922                    if (gsym->is_from_dynobj()
3923                        && !parameters->options().shared())
3924                      gsym->set_needs_dynsym_value();
3925                  }
3926                if (is_new)
3927                  {
3928                    unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
3929                    rela_dyn->add_global_relative(gsym,
3930                                                  r_type,
3931                                                  got, got_off, 0, false);
3932                  }
3933              }
3934          }
3935      }
3936      break;
3937
3938    // a minor difference here for R_TILEGX_JUMPOFF_X1
3939    // between bfd linker and gold linker for gold, when
3940    // R_TILEGX_JUMPOFF_X1 against global symbol, we
3941    // turn it into JUMPOFF_X1_PLT, otherwise the distance
3942    // to the symbol function may overflow at runtime.
3943    case elfcpp::R_TILEGX_JUMPOFF_X1:
3944
3945    case elfcpp::R_TILEGX_JUMPOFF_X1_PLT:
3946    case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
3947    case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
3948    case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
3949    case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
3950    case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
3951    case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
3952    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
3953    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
3954    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
3955    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
3956    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
3957    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
3958      // If the symbol is fully resolved, this is just a PC32 reloc.
3959      // Otherwise we need a PLT entry.
3960      if (gsym->final_value_is_known())
3961        break;
3962      // If building a shared library, we can also skip the PLT entry
3963      // if the symbol is defined in the output file and is protected
3964      // or hidden.
3965      if (gsym->is_defined()
3966          && !gsym->is_from_dynobj()
3967          && !gsym->is_preemptible())
3968        break;
3969      target->make_plt_entry(symtab, layout, gsym);
3970      break;
3971
3972
3973    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
3974    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
3975    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
3976    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
3977    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
3978    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
3979    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
3980    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
3981    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
3982    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
3983    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
3984    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
3985    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
3986    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
3987    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
3988    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
3989    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
3990    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
3991    case elfcpp::R_TILEGX_TLS_GD_CALL:
3992    case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
3993    case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
3994    case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
3995    case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
3996    case elfcpp::R_TILEGX_TLS_IE_LOAD:
3997    case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
3998    case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
3999    case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
4000    case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
4001      {
4002         const bool is_final = gsym->final_value_is_known();
4003         const tls::Tls_optimization opt_t =
4004          Target_tilegx<size, big_endian>::optimize_tls_reloc(is_final,
4005                                                              r_type);
4006
4007         switch (r_type)
4008           {
4009              // only expand to plt against __tls_get_addr in GD model
4010              case elfcpp::R_TILEGX_TLS_GD_CALL:
4011                if (opt_t == tls::TLSOPT_NONE) {
4012                  // FIXME:  it's better '__tls_get_addr' referenced explictly
4013                  if (!target->tls_get_addr_sym_defined_) {
4014                    Symbol* sym = NULL;
4015                    options::parse_set(NULL, "__tls_get_addr",
4016                                       (gold::options::String_set*)
4017                                       &parameters->options().undefined());
4018                    symtab->add_undefined_symbols_from_command_line(layout);
4019                    target->tls_get_addr_sym_defined_ = true;
4020                    sym = symtab->lookup("__tls_get_addr");
4021                    sym->set_in_reg();
4022                  }
4023                  target->make_plt_entry(symtab, layout,
4024                                         symtab->lookup("__tls_get_addr"));
4025                }
4026                break;
4027
4028              // only make effect when applying relocation
4029              case elfcpp::R_TILEGX_TLS_IE_LOAD:
4030              case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
4031              case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
4032              case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
4033              case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
4034              case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
4035              case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
4036              case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
4037              case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
4038                break;
4039
4040              // GD: requires two GOT entry for module index and offset
4041              // IE: requires one GOT entry for tp-relative offset
4042              // LE: shouldn't happen for global symbol
4043              case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
4044              case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
4045              case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
4046              case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
4047              case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
4048              case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
4049                {
4050                  if (opt_t == tls::TLSOPT_NONE) {
4051                      Output_data_got<size, big_endian>* got
4052                        = target->got_section(symtab, layout);
4053                      got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
4054                                             target->rela_dyn_section(layout),
4055                                             size == 32
4056                                           ? elfcpp::R_TILEGX_TLS_DTPMOD32
4057                                           : elfcpp::R_TILEGX_TLS_DTPMOD64,
4058                                             size == 32
4059                                           ? elfcpp::R_TILEGX_TLS_DTPOFF32
4060                                           : elfcpp::R_TILEGX_TLS_DTPOFF64);
4061                  } else if (opt_t == tls::TLSOPT_TO_IE) {
4062                    // Create a GOT entry for the tp-relative offset.
4063                    Output_data_got<size, big_endian>* got
4064                       = target->got_section(symtab, layout);
4065                    got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
4066                                           target->rela_dyn_section(layout),
4067                                           size == 32
4068                                           ? elfcpp::R_TILEGX_TLS_TPOFF32
4069                                           : elfcpp::R_TILEGX_TLS_TPOFF64);
4070                  } else if (opt_t != tls::TLSOPT_TO_LE)
4071                    // exteranl symbol should not be optimized to TO_LE
4072                    unsupported_reloc_global(object, r_type, gsym);
4073                }
4074                break;
4075
4076              // IE
4077              case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
4078              case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
4079              case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
4080              case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
4081              case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
4082              case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
4083                {
4084                    layout->set_has_static_tls();
4085                  if (opt_t == tls::TLSOPT_NONE) {
4086                    // Create a GOT entry for the tp-relative offset.
4087                    Output_data_got<size, big_endian>* got
4088                       = target->got_section(symtab, layout);
4089                    got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
4090                                           target->rela_dyn_section(layout),
4091                                           size == 32
4092                                           ? elfcpp::R_TILEGX_TLS_TPOFF32
4093                                           : elfcpp::R_TILEGX_TLS_TPOFF64);
4094                  } else if (opt_t != tls::TLSOPT_TO_LE)
4095                    unsupported_reloc_global(object, r_type, gsym);
4096                }
4097                break;
4098
4099              // LE
4100              case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
4101              case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
4102              case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
4103              case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
4104              case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
4105              case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
4106                  layout->set_has_static_tls();
4107                if (parameters->options().shared()) {
4108                  // defer to dynamic linker
4109                  Reloc_section* rela_dyn = target->rela_dyn_section(layout);
4110                  rela_dyn->add_symbolless_global_addend(gsym, r_type,
4111                                                      output_section, object,
4112                                                      data_shndx,
4113                                                      reloc.get_r_offset(), 0);
4114                  }
4115                break;
4116
4117              default:
4118                gold_unreachable();
4119           }
4120      }
4121      break;
4122
4123    // below are outstanding relocs
4124    // should not existed in static linking stage
4125    case elfcpp::R_TILEGX_COPY:
4126    case elfcpp::R_TILEGX_GLOB_DAT:
4127    case elfcpp::R_TILEGX_JMP_SLOT:
4128    case elfcpp::R_TILEGX_RELATIVE:
4129    case elfcpp::R_TILEGX_TLS_TPOFF32:
4130    case elfcpp::R_TILEGX_TLS_TPOFF64:
4131    case elfcpp::R_TILEGX_TLS_DTPMOD32:
4132    case elfcpp::R_TILEGX_TLS_DTPMOD64:
4133    case elfcpp::R_TILEGX_TLS_DTPOFF32:
4134    case elfcpp::R_TILEGX_TLS_DTPOFF64:
4135      gold_error(_("%s: unexpected reloc %u in object file"),
4136                 object->name().c_str(), r_type);
4137      break;
4138
4139    default:
4140      gold_error(_("%s: unsupported reloc %u against global symbol %s"),
4141                 object->name().c_str(), r_type,
4142                 gsym->demangled_name().c_str());
4143      break;
4144    }
4145}
4146
4147template<int size, bool big_endian>
4148void
4149Target_tilegx<size, big_endian>::gc_process_relocs(Symbol_table* symtab,
4150                                  Layout* layout,
4151                                  Sized_relobj_file<size, big_endian>* object,
4152                                  unsigned int data_shndx,
4153                                  unsigned int sh_type,
4154                                  const unsigned char* prelocs,
4155                                  size_t reloc_count,
4156                                  Output_section* output_section,
4157                                  bool needs_special_offset_handling,
4158                                  size_t local_symbol_count,
4159                                  const unsigned char* plocal_symbols)
4160{
4161  typedef Target_tilegx<size, big_endian> Tilegx;
4162  typedef typename Target_tilegx<size, big_endian>::Scan Scan;
4163  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
4164      Classify_reloc;
4165
4166  if (sh_type == elfcpp::SHT_REL)
4167    {
4168      return;
4169    }
4170
4171   gold::gc_process_relocs<size, big_endian, Tilegx, Scan, Classify_reloc>(
4172     symtab,
4173     layout,
4174     this,
4175     object,
4176     data_shndx,
4177     prelocs,
4178     reloc_count,
4179     output_section,
4180     needs_special_offset_handling,
4181     local_symbol_count,
4182     plocal_symbols);
4183}
4184// Scan relocations for a section.
4185
4186template<int size, bool big_endian>
4187void
4188Target_tilegx<size, big_endian>::scan_relocs(Symbol_table* symtab,
4189                                 Layout* layout,
4190                                 Sized_relobj_file<size, big_endian>* object,
4191                                 unsigned int data_shndx,
4192                                 unsigned int sh_type,
4193                                 const unsigned char* prelocs,
4194                                 size_t reloc_count,
4195                                 Output_section* output_section,
4196                                 bool needs_special_offset_handling,
4197                                 size_t local_symbol_count,
4198                                 const unsigned char* plocal_symbols)
4199{
4200  typedef Target_tilegx<size, big_endian> Tilegx;
4201  typedef typename Target_tilegx<size, big_endian>::Scan Scan;
4202  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
4203      Classify_reloc;
4204
4205  if (sh_type == elfcpp::SHT_REL)
4206    {
4207      gold_error(_("%s: unsupported REL reloc section"),
4208                 object->name().c_str());
4209      return;
4210    }
4211
4212  gold::scan_relocs<size, big_endian, Tilegx, Scan, Classify_reloc>(
4213    symtab,
4214    layout,
4215    this,
4216    object,
4217    data_shndx,
4218    prelocs,
4219    reloc_count,
4220    output_section,
4221    needs_special_offset_handling,
4222    local_symbol_count,
4223    plocal_symbols);
4224}
4225
4226template<int size, bool big_endian>
4227void
4228Target_tilegx<size, big_endian>::do_define_standard_symbols(
4229    Symbol_table* symtab,
4230    Layout* layout)
4231{
4232  Output_section* feedback_section = layout->find_output_section(".feedback");
4233
4234  if (feedback_section != NULL)
4235    {
4236      symtab->define_in_output_data("__feedback_section_end",
4237                    NULL,
4238                    Symbol_table::PREDEFINED,
4239                    feedback_section,
4240                    0,
4241                    0,
4242                    elfcpp::STT_NOTYPE,
4243                    elfcpp::STB_GLOBAL,
4244                    elfcpp::STV_HIDDEN,
4245                    0,
4246                    true, // offset_is_from_end
4247                    false);
4248    }
4249}
4250
4251// Finalize the sections.
4252
4253template<int size, bool big_endian>
4254void
4255Target_tilegx<size, big_endian>::do_finalize_sections(
4256    Layout* layout,
4257    const Input_objects*,
4258    Symbol_table* symtab)
4259{
4260  const Reloc_section* rel_plt = (this->plt_ == NULL
4261                                  ? NULL
4262                                  : this->plt_->rela_plt());
4263  layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
4264                                  this->rela_dyn_, true, true);
4265
4266  // Emit any relocs we saved in an attempt to avoid generating COPY
4267  // relocs.
4268  if (this->copy_relocs_.any_saved_relocs())
4269    this->copy_relocs_.emit(this->rela_dyn_section(layout));
4270
4271  // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
4272  // the .got section.
4273  Symbol* sym = this->global_offset_table_;
4274  if (sym != NULL)
4275    {
4276      uint64_t data_size = this->got_->current_data_size();
4277      symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
4278
4279      // If the .got section is more than 0x8000 bytes, we add
4280      // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
4281      // bit relocations have a greater chance of working.
4282      if (data_size >= 0x8000)
4283        symtab->get_sized_symbol<size>(sym)->set_value(
4284          symtab->get_sized_symbol<size>(sym)->value() + 0x8000);
4285    }
4286
4287  if (parameters->doing_static_link()
4288      && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
4289    {
4290      // If linking statically, make sure that the __rela_iplt symbols
4291      // were defined if necessary, even if we didn't create a PLT.
4292      static const Define_symbol_in_segment syms[] =
4293        {
4294          {
4295            "__rela_iplt_start",        // name
4296            elfcpp::PT_LOAD,            // segment_type
4297            elfcpp::PF_W,               // segment_flags_set
4298            elfcpp::PF(0),              // segment_flags_clear
4299            0,                          // value
4300            0,                          // size
4301            elfcpp::STT_NOTYPE,         // type
4302            elfcpp::STB_GLOBAL,         // binding
4303            elfcpp::STV_HIDDEN,         // visibility
4304            0,                          // nonvis
4305            Symbol::SEGMENT_START,      // offset_from_base
4306            true                        // only_if_ref
4307          },
4308          {
4309            "__rela_iplt_end",          // name
4310            elfcpp::PT_LOAD,            // segment_type
4311            elfcpp::PF_W,               // segment_flags_set
4312            elfcpp::PF(0),              // segment_flags_clear
4313            0,                          // value
4314            0,                          // size
4315            elfcpp::STT_NOTYPE,         // type
4316            elfcpp::STB_GLOBAL,         // binding
4317            elfcpp::STV_HIDDEN,         // visibility
4318            0,                          // nonvis
4319            Symbol::SEGMENT_START,      // offset_from_base
4320            true                        // only_if_ref
4321          }
4322        };
4323
4324      symtab->define_symbols(layout, 2, syms,
4325                             layout->script_options()->saw_sections_clause());
4326    }
4327}
4328
4329// Perform a relocation.
4330
4331template<int size, bool big_endian>
4332inline bool
4333Target_tilegx<size, big_endian>::Relocate::relocate(
4334    const Relocate_info<size, big_endian>* relinfo,
4335    unsigned int,
4336    Target_tilegx<size, big_endian>* target,
4337    Output_section*,
4338    size_t relnum,
4339    const unsigned char* preloc,
4340    const Sized_symbol<size>* gsym,
4341    const Symbol_value<size>* psymval,
4342    unsigned char* view,
4343    typename elfcpp::Elf_types<size>::Elf_Addr address,
4344    section_size_type)
4345{
4346  if (view == NULL)
4347    return true;
4348
4349  typedef Tilegx_relocate_functions<size, big_endian> TilegxReloc;
4350  typename TilegxReloc::Tilegx_howto r_howto;
4351
4352  const elfcpp::Rela<size, big_endian> rela(preloc);
4353  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
4354  const Sized_relobj_file<size, big_endian>* object = relinfo->object;
4355
4356  // Pick the value to use for symbols defined in the PLT.
4357  Symbol_value<size> symval;
4358  if (gsym != NULL
4359      && gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
4360    {
4361      symval.set_output_value(target->plt_address_for_global(gsym));
4362      psymval = &symval;
4363    }
4364  else if (gsym == NULL && psymval->is_ifunc_symbol())
4365    {
4366      unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
4367      if (object->local_has_plt_offset(r_sym))
4368        {
4369          symval.set_output_value(target->plt_address_for_local(object, r_sym));
4370          psymval = &symval;
4371        }
4372    }
4373
4374  elfcpp::Elf_Xword addend = rela.get_r_addend();
4375
4376  // Get the GOT offset if needed.
4377  // For tilegx, the GOT pointer points to the start of the GOT section.
4378  bool have_got_offset = false;
4379  int got_offset = 0;
4380  int got_base = target->got_ != NULL
4381                 ? target->got_->current_data_size() >= 0x8000 ? 0x8000 : 0
4382                 : 0;
4383  unsigned int got_type = GOT_TYPE_STANDARD;
4384  bool always_apply_relocation = false;
4385  switch (r_type)
4386    {
4387    case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT:
4388    case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT:
4389    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT:
4390    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT:
4391    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT:
4392    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT:
4393      if (gsym != NULL)
4394        {
4395          gold_assert(gsym->has_got_offset(got_type));
4396          got_offset = gsym->got_offset(got_type) - got_base;
4397        }
4398      else
4399        {
4400          unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
4401          gold_assert(object->local_has_got_offset(r_sym, got_type));
4402          got_offset =
4403            object->local_got_offset(r_sym, got_type) - got_base;
4404        }
4405      have_got_offset = true;
4406      break;
4407
4408    default:
4409      break;
4410    }
4411
4412  r_howto = TilegxReloc::howto[r_type];
4413  switch (r_type)
4414    {
4415    case elfcpp::R_TILEGX_NONE:
4416    case elfcpp::R_TILEGX_GNU_VTINHERIT:
4417    case elfcpp::R_TILEGX_GNU_VTENTRY:
4418      break;
4419
4420    case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT:
4421    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT:
4422    case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT:
4423    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT:
4424    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT:
4425    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT:
4426      gold_assert(have_got_offset);
4427      symval.set_output_value(got_offset);
4428      psymval = &symval;
4429      always_apply_relocation = true;
4430      addend = 0;
4431      // Fall through.
4432
4433    // when under PIC mode, these relocations are deferred to rtld
4434    case elfcpp::R_TILEGX_IMM16_X0_HW0:
4435    case elfcpp::R_TILEGX_IMM16_X1_HW0:
4436    case elfcpp::R_TILEGX_IMM16_X0_HW1:
4437    case elfcpp::R_TILEGX_IMM16_X1_HW1:
4438    case elfcpp::R_TILEGX_IMM16_X0_HW2:
4439    case elfcpp::R_TILEGX_IMM16_X1_HW2:
4440    case elfcpp::R_TILEGX_IMM16_X0_HW3:
4441    case elfcpp::R_TILEGX_IMM16_X1_HW3:
4442    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST:
4443    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST:
4444    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST:
4445    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST:
4446    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST:
4447    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST:
4448      if (always_apply_relocation
4449          || !parameters->options().output_is_position_independent())
4450        TilegxReloc::imm_x_general(view, object, psymval, addend, r_howto);
4451      break;
4452
4453    case elfcpp::R_TILEGX_JUMPOFF_X1:
4454    case elfcpp::R_TILEGX_JUMPOFF_X1_PLT:
4455      gold_assert(gsym == NULL
4456                  || gsym->has_plt_offset()
4457                  || gsym->final_value_is_known()
4458                  || (gsym->is_defined()
4459                      && !gsym->is_from_dynobj()
4460                      && !gsym->is_preemptible()));
4461      TilegxReloc::imm_x_pcrel_general(view, object, psymval, addend,
4462                                       address, r_howto);
4463      break;
4464
4465
4466    case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
4467    case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL:
4468    case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
4469    case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL:
4470    case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
4471    case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL:
4472    case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
4473    case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL:
4474    case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
4475    case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL:
4476    case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
4477    case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL:
4478    case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL:
4479    case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL:
4480    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
4481    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
4482    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
4483    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
4484    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
4485    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
4486    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
4487    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
4488    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
4489    case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
4490    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
4491    case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
4492      TilegxReloc::imm_x_pcrel_general(view, object, psymval, addend,
4493                                       address, r_howto);
4494      break;
4495
4496    case elfcpp::R_TILEGX_BROFF_X1:
4497    case elfcpp::R_TILEGX_DEST_IMM8_X1:
4498      TilegxReloc::imm_x_two_part_general(view, object, psymval,
4499                                          addend, address, r_type);
4500      break;
4501
4502
4503    // below are general relocation types, which can be
4504    // handled by target-independent handlers
4505    case elfcpp::R_TILEGX_64:
4506      TilegxReloc::abs64(view, object, psymval, addend);
4507      break;
4508
4509    case elfcpp::R_TILEGX_64_PCREL:
4510      TilegxReloc::pc_abs64(view, object, psymval, addend, address);
4511      break;
4512
4513    case elfcpp::R_TILEGX_32:
4514      TilegxReloc::abs32(view, object, psymval, addend);
4515      break;
4516
4517    case elfcpp::R_TILEGX_32_PCREL:
4518      TilegxReloc::pc_abs32(view, object, psymval, addend, address);
4519      break;
4520
4521    case elfcpp::R_TILEGX_16:
4522      TilegxReloc::abs16(view, object, psymval, addend);
4523      break;
4524
4525    case elfcpp::R_TILEGX_16_PCREL:
4526      TilegxReloc::pc_abs16(view, object, psymval, addend, address);
4527      break;
4528
4529    case elfcpp::R_TILEGX_8:
4530      Relocate_functions<size, big_endian>::rela8(view, object,
4531                                                  psymval, addend);
4532      break;
4533
4534    case elfcpp::R_TILEGX_8_PCREL:
4535      Relocate_functions<size, big_endian>::pcrela8(view, object,
4536                                                    psymval, addend, address);
4537      break;
4538
4539    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
4540    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
4541    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
4542    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
4543    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
4544    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
4545    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
4546    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
4547    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
4548    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
4549    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
4550    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
4551    case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
4552    case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
4553    case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
4554    case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
4555    case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
4556    case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
4557    case elfcpp::R_TILEGX_TLS_GD_CALL:
4558    case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
4559    case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
4560    case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
4561    case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
4562    case elfcpp::R_TILEGX_TLS_IE_LOAD:
4563    case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
4564    case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
4565    case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
4566    case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
4567      {
4568        const bool is_final = (gsym == NULL
4569                               ? !parameters->options().shared()
4570                               : gsym->final_value_is_known());
4571        tls::Tls_optimization opt_t =
4572          Target_tilegx<size, big_endian>::optimize_tls_reloc(is_final,
4573                                                              r_type);
4574
4575        switch (r_type)
4576          {
4577
4578            case elfcpp::R_TILEGX_TLS_GD_CALL:
4579              {
4580                if (opt_t == tls::TLSOPT_NONE) {
4581                  Symbol *tls_sym = relinfo->symtab->lookup("__tls_get_addr");
4582                  symval.set_output_value(
4583                    target->plt_address_for_global(tls_sym));
4584                  psymval = &symval;
4585                  TilegxReloc::imm_x_pcrel_general(view, object, psymval,
4586                                                   addend, address, r_howto);
4587                }
4588                else if (opt_t == tls::TLSOPT_TO_IE
4589                         || opt_t == tls::TLSOPT_TO_LE)
4590                  TilegxReloc::tls_relax(view, r_type, opt_t);
4591              }
4592              break;
4593
4594            // XX_TLS_GD is the same as normal X_GOT relocation
4595            // except allocating a got entry pair,
4596            case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
4597            case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
4598            case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
4599            case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
4600            case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
4601            case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
4602              if (opt_t == tls::TLSOPT_NONE) {
4603                got_type = GOT_TYPE_TLS_PAIR;
4604                have_got_offset = true;
4605              } else if (opt_t == tls::TLSOPT_TO_IE) {
4606                got_type = GOT_TYPE_TLS_OFFSET;
4607                have_got_offset = true;
4608              }
4609              goto do_update_value;
4610            // XX_TLS_IE is the same as normal X_GOT relocation
4611            // except allocating one additional runtime relocation
4612            case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
4613            case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
4614            case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
4615            case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
4616            case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
4617            case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
4618              if (opt_t == tls::TLSOPT_NONE) {
4619                got_type = GOT_TYPE_TLS_OFFSET;
4620                have_got_offset = true;
4621              }
4622	      // Fall through.
4623            do_update_value:
4624              if (have_got_offset) {
4625                if (gsym != NULL) {
4626                  gold_assert(gsym->has_got_offset(got_type));
4627                  got_offset = gsym->got_offset(got_type) - got_base;
4628                } else {
4629                  unsigned int r_sym
4630                     = elfcpp::elf_r_sym<size>(rela.get_r_info());
4631                  gold_assert(object->local_has_got_offset(r_sym, got_type));
4632                  got_offset =
4633                    object->local_got_offset(r_sym, got_type) - got_base;
4634                }
4635              }
4636
4637              if (opt_t == tls::TLSOPT_NONE
4638                  || opt_t == tls::TLSOPT_TO_IE) {
4639                // for both GD/IE, these relocations
4640                // actually calculate got offset, so
4641                // there behavior are the same
4642                gold_assert(have_got_offset);
4643                symval.set_output_value(got_offset);
4644                psymval = &symval;
4645                addend = 0;
4646                TilegxReloc::imm_x_general(view, object, psymval,
4647                                           addend, r_howto);
4648                break;
4649              } // else if (opt_t == tls::TLSOPT_TO_LE)
4650                //   both GD/IE are turned into LE, which
4651                //   is absolute relocation.
4652                // Fall through.
4653
4654            // LE
4655            //
4656            // tp
4657            // |
4658            // V
4659            //  t_var1 | t_var2 | t_var3 | ...
4660            //  --------------------------------------------------
4661            //
4662            //  so offset to tp should be negative, we get offset
4663            //  from the following formular for LE
4664            //
4665            //    t_var1_off = t_var1_sym_value - tls_section_start
4666            //
4667            case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
4668            case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
4669            case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
4670            case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
4671            case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
4672            case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
4673              {
4674                Output_segment *tls_segment = relinfo->layout->tls_segment();
4675                if (tls_segment == NULL) {
4676                  gold_assert(parameters->errors()->error_count() > 0
4677                              || issue_undefined_symbol_error(gsym));
4678                  return false;
4679                }
4680
4681                typename elfcpp::Elf_types<size>::Elf_Addr value
4682                  = psymval->value(relinfo->object, 0);
4683                symval.set_output_value(value);
4684                psymval = &symval;
4685                TilegxReloc::imm_x_general(view, object, psymval,
4686                                           addend, r_howto);
4687              }
4688              break;
4689
4690            // tls relaxation
4691            case elfcpp::R_TILEGX_TLS_IE_LOAD:
4692            case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
4693            case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD:
4694            case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD:
4695            case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD:
4696            case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
4697            case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD:
4698            case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
4699            case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
4700              TilegxReloc::tls_relax(view, r_type, opt_t);
4701              break;
4702
4703            default:
4704              gold_unreachable();
4705          }
4706      }
4707      break;
4708
4709    // below are outstanding relocs
4710    // should not existed in static linking stage
4711    case elfcpp::R_TILEGX_COPY:
4712    case elfcpp::R_TILEGX_GLOB_DAT:
4713    case elfcpp::R_TILEGX_JMP_SLOT:
4714    case elfcpp::R_TILEGX_RELATIVE:
4715    case elfcpp::R_TILEGX_TLS_TPOFF32:
4716    case elfcpp::R_TILEGX_TLS_TPOFF64:
4717    case elfcpp::R_TILEGX_TLS_DTPMOD32:
4718    case elfcpp::R_TILEGX_TLS_DTPMOD64:
4719    case elfcpp::R_TILEGX_TLS_DTPOFF32:
4720    case elfcpp::R_TILEGX_TLS_DTPOFF64:
4721      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
4722                             _("unexpected reloc %u in object file"),
4723                             r_type);
4724      break;
4725
4726    default:
4727      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
4728                             _("unsupported reloc %u"),
4729                             r_type);
4730      break;
4731    }
4732
4733  return true;
4734}
4735
4736// Relocate section data.
4737
4738template<int size, bool big_endian>
4739void
4740Target_tilegx<size, big_endian>::relocate_section(
4741    const Relocate_info<size, big_endian>* relinfo,
4742    unsigned int sh_type,
4743    const unsigned char* prelocs,
4744    size_t reloc_count,
4745    Output_section* output_section,
4746    bool needs_special_offset_handling,
4747    unsigned char* view,
4748    typename elfcpp::Elf_types<size>::Elf_Addr address,
4749    section_size_type view_size,
4750    const Reloc_symbol_changes* reloc_symbol_changes)
4751{
4752  typedef Target_tilegx<size, big_endian> Tilegx;
4753  typedef typename Target_tilegx<size, big_endian>::Relocate Tilegx_relocate;
4754  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
4755      Classify_reloc;
4756
4757  gold_assert(sh_type == elfcpp::SHT_RELA);
4758
4759  gold::relocate_section<size, big_endian, Tilegx, Tilegx_relocate,
4760			 gold::Default_comdat_behavior, Classify_reloc>(
4761    relinfo,
4762    this,
4763    prelocs,
4764    reloc_count,
4765    output_section,
4766    needs_special_offset_handling,
4767    view,
4768    address,
4769    view_size,
4770    reloc_symbol_changes);
4771}
4772
4773// Apply an incremental relocation.  Incremental relocations always refer
4774// to global symbols.
4775
4776template<int size, bool big_endian>
4777void
4778Target_tilegx<size, big_endian>::apply_relocation(
4779    const Relocate_info<size, big_endian>* relinfo,
4780    typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
4781    unsigned int r_type,
4782    typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
4783    const Symbol* gsym,
4784    unsigned char* view,
4785    typename elfcpp::Elf_types<size>::Elf_Addr address,
4786    section_size_type view_size)
4787{
4788  gold::apply_relocation<size, big_endian, Target_tilegx<size, big_endian>,
4789                         typename Target_tilegx<size, big_endian>::Relocate>(
4790    relinfo,
4791    this,
4792    r_offset,
4793    r_type,
4794    r_addend,
4795    gsym,
4796    view,
4797    address,
4798    view_size);
4799}
4800
4801// Scan the relocs during a relocatable link.
4802
4803template<int size, bool big_endian>
4804void
4805Target_tilegx<size, big_endian>::scan_relocatable_relocs(
4806    Symbol_table* symtab,
4807    Layout* layout,
4808    Sized_relobj_file<size, big_endian>* object,
4809    unsigned int data_shndx,
4810    unsigned int sh_type,
4811    const unsigned char* prelocs,
4812    size_t reloc_count,
4813    Output_section* output_section,
4814    bool needs_special_offset_handling,
4815    size_t local_symbol_count,
4816    const unsigned char* plocal_symbols,
4817    Relocatable_relocs* rr)
4818{
4819  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
4820      Classify_reloc;
4821  typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
4822      Scan_relocatable_relocs;
4823
4824  gold_assert(sh_type == elfcpp::SHT_RELA);
4825
4826  gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>(
4827    symtab,
4828    layout,
4829    object,
4830    data_shndx,
4831    prelocs,
4832    reloc_count,
4833    output_section,
4834    needs_special_offset_handling,
4835    local_symbol_count,
4836    plocal_symbols,
4837    rr);
4838}
4839
4840// Scan the relocs for --emit-relocs.
4841
4842template<int size, bool big_endian>
4843void
4844Target_tilegx<size, big_endian>::emit_relocs_scan(
4845    Symbol_table* symtab,
4846    Layout* layout,
4847    Sized_relobj_file<size, big_endian>* object,
4848    unsigned int data_shndx,
4849    unsigned int sh_type,
4850    const unsigned char* prelocs,
4851    size_t reloc_count,
4852    Output_section* output_section,
4853    bool needs_special_offset_handling,
4854    size_t local_symbol_count,
4855    const unsigned char* plocal_syms,
4856    Relocatable_relocs* rr)
4857{
4858  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
4859      Classify_reloc;
4860  typedef gold::Default_emit_relocs_strategy<Classify_reloc>
4861      Emit_relocs_strategy;
4862
4863  gold_assert(sh_type == elfcpp::SHT_RELA);
4864
4865  gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>(
4866    symtab,
4867    layout,
4868    object,
4869    data_shndx,
4870    prelocs,
4871    reloc_count,
4872    output_section,
4873    needs_special_offset_handling,
4874    local_symbol_count,
4875    plocal_syms,
4876    rr);
4877}
4878
4879// Relocate a section during a relocatable link.
4880
4881template<int size, bool big_endian>
4882void
4883Target_tilegx<size, big_endian>::relocate_relocs(
4884    const Relocate_info<size, big_endian>* relinfo,
4885    unsigned int sh_type,
4886    const unsigned char* prelocs,
4887    size_t reloc_count,
4888    Output_section* output_section,
4889    typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
4890    unsigned char* view,
4891    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
4892    section_size_type view_size,
4893    unsigned char* reloc_view,
4894    section_size_type reloc_view_size)
4895{
4896  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
4897      Classify_reloc;
4898
4899  gold_assert(sh_type == elfcpp::SHT_RELA);
4900
4901  gold::relocate_relocs<size, big_endian, Classify_reloc>(
4902    relinfo,
4903    prelocs,
4904    reloc_count,
4905    output_section,
4906    offset_in_output_section,
4907    view,
4908    view_address,
4909    view_size,
4910    reloc_view,
4911    reloc_view_size);
4912}
4913
4914// Return the value to use for a dynamic which requires special
4915// treatment.  This is how we support equality comparisons of function
4916// pointers across shared library boundaries, as described in the
4917// processor specific ABI supplement.
4918
4919template<int size, bool big_endian>
4920uint64_t
4921Target_tilegx<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
4922{
4923  gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
4924  return this->plt_address_for_global(gsym);
4925}
4926
4927// Return the value to use for the base of a DW_EH_PE_datarel offset
4928// in an FDE.  Solaris and SVR4 use DW_EH_PE_datarel because their
4929// assembler can not write out the difference between two labels in
4930// different sections, so instead of using a pc-relative value they
4931// use an offset from the GOT.
4932
4933template<int size, bool big_endian>
4934uint64_t
4935Target_tilegx<size, big_endian>::do_ehframe_datarel_base() const
4936{
4937  gold_assert(this->global_offset_table_ != NULL);
4938  Symbol* sym = this->global_offset_table_;
4939  Sized_symbol<size>* ssym = static_cast<Sized_symbol<size>*>(sym);
4940  return ssym->value();
4941}
4942
4943// The selector for tilegx object files.
4944
4945template<int size, bool big_endian>
4946class Target_selector_tilegx : public Target_selector
4947{
4948public:
4949  Target_selector_tilegx()
4950    : Target_selector(elfcpp::EM_TILEGX, size, big_endian,
4951                      (size == 64
4952                       ? (big_endian ? "elf64-tilegx-be" : "elf64-tilegx-le")
4953                          : (big_endian ? "elf32-tilegx-be"
4954                                           : "elf32-tilegx-le")),
4955                      (size == 64
4956                       ? (big_endian ? "elf64tilegx_be" : "elf64tilegx")
4957                          : (big_endian ? "elf32tilegx_be" : "elf32tilegx")))
4958  { }
4959
4960  Target*
4961  do_instantiate_target()
4962  { return new Target_tilegx<size, big_endian>(); }
4963
4964};
4965
4966Target_selector_tilegx<64, false> target_selector_tilegx64_le;
4967Target_selector_tilegx<32, false> target_selector_tilegx32_le;
4968Target_selector_tilegx<64, true> target_selector_tilegx64_be;
4969Target_selector_tilegx<32, true> target_selector_tilegx32_be;
4970} // End anonymous namespace.
4971