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