OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gold/] [powerpc.cc] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
// powerpc.cc -- powerpc target support for gold.
2
 
3
// Copyright 2008, 2009 Free Software Foundation, Inc.
4
// Written by David S. Miller <davem@davemloft.net>
5
//        and David Edelsohn <edelsohn@gnu.org>
6
 
7
// This file is part of gold.
8
 
9
// This program is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation; either version 3 of the License, or
12
// (at your option) any later version.
13
 
14
// This program is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
// GNU General Public License for more details.
18
 
19
// You should have received a copy of the GNU General Public License
20
// along with this program; if not, write to the Free Software
21
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
// MA 02110-1301, USA.
23
 
24
#include "gold.h"
25
 
26
#include "elfcpp.h"
27
#include "parameters.h"
28
#include "reloc.h"
29
#include "powerpc.h"
30
#include "object.h"
31
#include "symtab.h"
32
#include "layout.h"
33
#include "output.h"
34
#include "copy-relocs.h"
35
#include "target.h"
36
#include "target-reloc.h"
37
#include "target-select.h"
38
#include "tls.h"
39
#include "errors.h"
40
#include "gc.h"
41
 
42
namespace
43
{
44
 
45
using namespace gold;
46
 
47
template<int size, bool big_endian>
48
class Output_data_plt_powerpc;
49
 
50
template<int size, bool big_endian>
51
class Target_powerpc : public Sized_target<size, big_endian>
52
{
53
 public:
54
  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Reloc_section;
55
 
56
  Target_powerpc()
57
    : Sized_target<size, big_endian>(&powerpc_info),
58
      got_(NULL), got2_(NULL), toc_(NULL),
59
      plt_(NULL), rela_dyn_(NULL),
60
      copy_relocs_(elfcpp::R_POWERPC_COPY),
61
      dynbss_(NULL), got_mod_index_offset_(-1U)
62
  {
63
  }
64
 
65
  // Process the relocations to determine unreferenced sections for 
66
  // garbage collection.
67
  void
68
  gc_process_relocs(const General_options& options,
69
                    Symbol_table* symtab,
70
                    Layout* layout,
71
                    Sized_relobj<size, big_endian>* object,
72
                    unsigned int data_shndx,
73
                    unsigned int sh_type,
74
                    const unsigned char* prelocs,
75
                    size_t reloc_count,
76
                    Output_section* output_section,
77
                    bool needs_special_offset_handling,
78
                    size_t local_symbol_count,
79
                    const unsigned char* plocal_symbols);
80
 
81
  // Scan the relocations to look for symbol adjustments.
82
  void
83
  scan_relocs(const General_options& options,
84
              Symbol_table* symtab,
85
              Layout* layout,
86
              Sized_relobj<size, big_endian>* object,
87
              unsigned int data_shndx,
88
              unsigned int sh_type,
89
              const unsigned char* prelocs,
90
              size_t reloc_count,
91
              Output_section* output_section,
92
              bool needs_special_offset_handling,
93
              size_t local_symbol_count,
94
              const unsigned char* plocal_symbols);
95
  // Finalize the sections.
96
  void
97
  do_finalize_sections(Layout*);
98
 
99
  // Return the value to use for a dynamic which requires special
100
  // treatment.
101
  uint64_t
102
  do_dynsym_value(const Symbol*) const;
103
 
104
  // Relocate a section.
105
  void
106
  relocate_section(const Relocate_info<size, big_endian>*,
107
                   unsigned int sh_type,
108
                   const unsigned char* prelocs,
109
                   size_t reloc_count,
110
                   Output_section* output_section,
111
                   bool needs_special_offset_handling,
112
                   unsigned char* view,
113
                   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
114
                   section_size_type view_size,
115
                   const Reloc_symbol_changes*);
116
 
117
  // Scan the relocs during a relocatable link.
118
  void
119
  scan_relocatable_relocs(const General_options& options,
120
                          Symbol_table* symtab,
121
                          Layout* layout,
122
                          Sized_relobj<size, big_endian>* object,
123
                          unsigned int data_shndx,
124
                          unsigned int sh_type,
125
                          const unsigned char* prelocs,
126
                          size_t reloc_count,
127
                          Output_section* output_section,
128
                          bool needs_special_offset_handling,
129
                          size_t local_symbol_count,
130
                          const unsigned char* plocal_symbols,
131
                          Relocatable_relocs*);
132
 
133
  // Relocate a section during a relocatable link.
134
  void
135
  relocate_for_relocatable(const Relocate_info<size, big_endian>*,
136
                           unsigned int sh_type,
137
                           const unsigned char* prelocs,
138
                           size_t reloc_count,
139
                           Output_section* output_section,
140
                           off_t offset_in_output_section,
141
                           const Relocatable_relocs*,
142
                           unsigned char* view,
143
                           typename elfcpp::Elf_types<size>::Elf_Addr view_address,
144
                           section_size_type view_size,
145
                           unsigned char* reloc_view,
146
                           section_size_type reloc_view_size);
147
 
148
  // Return whether SYM is defined by the ABI.
149
  bool
150
  do_is_defined_by_abi(const Symbol* sym) const
151
  {
152
    return strcmp(sym->name(), "___tls_get_addr") == 0;
153
  }
154
 
155
  // Return the size of the GOT section.
156
  section_size_type
157
  got_size()
158
  {
159
    gold_assert(this->got_ != NULL);
160
    return this->got_->data_size();
161
  }
162
 
163
 private:
164
 
165
  // The class which scans relocations.
166
  class Scan
167
  {
168
  public:
169
    Scan()
170
      : issued_non_pic_error_(false)
171
    { }
172
 
173
    inline void
174
    local(const General_options& options, Symbol_table* symtab,
175
          Layout* layout, Target_powerpc* target,
176
          Sized_relobj<size, big_endian>* object,
177
          unsigned int data_shndx,
178
          Output_section* output_section,
179
          const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
180
          const elfcpp::Sym<size, big_endian>& lsym);
181
 
182
    inline void
183
    global(const General_options& options, Symbol_table* symtab,
184
           Layout* layout, Target_powerpc* target,
185
           Sized_relobj<size, big_endian>* object,
186
           unsigned int data_shndx,
187
           Output_section* output_section,
188
           const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
189
           Symbol* gsym);
190
 
191
  private:
192
    static void
193
    unsupported_reloc_local(Sized_relobj<size, big_endian>*,
194
                            unsigned int r_type);
195
 
196
    static void
197
    unsupported_reloc_global(Sized_relobj<size, big_endian>*,
198
                             unsigned int r_type, Symbol*);
199
 
200
    static void
201
    generate_tls_call(Symbol_table* symtab, Layout* layout,
202
                      Target_powerpc* target);
203
 
204
    void
205
    check_non_pic(Relobj*, unsigned int r_type);
206
 
207
    // Whether we have issued an error about a non-PIC compilation.
208
    bool issued_non_pic_error_;
209
  };
210
 
211
  // The class which implements relocation.
212
  class Relocate
213
  {
214
   public:
215
    // Do a relocation.  Return false if the caller should not issue
216
    // any warnings about this relocation.
217
    inline bool
218
    relocate(const Relocate_info<size, big_endian>*, Target_powerpc*,
219
             Output_section*, size_t relnum,
220
             const elfcpp::Rela<size, big_endian>&,
221
             unsigned int r_type, const Sized_symbol<size>*,
222
             const Symbol_value<size>*,
223
             unsigned char*,
224
             typename elfcpp::Elf_types<size>::Elf_Addr,
225
             section_size_type);
226
 
227
   private:
228
    // Do a TLS relocation.
229
    inline void
230
    relocate_tls(const Relocate_info<size, big_endian>*,
231
                 Target_powerpc* target,
232
                 size_t relnum, const elfcpp::Rela<size, big_endian>&,
233
                 unsigned int r_type, const Sized_symbol<size>*,
234
                 const Symbol_value<size>*,
235
                 unsigned char*,
236
                 typename elfcpp::Elf_types<size>::Elf_Addr,
237
                 section_size_type);
238
  };
239
 
240
  // A class which returns the size required for a relocation type,
241
  // used while scanning relocs during a relocatable link.
242
  class Relocatable_size_for_reloc
243
  {
244
   public:
245
    unsigned int
246
    get_size_for_reloc(unsigned int, Relobj*);
247
  };
248
 
249
  // Get the GOT section, creating it if necessary.
250
  Output_data_got<size, big_endian>*
251
  got_section(Symbol_table*, Layout*);
252
 
253
  Output_data_space*
254
  got2_section() const
255
  {
256
    gold_assert (this->got2_ != NULL);
257
    return this->got2_;
258
  }
259
 
260
  // Get the TOC section.
261
  Output_data_space*
262
  toc_section() const
263
  {
264
    gold_assert (this->toc_ != NULL);
265
    return this->toc_;
266
  }
267
 
268
  // Create a PLT entry for a global symbol.
269
  void
270
  make_plt_entry(Symbol_table*, Layout*, Symbol*);
271
 
272
  // Create a GOT entry for the TLS module index.
273
  unsigned int
274
  got_mod_index_entry(Symbol_table* symtab, Layout* layout,
275
                      Sized_relobj<size, big_endian>* object);
276
 
277
  // Get the PLT section.
278
  const Output_data_plt_powerpc<size, big_endian>*
279
  plt_section() const
280
  {
281
    gold_assert(this->plt_ != NULL);
282
    return this->plt_;
283
  }
284
 
285
  // Get the dynamic reloc section, creating it if necessary.
286
  Reloc_section*
287
  rela_dyn_section(Layout*);
288
 
289
  // Copy a relocation against a global symbol.
290
  void
291
  copy_reloc(Symbol_table* symtab, Layout* layout,
292
             Sized_relobj<size, big_endian>* object,
293
             unsigned int shndx, Output_section* output_section,
294
             Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
295
  {
296
    this->copy_relocs_.copy_reloc(symtab, layout,
297
                                  symtab->get_sized_symbol<size>(sym),
298
                                  object, shndx, output_section,
299
                                  reloc, this->rela_dyn_section(layout));
300
  }
301
 
302
  // Information about this specific target which we pass to the
303
  // general Target structure.
304
  static Target::Target_info powerpc_info;
305
 
306
  // The types of GOT entries needed for this platform.
307
  enum Got_type
308
  {
309
    GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
310
    GOT_TYPE_TLS_OFFSET = 1,    // GOT entry for TLS offset
311
    GOT_TYPE_TLS_PAIR = 2,      // GOT entry for TLS module/offset pair
312
  };
313
 
314
  // The GOT section.
315
  Output_data_got<size, big_endian>* got_;
316
  // The GOT2 section.
317
  Output_data_space* got2_;
318
  // The TOC section.
319
  Output_data_space* toc_;
320
  // The PLT section.
321
  Output_data_plt_powerpc<size, big_endian>* plt_;
322
  // The dynamic reloc section.
323
  Reloc_section* rela_dyn_;
324
  // Relocs saved to avoid a COPY reloc.
325
  Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
326
  // Space for variables copied with a COPY reloc.
327
  Output_data_space* dynbss_;
328
  // Offset of the GOT entry for the TLS module index;
329
  unsigned int got_mod_index_offset_;
330
};
331
 
332
template<>
333
Target::Target_info Target_powerpc<32, true>::powerpc_info =
334
{
335
  32,                   // size
336
  true,                 // is_big_endian
337
  elfcpp::EM_PPC,       // machine_code
338
  false,                // has_make_symbol
339
  false,                // has_resolve
340
  false,                // has_code_fill
341
  true,                 // is_default_stack_executable
342
  '\0',                 // wrap_char
343
  "/usr/lib/ld.so.1",   // dynamic_linker
344
  0x10000000,           // default_text_segment_address
345
  64 * 1024,            // abi_pagesize (overridable by -z max-page-size)
346
  4 * 1024,             // common_pagesize (overridable by -z common-page-size)
347
  elfcpp::SHN_UNDEF,    // small_common_shndx
348
  elfcpp::SHN_UNDEF,    // large_common_shndx
349
  0,                     // small_common_section_flags
350
 
351
};
352
 
353
template<>
354
Target::Target_info Target_powerpc<32, false>::powerpc_info =
355
{
356
  32,                   // size
357
  false,                // is_big_endian
358
  elfcpp::EM_PPC,       // machine_code
359
  false,                // has_make_symbol
360
  false,                // has_resolve
361
  false,                // has_code_fill
362
  true,                 // is_default_stack_executable
363
  '\0',                 // wrap_char
364
  "/usr/lib/ld.so.1",   // dynamic_linker
365
  0x10000000,           // default_text_segment_address
366
  64 * 1024,            // abi_pagesize (overridable by -z max-page-size)
367
  4 * 1024,             // common_pagesize (overridable by -z common-page-size)
368
  elfcpp::SHN_UNDEF,    // small_common_shndx
369
  elfcpp::SHN_UNDEF,    // large_common_shndx
370
  0,                     // small_common_section_flags
371
 
372
};
373
 
374
template<>
375
Target::Target_info Target_powerpc<64, true>::powerpc_info =
376
{
377
  64,                   // size
378
  true,                 // is_big_endian
379
  elfcpp::EM_PPC64,     // machine_code
380
  false,                // has_make_symbol
381
  false,                // has_resolve
382
  false,                // has_code_fill
383
  true,                 // is_default_stack_executable
384
  '\0',                 // wrap_char
385
  "/usr/lib/ld.so.1",   // dynamic_linker
386
  0x10000000,           // default_text_segment_address
387
  64 * 1024,            // abi_pagesize (overridable by -z max-page-size)
388
  8 * 1024,             // common_pagesize (overridable by -z common-page-size)
389
  elfcpp::SHN_UNDEF,    // small_common_shndx
390
  elfcpp::SHN_UNDEF,    // large_common_shndx
391
  0,                     // small_common_section_flags
392
 
393
};
394
 
395
template<>
396
Target::Target_info Target_powerpc<64, false>::powerpc_info =
397
{
398
  64,                   // size
399
  false,                // is_big_endian
400
  elfcpp::EM_PPC64,     // machine_code
401
  false,                // has_make_symbol
402
  false,                // has_resolve
403
  false,                // has_code_fill
404
  true,                 // is_default_stack_executable
405
  '\0',                 // wrap_char
406
  "/usr/lib/ld.so.1",   // dynamic_linker
407
  0x10000000,           // default_text_segment_address
408
  64 * 1024,            // abi_pagesize (overridable by -z max-page-size)
409
  8 * 1024,             // common_pagesize (overridable by -z common-page-size)
410
  elfcpp::SHN_UNDEF,    // small_common_shndx
411
  elfcpp::SHN_UNDEF,    // large_common_shndx
412
  0,                     // small_common_section_flags
413
 
414
};
415
 
416
template<int size, bool big_endian>
417
class Powerpc_relocate_functions
418
{
419
private:
420
  // Do a simple relocation with the addend in the relocation.
421
  template<int valsize>
422
  static inline void
423
  rela(unsigned char* view,
424
       unsigned int right_shift,
425
       elfcpp::Elf_Xword dst_mask,
426
       typename elfcpp::Swap<size, big_endian>::Valtype value,
427
       typename elfcpp::Swap<size, big_endian>::Valtype addend)
428
  {
429
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
430
    Valtype* wv = reinterpret_cast<Valtype*>(view);
431
    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
432
    Valtype reloc = ((value + addend) >> right_shift);
433
 
434
    val &= ~dst_mask;
435
    reloc &= dst_mask;
436
 
437
    elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
438
  }
439
 
440
  // Do a simple relocation using a symbol value with the addend in
441
  // the relocation.
442
  template<int valsize>
443
  static inline void
444
  rela(unsigned char* view,
445
       unsigned int right_shift,
446
       elfcpp::Elf_Xword dst_mask,
447
       const Sized_relobj<size, big_endian>* object,
448
       const Symbol_value<size>* psymval,
449
       typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
450
  {
451
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
452
    Valtype* wv = reinterpret_cast<Valtype*>(view);
453
    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
454
    Valtype reloc = (psymval->value(object, addend) >> right_shift);
455
 
456
    val &= ~dst_mask;
457
    reloc &= dst_mask;
458
 
459
    elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
460
  }
461
 
462
  // Do a simple relocation using a symbol value with the addend in
463
  // the relocation, unaligned.
464
  template<int valsize>
465
  static inline void
466
  rela_ua(unsigned char* view, unsigned int right_shift,
467
          elfcpp::Elf_Xword dst_mask,
468
          const Sized_relobj<size, big_endian>* object,
469
          const Symbol_value<size>* psymval,
470
          typename elfcpp::Swap<size, big_endian>::Valtype addend)
471
  {
472
    typedef typename elfcpp::Swap_unaligned<valsize,
473
            big_endian>::Valtype Valtype;
474
    unsigned char* wv = view;
475
    Valtype val = elfcpp::Swap_unaligned<valsize, big_endian>::readval(wv);
476
    Valtype reloc = (psymval->value(object, addend) >> right_shift);
477
 
478
    val &= ~dst_mask;
479
    reloc &= dst_mask;
480
 
481
    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(wv, val | reloc);
482
  }
483
 
484
  // Do a simple PC relative relocation with a Symbol_value with the
485
  // addend in the relocation.
486
  template<int valsize>
487
  static inline void
488
  pcrela(unsigned char* view, unsigned int right_shift,
489
         elfcpp::Elf_Xword dst_mask,
490
         const Sized_relobj<size, big_endian>* object,
491
         const Symbol_value<size>* psymval,
492
         typename elfcpp::Swap<size, big_endian>::Valtype addend,
493
         typename elfcpp::Elf_types<size>::Elf_Addr address)
494
  {
495
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
496
    Valtype* wv = reinterpret_cast<Valtype*>(view);
497
    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
498
    Valtype reloc = ((psymval->value(object, addend) - address)
499
                     >> right_shift);
500
 
501
    val &= ~dst_mask;
502
    reloc &= dst_mask;
503
 
504
    elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
505
  }
506
 
507
  template<int valsize>
508
  static inline void
509
  pcrela_unaligned(unsigned char* view,
510
                   const Sized_relobj<size, big_endian>* object,
511
                   const Symbol_value<size>* psymval,
512
                   typename elfcpp::Swap<size, big_endian>::Valtype addend,
513
                   typename elfcpp::Elf_types<size>::Elf_Addr address)
514
  {
515
    typedef typename elfcpp::Swap_unaligned<valsize,
516
            big_endian>::Valtype Valtype;
517
    unsigned char* wv = view;
518
    Valtype reloc = (psymval->value(object, addend) - address);
519
 
520
    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(wv, reloc);
521
  }
522
 
523
  typedef Powerpc_relocate_functions<size, big_endian> This;
524
  typedef Relocate_functions<size, big_endian> This_reloc;
525
public:
526
  // R_POWERPC_REL32: (Symbol + Addend - Address)
527
  static inline void
528
  rel32(unsigned char* view,
529
        const Sized_relobj<size, big_endian>* object,
530
        const Symbol_value<size>* psymval,
531
        typename elfcpp::Elf_types<size>::Elf_Addr addend,
532
        typename elfcpp::Elf_types<size>::Elf_Addr address)
533
  { This_reloc::pcrela32(view, object, psymval, addend, address); }
534
 
535
  // R_POWERPC_REL24: (Symbol + Addend - Address) & 0x3fffffc
536
  static inline void
537
  rel24(unsigned char* view,
538
        const Sized_relobj<size, big_endian>* object,
539
        const Symbol_value<size>* psymval,
540
        typename elfcpp::Elf_types<size>::Elf_Addr addend,
541
        typename elfcpp::Elf_types<size>::Elf_Addr address)
542
  {
543
    This::template pcrela<32>(view, 0, 0x03fffffc, object,
544
                              psymval, addend, address);
545
  }
546
 
547
  // R_POWERPC_REL14: (Symbol + Addend - Address) & 0xfffc
548
  static inline void
549
  rel14(unsigned char* view,
550
        const Sized_relobj<size, big_endian>* object,
551
        const Symbol_value<size>* psymval,
552
        typename elfcpp::Elf_types<size>::Elf_Addr addend,
553
        typename elfcpp::Elf_types<size>::Elf_Addr address)
554
  {
555
    This::template pcrela<32>(view, 0, 0x0000fffc, object,
556
                              psymval, addend, address);
557
  }
558
 
559
  // R_POWERPC_ADDR16: (Symbol + Addend) & 0xffff
560
  static inline void
561
  addr16(unsigned char* view,
562
         typename elfcpp::Elf_types<size>::Elf_Addr value,
563
         typename elfcpp::Elf_types<size>::Elf_Addr addend)
564
  { This_reloc::rela16(view, value, addend); }
565
 
566
  static inline void
567
  addr16(unsigned char* view,
568
         const Sized_relobj<size, big_endian>* object,
569
         const Symbol_value<size>* psymval,
570
         typename elfcpp::Elf_types<size>::Elf_Addr addend)
571
  { This_reloc::rela16(view, object, psymval, addend); }
572
 
573
  // R_POWERPC_ADDR16_DS: (Symbol + Addend) & 0xfffc
574
  static inline void
575
  addr16_ds(unsigned char* view,
576
            typename elfcpp::Elf_types<size>::Elf_Addr value,
577
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
578
  {
579
    This::template rela<16>(view, 0, 0xfffc, value, addend);
580
  }
581
 
582
  // R_POWERPC_ADDR16_LO: (Symbol + Addend) & 0xffff
583
  static inline void
584
  addr16_lo(unsigned char* view,
585
         typename elfcpp::Elf_types<size>::Elf_Addr value,
586
         typename elfcpp::Elf_types<size>::Elf_Addr addend)
587
  { This_reloc::rela16(view, value, addend); }
588
 
589
  static inline void
590
  addr16_lo(unsigned char* view,
591
            const Sized_relobj<size, big_endian>* object,
592
            const Symbol_value<size>* psymval,
593
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
594
  { This_reloc::rela16(view, object, psymval, addend); }
595
 
596
  // R_POWERPC_ADDR16_HI: ((Symbol + Addend) >> 16) & 0xffff
597
  static inline void
598
  addr16_hi(unsigned char* view,
599
            typename elfcpp::Elf_types<size>::Elf_Addr value,
600
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
601
  {
602
    This::template rela<16>(view, 16, 0xffff, value, addend);
603
  }
604
 
605
  static inline void
606
  addr16_hi(unsigned char* view,
607
            const Sized_relobj<size, big_endian>* object,
608
            const Symbol_value<size>* psymval,
609
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
610
  {
611
    This::template rela<16>(view, 16, 0xffff, object, psymval, addend);
612
  }
613
 
614
  // R_POWERPC_ADDR16_HA: Same as R_POWERPC_ADDR16_HI except that if the
615
  //                      final value of the low 16 bits of the
616
  //                      relocation is negative, add one.
617
  static inline void
618
  addr16_ha(unsigned char* view,
619
            typename elfcpp::Elf_types<size>::Elf_Addr value,
620
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
621
  {
622
    typename elfcpp::Elf_types<size>::Elf_Addr reloc;
623
 
624
    reloc = value + addend;
625
 
626
    if (reloc & 0x8000)
627
      reloc += 0x10000;
628
    reloc >>= 16;
629
 
630
    elfcpp::Swap<16, big_endian>::writeval(view, reloc);
631
  }
632
 
633
  static inline void
634
  addr16_ha(unsigned char* view,
635
            const Sized_relobj<size, big_endian>* object,
636
            const Symbol_value<size>* psymval,
637
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
638
  {
639
    typename elfcpp::Elf_types<size>::Elf_Addr reloc;
640
 
641
    reloc = psymval->value(object, addend);
642
 
643
    if (reloc & 0x8000)
644
      reloc += 0x10000;
645
    reloc >>= 16;
646
 
647
    elfcpp::Swap<16, big_endian>::writeval(view, reloc);
648
  }
649
 
650
  // R_PPC_REL16: (Symbol + Addend - Address) & 0xffff
651
  static inline void
652
  rel16(unsigned char* view,
653
        const Sized_relobj<size, big_endian>* object,
654
        const Symbol_value<size>* psymval,
655
        typename elfcpp::Elf_types<size>::Elf_Addr addend,
656
        typename elfcpp::Elf_types<size>::Elf_Addr address)
657
  { This_reloc::pcrela16(view, object, psymval, addend, address); }
658
 
659
  // R_PPC_REL16_LO: (Symbol + Addend - Address) & 0xffff
660
  static inline void
661
  rel16_lo(unsigned char* view,
662
           const Sized_relobj<size, big_endian>* object,
663
           const Symbol_value<size>* psymval,
664
           typename elfcpp::Elf_types<size>::Elf_Addr addend,
665
           typename elfcpp::Elf_types<size>::Elf_Addr address)
666
  { This_reloc::pcrela16(view, object, psymval, addend, address); }
667
 
668
  // R_PPC_REL16_HI: ((Symbol + Addend - Address) >> 16) & 0xffff
669
  static inline void
670
  rel16_hi(unsigned char* view,
671
           const Sized_relobj<size, big_endian>* object,
672
           const Symbol_value<size>* psymval,
673
           typename elfcpp::Elf_types<size>::Elf_Addr addend,
674
           typename elfcpp::Elf_types<size>::Elf_Addr address)
675
  {
676
    This::template pcrela<16>(view, 16, 0xffff, object,
677
                              psymval, addend, address);
678
  }
679
 
680
  // R_PPC_REL16_HA: Same as R_PPC_REL16_HI except that if the
681
  //                 final value of the low 16 bits of the
682
  //                 relocation is negative, add one.
683
  static inline void
684
  rel16_ha(unsigned char* view,
685
           const Sized_relobj<size, big_endian>* object,
686
           const Symbol_value<size>* psymval,
687
           typename elfcpp::Elf_types<size>::Elf_Addr addend,
688
           typename elfcpp::Elf_types<size>::Elf_Addr address)
689
  {
690
    typename elfcpp::Elf_types<size>::Elf_Addr reloc;
691
 
692
    reloc = (psymval->value(object, addend) - address);
693
    if (reloc & 0x8000)
694
      reloc += 0x10000;
695
    reloc >>= 16;
696
 
697
    elfcpp::Swap<16, big_endian>::writeval(view, reloc);
698
  }
699
};
700
 
701
// Get the GOT section, creating it if necessary.
702
 
703
template<int size, bool big_endian>
704
Output_data_got<size, big_endian>*
705
Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
706
                                              Layout* layout)
707
{
708
  if (this->got_ == NULL)
709
    {
710
      gold_assert(symtab != NULL && layout != NULL);
711
 
712
      this->got_ = new Output_data_got<size, big_endian>();
713
 
714
      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
715
                                      elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
716
                                      this->got_, false);
717
 
718
      // Create the GOT2 or TOC in the .got section.
719
      if (size == 32)
720
        {
721
          this->got2_ = new Output_data_space(4, "** GOT2");
722
          layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS,
723
                                          elfcpp::SHF_ALLOC
724
                                          | elfcpp::SHF_WRITE,
725
                                          this->got2_, false);
726
        }
727
      else
728
        {
729
          this->toc_ = new Output_data_space(8, "** TOC");
730
          layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS,
731
                                          elfcpp::SHF_ALLOC
732
                                          | elfcpp::SHF_WRITE,
733
                                          this->toc_, false);
734
        }
735
 
736
      // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
737
      symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
738
                                    this->got_,
739
                                    0, 0, elfcpp::STT_OBJECT,
740
                                    elfcpp::STB_LOCAL,
741
                                    elfcpp::STV_HIDDEN, 0,
742
                                    false, false);
743
    }
744
 
745
  return this->got_;
746
}
747
 
748
// Get the dynamic reloc section, creating it if necessary.
749
 
750
template<int size, bool big_endian>
751
typename Target_powerpc<size, big_endian>::Reloc_section*
752
Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout)
753
{
754
  if (this->rela_dyn_ == NULL)
755
    {
756
      gold_assert(layout != NULL);
757
      this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
758
      layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
759
                                      elfcpp::SHF_ALLOC, this->rela_dyn_, true);
760
    }
761
  return this->rela_dyn_;
762
}
763
 
764
// A class to handle the PLT data.
765
 
766
template<int size, bool big_endian>
767
class Output_data_plt_powerpc : public Output_section_data
768
{
769
 public:
770
  typedef Output_data_reloc<elfcpp::SHT_RELA, true,
771
                            size, big_endian> Reloc_section;
772
 
773
  Output_data_plt_powerpc(Layout*);
774
 
775
  // Add an entry to the PLT.
776
  void add_entry(Symbol* gsym);
777
 
778
  // Return the .rela.plt section data.
779
  const Reloc_section* rel_plt() const
780
 {
781
    return this->rel_;
782
  }
783
 
784
 protected:
785
  void do_adjust_output_section(Output_section* os);
786
 
787
 private:
788
  // The size of an entry in the PLT.
789
  static const int base_plt_entry_size = (size == 32 ? 16 : 24);
790
 
791
  // Set the final size.
792
  void
793
  set_final_data_size()
794
  {
795
    unsigned int full_count = this->count_ + 4;
796
 
797
    this->set_data_size(full_count * base_plt_entry_size);
798
  }
799
 
800
  // Write out the PLT data.
801
  void
802
  do_write(Output_file*);
803
 
804
  // The reloc section.
805
  Reloc_section* rel_;
806
  // The number of PLT entries.
807
  unsigned int count_;
808
};
809
 
810
// Create the PLT section.  The ordinary .got section is an argument,
811
// since we need to refer to the start.
812
 
813
template<int size, bool big_endian>
814
Output_data_plt_powerpc<size, big_endian>::Output_data_plt_powerpc(Layout* layout)
815
  : Output_section_data(size == 32 ? 4 : 8), count_(0)
816
{
817
  this->rel_ = new Reloc_section(false);
818
  layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
819
                                  elfcpp::SHF_ALLOC, this->rel_, true);
820
}
821
 
822
template<int size, bool big_endian>
823
void
824
Output_data_plt_powerpc<size, big_endian>::do_adjust_output_section(Output_section* os)
825
{
826
  os->set_entsize(0);
827
}
828
 
829
// Add an entry to the PLT.
830
 
831
template<int size, bool big_endian>
832
void
833
Output_data_plt_powerpc<size, big_endian>::add_entry(Symbol* gsym)
834
{
835
  gold_assert(!gsym->has_plt_offset());
836
  unsigned int index = this->count_+ + 4;
837
  section_offset_type plt_offset;
838
 
839
  if (index < 8192)
840
    plt_offset = index * base_plt_entry_size;
841
  else
842
    gold_unreachable();
843
 
844
  gsym->set_plt_offset(plt_offset);
845
 
846
  ++this->count_;
847
 
848
  gsym->set_needs_dynsym_entry();
849
  this->rel_->add_global(gsym, elfcpp::R_POWERPC_JMP_SLOT, this,
850
                         plt_offset, 0);
851
}
852
 
853
static const unsigned int addis_11_11     = 0x3d6b0000;
854
static const unsigned int addis_11_30     = 0x3d7e0000;
855
static const unsigned int addis_12_12     = 0x3d8c0000;
856
static const unsigned int addi_11_11      = 0x396b0000;
857
static const unsigned int add_0_11_11     = 0x7c0b5a14;
858
static const unsigned int add_11_0_11     = 0x7d605a14;
859
static const unsigned int b               = 0x48000000;
860
static const unsigned int bcl_20_31       = 0x429f0005;
861
static const unsigned int bctr            = 0x4e800420;
862
static const unsigned int lis_11          = 0x3d600000;
863
static const unsigned int lis_12          = 0x3d800000;
864
static const unsigned int lwzu_0_12       = 0x840c0000;
865
static const unsigned int lwz_0_12        = 0x800c0000;
866
static const unsigned int lwz_11_11       = 0x816b0000;
867
static const unsigned int lwz_11_30       = 0x817e0000;
868
static const unsigned int lwz_12_12       = 0x818c0000;
869
static const unsigned int mflr_0          = 0x7c0802a6;
870
static const unsigned int mflr_12         = 0x7d8802a6;
871
static const unsigned int mtctr_0         = 0x7c0903a6;
872
static const unsigned int mtctr_11        = 0x7d6903a6;
873
static const unsigned int mtlr_0          = 0x7c0803a6;
874
static const unsigned int nop             = 0x60000000;
875
static const unsigned int sub_11_11_12    = 0x7d6c5850;
876
 
877
static const unsigned int addis_r12_r2    = 0x3d820000;  /* addis %r12,%r2,xxx@ha     */
878
static const unsigned int std_r2_40r1     = 0xf8410028;  /* std   %r2,40(%r1)         */
879
static const unsigned int ld_r11_0r12     = 0xe96c0000;  /* ld    %r11,xxx+0@l(%r12)  */
880
static const unsigned int ld_r2_0r12      = 0xe84c0000;  /* ld    %r2,xxx+8@l(%r12)   */
881
                                                         /* ld    %r11,xxx+16@l(%r12) */
882
 
883
 
884
// Write out the PLT.
885
 
886
template<int size, bool big_endian>
887
void
888
Output_data_plt_powerpc<size, big_endian>::do_write(Output_file* of)
889
{
890
  const off_t offset = this->offset();
891
  const section_size_type oview_size =
892
    convert_to_section_size_type(this->data_size());
893
  unsigned char* const oview = of->get_output_view(offset, oview_size);
894
  unsigned char* pov = oview;
895
 
896
  memset(pov, 0, base_plt_entry_size * 4);
897
  pov += base_plt_entry_size * 4;
898
 
899
  unsigned int plt_offset = base_plt_entry_size * 4;
900
  const unsigned int count = this->count_;
901
 
902
  if (size == 64)
903
    {
904
      for (unsigned int i = 0; i < count; i++)
905
        {
906
        }
907
    }
908
  else
909
    {
910
      for (unsigned int i = 0; i < count; i++)
911
        {
912
          elfcpp::Swap<32, true>::writeval(pov + 0x00,
913
                                           lwz_11_30 + plt_offset);
914
          elfcpp::Swap<32, true>::writeval(pov + 0x04, mtctr_11);
915
          elfcpp::Swap<32, true>::writeval(pov + 0x08, bctr);
916
          elfcpp::Swap<32, true>::writeval(pov + 0x0c, nop);
917
          pov += base_plt_entry_size;
918
          plt_offset += base_plt_entry_size;
919
        }
920
    }
921
 
922
  gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
923
 
924
  of->write_output_view(offset, oview_size, oview);
925
}
926
 
927
// Create a PLT entry for a global symbol.
928
 
929
template<int size, bool big_endian>
930
void
931
Target_powerpc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
932
                                                 Layout* layout,
933
                                                 Symbol* gsym)
934
{
935
  if (gsym->has_plt_offset())
936
    return;
937
 
938
  if (this->plt_ == NULL)
939
    {
940
      // Create the GOT section first.
941
      this->got_section(symtab, layout);
942
 
943
      this->plt_ = new Output_data_plt_powerpc<size, big_endian>(layout);
944
      layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
945
                                      (elfcpp::SHF_ALLOC
946
                                       | elfcpp::SHF_EXECINSTR
947
                                       | elfcpp::SHF_WRITE),
948
                                      this->plt_, false);
949
 
950
      // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section.
951
      symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL,
952
                                    this->plt_,
953
                                    0, 0, elfcpp::STT_OBJECT,
954
                                    elfcpp::STB_LOCAL,
955
                                    elfcpp::STV_HIDDEN, 0,
956
                                    false, false);
957
    }
958
 
959
  this->plt_->add_entry(gsym);
960
}
961
 
962
// Create a GOT entry for the TLS module index.
963
 
964
template<int size, bool big_endian>
965
unsigned int
966
Target_powerpc<size, big_endian>::got_mod_index_entry(Symbol_table* symtab,
967
                                                      Layout* layout,
968
                                                      Sized_relobj<size, big_endian>* object)
969
{
970
  if (this->got_mod_index_offset_ == -1U)
971
    {
972
      gold_assert(symtab != NULL && layout != NULL && object != NULL);
973
      Reloc_section* rela_dyn = this->rela_dyn_section(layout);
974
      Output_data_got<size, big_endian>* got;
975
      unsigned int got_offset;
976
 
977
      got = this->got_section(symtab, layout);
978
      got_offset = got->add_constant(0);
979
      rela_dyn->add_local(object, 0, elfcpp::R_POWERPC_DTPMOD, got,
980
                          got_offset, 0);
981
      got->add_constant(0);
982
      this->got_mod_index_offset_ = got_offset;
983
    }
984
  return this->got_mod_index_offset_;
985
}
986
 
987
// Optimize the TLS relocation type based on what we know about the
988
// symbol.  IS_FINAL is true if the final address of this symbol is
989
// known at link time.
990
 
991
static tls::Tls_optimization
992
optimize_tls_reloc(bool /* is_final */, int r_type)
993
{
994
  // If we are generating a shared library, then we can't do anything
995
  // in the linker.
996
  if (parameters->options().shared())
997
    return tls::TLSOPT_NONE;
998
  switch (r_type)
999
    {
1000
      // XXX
1001
    default:
1002
      gold_unreachable();
1003
    }
1004
}
1005
 
1006
// Report an unsupported relocation against a local symbol.
1007
 
1008
template<int size, bool big_endian>
1009
void
1010
Target_powerpc<size, big_endian>::Scan::unsupported_reloc_local(
1011
                        Sized_relobj<size, big_endian>* object,
1012
                        unsigned int r_type)
1013
{
1014
  gold_error(_("%s: unsupported reloc %u against local symbol"),
1015
             object->name().c_str(), r_type);
1016
}
1017
 
1018
// We are about to emit a dynamic relocation of type R_TYPE.  If the
1019
// dynamic linker does not support it, issue an error.
1020
 
1021
template<int size, bool big_endian>
1022
void
1023
Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
1024
                                                      unsigned int r_type)
1025
{
1026
  gold_assert(r_type != elfcpp::R_POWERPC_NONE);
1027
 
1028
  // These are the relocation types supported by glibc for both 32-bit
1029
  // and 64-bit powerpc.
1030
  switch (r_type)
1031
    {
1032
    case elfcpp::R_POWERPC_RELATIVE:
1033
    case elfcpp::R_POWERPC_GLOB_DAT:
1034
    case elfcpp::R_POWERPC_DTPMOD:
1035
    case elfcpp::R_POWERPC_DTPREL:
1036
    case elfcpp::R_POWERPC_TPREL:
1037
    case elfcpp::R_POWERPC_JMP_SLOT:
1038
    case elfcpp::R_POWERPC_COPY:
1039
    case elfcpp::R_POWERPC_ADDR32:
1040
    case elfcpp::R_POWERPC_ADDR24:
1041
    case elfcpp::R_POWERPC_REL24:
1042
      return;
1043
 
1044
    default:
1045
      break;
1046
    }
1047
 
1048
  if (size == 64)
1049
    {
1050
      switch (r_type)
1051
        {
1052
          // These are the relocation types supported only on 64-bit.
1053
        case elfcpp::R_PPC64_ADDR64:
1054
        case elfcpp::R_PPC64_TPREL16_LO_DS:
1055
        case elfcpp::R_PPC64_TPREL16_DS:
1056
        case elfcpp::R_POWERPC_TPREL16:
1057
        case elfcpp::R_POWERPC_TPREL16_LO:
1058
        case elfcpp::R_POWERPC_TPREL16_HI:
1059
        case elfcpp::R_POWERPC_TPREL16_HA:
1060
        case elfcpp::R_PPC64_TPREL16_HIGHER:
1061
        case elfcpp::R_PPC64_TPREL16_HIGHEST:
1062
        case elfcpp::R_PPC64_TPREL16_HIGHERA:
1063
        case elfcpp::R_PPC64_TPREL16_HIGHESTA:
1064
        case elfcpp::R_PPC64_ADDR16_LO_DS:
1065
        case elfcpp::R_POWERPC_ADDR16_LO:
1066
        case elfcpp::R_POWERPC_ADDR16_HI:
1067
        case elfcpp::R_POWERPC_ADDR16_HA:
1068
        case elfcpp::R_POWERPC_ADDR30:
1069
        case elfcpp::R_PPC64_UADDR64:
1070
        case elfcpp::R_POWERPC_UADDR32:
1071
        case elfcpp::R_POWERPC_ADDR16:
1072
        case elfcpp::R_POWERPC_UADDR16:
1073
        case elfcpp::R_PPC64_ADDR16_DS:
1074
        case elfcpp::R_PPC64_ADDR16_HIGHER:
1075
        case elfcpp::R_PPC64_ADDR16_HIGHEST:
1076
        case elfcpp::R_PPC64_ADDR16_HIGHERA:
1077
        case elfcpp::R_PPC64_ADDR16_HIGHESTA:
1078
        case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
1079
        case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
1080
        case elfcpp::R_POWERPC_REL32:
1081
        case elfcpp::R_PPC64_REL64:
1082
          return;
1083
 
1084
        default:
1085
          break;
1086
        }
1087
    }
1088
  else
1089
    {
1090
      switch (r_type)
1091
        {
1092
          // These are the relocation types supported only on 32-bit.
1093
 
1094
        default:
1095
          break;
1096
        }
1097
    }
1098
 
1099
  // This prevents us from issuing more than one error per reloc
1100
  // section.  But we can still wind up issuing more than one
1101
  // error per object file.
1102
  if (this->issued_non_pic_error_)
1103
    return;
1104
  gold_assert(parameters->options().output_is_position_independent());
1105
  object->error(_("requires unsupported dynamic reloc; "
1106
                  "recompile with -fPIC"));
1107
  this->issued_non_pic_error_ = true;
1108
  return;
1109
}
1110
 
1111
// Scan a relocation for a local symbol.
1112
 
1113
template<int size, bool big_endian>
1114
inline void
1115
Target_powerpc<size, big_endian>::Scan::local(
1116
                        const General_options&,
1117
                        Symbol_table* symtab,
1118
                        Layout* layout,
1119
                        Target_powerpc<size, big_endian>* target,
1120
                        Sized_relobj<size, big_endian>* object,
1121
                        unsigned int data_shndx,
1122
                        Output_section* output_section,
1123
                        const elfcpp::Rela<size, big_endian>& reloc,
1124
                        unsigned int r_type,
1125
                        const elfcpp::Sym<size, big_endian>& lsym)
1126
{
1127
  switch (r_type)
1128
    {
1129
    case elfcpp::R_POWERPC_NONE:
1130
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
1131
    case elfcpp::R_POWERPC_GNU_VTENTRY:
1132
      break;
1133
 
1134
    case elfcpp::R_PPC64_ADDR64:
1135
    case elfcpp::R_POWERPC_ADDR32:
1136
    case elfcpp::R_POWERPC_ADDR16_HA:
1137
    case elfcpp::R_POWERPC_ADDR16_LO:
1138
      // If building a shared library (or a position-independent
1139
      // executable), we need to create a dynamic relocation for
1140
      // this location.
1141
      if (parameters->options().output_is_position_independent())
1142
        {
1143
          Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1144
 
1145
          check_non_pic(object, r_type);
1146
          if (lsym.get_st_type() != elfcpp::STT_SECTION)
1147
            {
1148
              unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
1149
              rela_dyn->add_local(object, r_sym, r_type, output_section,
1150
                                  data_shndx, reloc.get_r_offset(),
1151
                                  reloc.get_r_addend());
1152
            }
1153
          else
1154
            {
1155
              unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
1156
              gold_assert(lsym.get_st_value() == 0);
1157
              rela_dyn->add_local_relative(object, r_sym, r_type,
1158
                                           output_section, data_shndx,
1159
                                           reloc.get_r_offset(),
1160
                                           reloc.get_r_addend());
1161
            }
1162
        }
1163
      break;
1164
 
1165
    case elfcpp::R_POWERPC_REL24:
1166
    case elfcpp::R_PPC_LOCAL24PC:
1167
    case elfcpp::R_POWERPC_REL32:
1168
    case elfcpp::R_PPC_REL16_LO:
1169
    case elfcpp::R_PPC_REL16_HA:
1170
      break;
1171
 
1172
    case elfcpp::R_POWERPC_GOT16:
1173
    case elfcpp::R_POWERPC_GOT16_LO:
1174
    case elfcpp::R_POWERPC_GOT16_HI:
1175
    case elfcpp::R_POWERPC_GOT16_HA:
1176
    case elfcpp::R_PPC64_TOC16:
1177
    case elfcpp::R_PPC64_TOC16_LO:
1178
    case elfcpp::R_PPC64_TOC16_HI:
1179
    case elfcpp::R_PPC64_TOC16_HA:
1180
    case elfcpp::R_PPC64_TOC16_DS:
1181
    case elfcpp::R_PPC64_TOC16_LO_DS:
1182
      {
1183
        // The symbol requires a GOT entry.
1184
        Output_data_got<size, big_endian>* got;
1185
        unsigned int r_sym;
1186
 
1187
        got = target->got_section(symtab, layout);
1188
        r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
1189
 
1190
        // If we are generating a shared object, we need to add a
1191
        // dynamic relocation for this symbol's GOT entry.
1192
        if (parameters->options().output_is_position_independent())
1193
          {
1194
            if (!object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD))
1195
              {
1196
                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1197
                unsigned int off;
1198
 
1199
                off = got->add_constant(0);
1200
                object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
1201
                rela_dyn->add_local_relative(object, r_sym,
1202
                                             elfcpp::R_POWERPC_RELATIVE,
1203
                                             got, off, 0);
1204
              }
1205
          }
1206
        else
1207
          got->add_local(object, r_sym, GOT_TYPE_STANDARD);
1208
      }
1209
      break;
1210
 
1211
    case elfcpp::R_PPC64_TOC:
1212
      // We need a GOT section.
1213
      target->got_section(symtab, layout);
1214
      break;
1215
 
1216
      // These are relocations which should only be seen by the
1217
      // dynamic linker, and should never be seen here.
1218
    case elfcpp::R_POWERPC_COPY:
1219
    case elfcpp::R_POWERPC_GLOB_DAT:
1220
    case elfcpp::R_POWERPC_JMP_SLOT:
1221
    case elfcpp::R_POWERPC_RELATIVE:
1222
    case elfcpp::R_POWERPC_DTPMOD:
1223
      gold_error(_("%s: unexpected reloc %u in object file"),
1224
                 object->name().c_str(), r_type);
1225
      break;
1226
 
1227
    default:
1228
      unsupported_reloc_local(object, r_type);
1229
      break;
1230
    }
1231
}
1232
 
1233
// Report an unsupported relocation against a global symbol.
1234
 
1235
template<int size, bool big_endian>
1236
void
1237
Target_powerpc<size, big_endian>::Scan::unsupported_reloc_global(
1238
                        Sized_relobj<size, big_endian>* object,
1239
                        unsigned int r_type,
1240
                        Symbol* gsym)
1241
{
1242
  gold_error(_("%s: unsupported reloc %u against global symbol %s"),
1243
             object->name().c_str(), r_type, gsym->demangled_name().c_str());
1244
}
1245
 
1246
// Scan a relocation for a global symbol.
1247
 
1248
template<int size, bool big_endian>
1249
inline void
1250
Target_powerpc<size, big_endian>::Scan::global(
1251
                                const General_options&,
1252
                                Symbol_table* symtab,
1253
                                Layout* layout,
1254
                                Target_powerpc<size, big_endian>* target,
1255
                                Sized_relobj<size, big_endian>* object,
1256
                                unsigned int data_shndx,
1257
                                Output_section* output_section,
1258
                                const elfcpp::Rela<size, big_endian>& reloc,
1259
                                unsigned int r_type,
1260
                                Symbol* gsym)
1261
{
1262
  switch (r_type)
1263
    {
1264
    case elfcpp::R_POWERPC_NONE:
1265
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
1266
    case elfcpp::R_POWERPC_GNU_VTENTRY:
1267
      break;
1268
 
1269
    case elfcpp::R_PPC_PLTREL24:
1270
      // If the symbol is fully resolved, this is just a PC32 reloc.
1271
      // Otherwise we need a PLT entry.
1272
      if (gsym->final_value_is_known())
1273
        break;
1274
      // If building a shared library, we can also skip the PLT entry
1275
      // if the symbol is defined in the output file and is protected
1276
      // or hidden.
1277
      if (gsym->is_defined()
1278
          && !gsym->is_from_dynobj()
1279
          && !gsym->is_preemptible())
1280
        break;
1281
      target->make_plt_entry(symtab, layout, gsym);
1282
      break;
1283
 
1284
    case elfcpp::R_POWERPC_ADDR16:
1285
    case elfcpp::R_POWERPC_ADDR16_LO:
1286
    case elfcpp::R_POWERPC_ADDR16_HI:
1287
    case elfcpp::R_POWERPC_ADDR16_HA:
1288
    case elfcpp::R_POWERPC_ADDR32:
1289
    case elfcpp::R_PPC64_ADDR64:
1290
      {
1291
        // Make a PLT entry if necessary.
1292
        if (gsym->needs_plt_entry())
1293
          {
1294
            target->make_plt_entry(symtab, layout, gsym);
1295
            // Since this is not a PC-relative relocation, we may be
1296
            // taking the address of a function. In that case we need to
1297
            // set the entry in the dynamic symbol table to the address of
1298
            // the PLT entry.
1299
            if (gsym->is_from_dynobj() && !parameters->options().shared())
1300
              gsym->set_needs_dynsym_value();
1301
          }
1302
        // Make a dynamic relocation if necessary.
1303
        if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF))
1304
          {
1305
            if (gsym->may_need_copy_reloc())
1306
              {
1307
                target->copy_reloc(symtab, layout, object,
1308
                                   data_shndx, output_section, gsym, reloc);
1309
              }
1310
            else if ((r_type == elfcpp::R_POWERPC_ADDR32
1311
                      || r_type == elfcpp::R_PPC64_ADDR64)
1312
                     && gsym->can_use_relative_reloc(false))
1313
              {
1314
                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1315
                rela_dyn->add_global_relative(gsym, elfcpp::R_POWERPC_RELATIVE,
1316
                                              output_section, object,
1317
                                              data_shndx, reloc.get_r_offset(),
1318
                                              reloc.get_r_addend());
1319
              }
1320
            else
1321
              {
1322
                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1323
 
1324
                check_non_pic(object, r_type);
1325
                if (gsym->is_from_dynobj()
1326
                    || gsym->is_undefined()
1327
                    || gsym->is_preemptible())
1328
                  rela_dyn->add_global(gsym, r_type, output_section,
1329
                                       object, data_shndx,
1330
                                       reloc.get_r_offset(),
1331
                                       reloc.get_r_addend());
1332
                else
1333
                  rela_dyn->add_global_relative(gsym, r_type,
1334
                                                output_section, object,
1335
                                                data_shndx,
1336
                                                reloc.get_r_offset(),
1337
                                                reloc.get_r_addend());
1338
              }
1339
          }
1340
      }
1341
      break;
1342
 
1343
    case elfcpp::R_POWERPC_REL24:
1344
    case elfcpp::R_PPC_LOCAL24PC:
1345
    case elfcpp::R_PPC_REL16:
1346
    case elfcpp::R_PPC_REL16_LO:
1347
    case elfcpp::R_PPC_REL16_HI:
1348
    case elfcpp::R_PPC_REL16_HA:
1349
      {
1350
        if (gsym->needs_plt_entry())
1351
          target->make_plt_entry(symtab, layout, gsym);
1352
        // Make a dynamic relocation if necessary.
1353
        int flags = Symbol::NON_PIC_REF;
1354
        if (gsym->type() == elfcpp::STT_FUNC)
1355
          flags |= Symbol::FUNCTION_CALL;
1356
        if (gsym->needs_dynamic_reloc(flags))
1357
          {
1358
            if (gsym->may_need_copy_reloc())
1359
              {
1360
                target->copy_reloc(symtab, layout, object,
1361
                                   data_shndx, output_section, gsym,
1362
                                   reloc);
1363
              }
1364
            else
1365
              {
1366
                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1367
                check_non_pic(object, r_type);
1368
                rela_dyn->add_global(gsym, r_type, output_section, object,
1369
                                     data_shndx, reloc.get_r_offset(),
1370
                                     reloc.get_r_addend());
1371
              }
1372
          }
1373
      }
1374
      break;
1375
 
1376
    case elfcpp::R_POWERPC_GOT16:
1377
    case elfcpp::R_POWERPC_GOT16_LO:
1378
    case elfcpp::R_POWERPC_GOT16_HI:
1379
    case elfcpp::R_POWERPC_GOT16_HA:
1380
    case elfcpp::R_PPC64_TOC16:
1381
    case elfcpp::R_PPC64_TOC16_LO:
1382
    case elfcpp::R_PPC64_TOC16_HI:
1383
    case elfcpp::R_PPC64_TOC16_HA:
1384
    case elfcpp::R_PPC64_TOC16_DS:
1385
    case elfcpp::R_PPC64_TOC16_LO_DS:
1386
      {
1387
        // The symbol requires a GOT entry.
1388
        Output_data_got<size, big_endian>* got;
1389
 
1390
        got = target->got_section(symtab, layout);
1391
        if (gsym->final_value_is_known())
1392
          got->add_global(gsym, GOT_TYPE_STANDARD);
1393
        else
1394
          {
1395
            // If this symbol is not fully resolved, we need to add a
1396
            // dynamic relocation for it.
1397
            Reloc_section* rela_dyn = target->rela_dyn_section(layout);
1398
            if (gsym->is_from_dynobj()
1399
                || gsym->is_undefined()
1400
                || gsym->is_preemptible())
1401
              got->add_global_with_rela(gsym, GOT_TYPE_STANDARD, rela_dyn,
1402
                                        elfcpp::R_POWERPC_GLOB_DAT);
1403
            else if (!gsym->has_got_offset(GOT_TYPE_STANDARD))
1404
              {
1405
                unsigned int off = got->add_constant(0);
1406
 
1407
                gsym->set_got_offset(GOT_TYPE_STANDARD, off);
1408
                rela_dyn->add_global_relative(gsym, elfcpp::R_POWERPC_RELATIVE,
1409
                                              got, off, 0);
1410
              }
1411
          }
1412
      }
1413
      break;
1414
 
1415
    case elfcpp::R_PPC64_TOC:
1416
      // We need a GOT section.
1417
      target->got_section(symtab, layout);
1418
      break;
1419
 
1420
    case elfcpp::R_POWERPC_GOT_TPREL16:
1421
    case elfcpp::R_POWERPC_TLS:
1422
      // XXX TLS
1423
      break;
1424
 
1425
      // These are relocations which should only be seen by the
1426
      // dynamic linker, and should never be seen here.
1427
    case elfcpp::R_POWERPC_COPY:
1428
    case elfcpp::R_POWERPC_GLOB_DAT:
1429
    case elfcpp::R_POWERPC_JMP_SLOT:
1430
    case elfcpp::R_POWERPC_RELATIVE:
1431
    case elfcpp::R_POWERPC_DTPMOD:
1432
      gold_error(_("%s: unexpected reloc %u in object file"),
1433
                 object->name().c_str(), r_type);
1434
      break;
1435
 
1436
    default:
1437
      unsupported_reloc_global(object, r_type, gsym);
1438
      break;
1439
    }
1440
}
1441
 
1442
// Process relocations for gc.
1443
 
1444
template<int size, bool big_endian>
1445
void
1446
Target_powerpc<size, big_endian>::gc_process_relocs(
1447
                        const General_options& options,
1448
                        Symbol_table* symtab,
1449
                        Layout* layout,
1450
                        Sized_relobj<size, big_endian>* object,
1451
                        unsigned int data_shndx,
1452
                        unsigned int,
1453
                        const unsigned char* prelocs,
1454
                        size_t reloc_count,
1455
                        Output_section* output_section,
1456
                        bool needs_special_offset_handling,
1457
                        size_t local_symbol_count,
1458
                        const unsigned char* plocal_symbols)
1459
{
1460
  typedef Target_powerpc<size, big_endian> Powerpc;
1461
  typedef typename Target_powerpc<size, big_endian>::Scan Scan;
1462
 
1463
  gold::gc_process_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>(
1464
    options,
1465
    symtab,
1466
    layout,
1467
    this,
1468
    object,
1469
    data_shndx,
1470
    prelocs,
1471
    reloc_count,
1472
    output_section,
1473
    needs_special_offset_handling,
1474
    local_symbol_count,
1475
    plocal_symbols);
1476
}
1477
 
1478
// Scan relocations for a section.
1479
 
1480
template<int size, bool big_endian>
1481
void
1482
Target_powerpc<size, big_endian>::scan_relocs(
1483
                        const General_options& options,
1484
                        Symbol_table* symtab,
1485
                        Layout* layout,
1486
                        Sized_relobj<size, big_endian>* object,
1487
                        unsigned int data_shndx,
1488
                        unsigned int sh_type,
1489
                        const unsigned char* prelocs,
1490
                        size_t reloc_count,
1491
                        Output_section* output_section,
1492
                        bool needs_special_offset_handling,
1493
                        size_t local_symbol_count,
1494
                        const unsigned char* plocal_symbols)
1495
{
1496
  typedef Target_powerpc<size, big_endian> Powerpc;
1497
  typedef typename Target_powerpc<size, big_endian>::Scan Scan;
1498
  static Output_data_space* sdata;
1499
 
1500
  if (sh_type == elfcpp::SHT_REL)
1501
    {
1502
      gold_error(_("%s: unsupported REL reloc section"),
1503
                 object->name().c_str());
1504
      return;
1505
    }
1506
 
1507
  // Define _SDA_BASE_ at the start of the .sdata section.
1508
  if (sdata == NULL)
1509
  {
1510
    // layout->find_output_section(".sdata") == NULL
1511
    sdata = new Output_data_space(4, "** sdata");
1512
    Output_section* os = layout->add_output_section_data(".sdata", 0,
1513
                                                         elfcpp::SHF_ALLOC
1514
                                                         | elfcpp::SHF_WRITE,
1515
                                                         sdata, false);
1516
    symtab->define_in_output_data("_SDA_BASE_", NULL,
1517
                                  os,
1518
                                  32768, 0,
1519
                                  elfcpp::STT_OBJECT,
1520
                                  elfcpp::STB_LOCAL,
1521
                                  elfcpp::STV_HIDDEN, 0,
1522
                                  false, false);
1523
  }
1524
 
1525
  gold::scan_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>(
1526
    options,
1527
    symtab,
1528
    layout,
1529
    this,
1530
    object,
1531
    data_shndx,
1532
    prelocs,
1533
    reloc_count,
1534
    output_section,
1535
    needs_special_offset_handling,
1536
    local_symbol_count,
1537
    plocal_symbols);
1538
}
1539
 
1540
// Finalize the sections.
1541
 
1542
template<int size, bool big_endian>
1543
void
1544
Target_powerpc<size, big_endian>::do_finalize_sections(Layout* layout)
1545
{
1546
  // Fill in some more dynamic tags.
1547
  Output_data_dynamic* const odyn = layout->dynamic_data();
1548
  if (odyn != NULL)
1549
    {
1550
      if (this->plt_ != NULL
1551
          && this->plt_->output_section() != NULL)
1552
        {
1553
          const Output_data* od = this->plt_->rel_plt();
1554
          odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
1555
          odyn->add_section_address(elfcpp::DT_JMPREL, od);
1556
          odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
1557
 
1558
          odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_);
1559
        }
1560
 
1561
      if (this->rela_dyn_ != NULL
1562
          && this->rela_dyn_->output_section() != NULL)
1563
        {
1564
          const Output_data* od = this->rela_dyn_;
1565
          odyn->add_section_address(elfcpp::DT_RELA, od);
1566
          odyn->add_section_size(elfcpp::DT_RELASZ, od);
1567
          odyn->add_constant(elfcpp::DT_RELAENT,
1568
                             elfcpp::Elf_sizes<size>::rela_size);
1569
        }
1570
 
1571
      if (!parameters->options().shared())
1572
        {
1573
          // The value of the DT_DEBUG tag is filled in by the dynamic
1574
          // linker at run time, and used by the debugger.
1575
          odyn->add_constant(elfcpp::DT_DEBUG, 0);
1576
        }
1577
    }
1578
 
1579
  // Emit any relocs we saved in an attempt to avoid generating COPY
1580
  // relocs.
1581
  if (this->copy_relocs_.any_saved_relocs())
1582
    this->copy_relocs_.emit(this->rela_dyn_section(layout));
1583
}
1584
 
1585
// Perform a relocation.
1586
 
1587
template<int size, bool big_endian>
1588
inline bool
1589
Target_powerpc<size, big_endian>::Relocate::relocate(
1590
                        const Relocate_info<size, big_endian>* relinfo,
1591
                        Target_powerpc* target,
1592
                        Output_section*,
1593
                        size_t relnum,
1594
                        const elfcpp::Rela<size, big_endian>& rela,
1595
                        unsigned int r_type,
1596
                        const Sized_symbol<size>* gsym,
1597
                        const Symbol_value<size>* psymval,
1598
                        unsigned char* view,
1599
                        typename elfcpp::Elf_types<size>::Elf_Addr address,
1600
                        section_size_type /* view_size */)
1601
{
1602
  const unsigned int toc_base_offset = 0x8000;
1603
  typedef Powerpc_relocate_functions<size, big_endian> Reloc;
1604
 
1605
  // Pick the value to use for symbols defined in shared objects.
1606
  Symbol_value<size> symval;
1607
  if (gsym != NULL
1608
      && gsym->use_plt_offset(r_type == elfcpp::R_POWERPC_REL24
1609
                              || r_type == elfcpp::R_PPC_LOCAL24PC
1610
                              || r_type == elfcpp::R_PPC_REL16
1611
                              || r_type == elfcpp::R_PPC_REL16_LO
1612
                              || r_type == elfcpp::R_PPC_REL16_HI
1613
                              || r_type == elfcpp::R_PPC_REL16_HA))
1614
    {
1615
      elfcpp::Elf_Xword value;
1616
 
1617
      value = target->plt_section()->address() + gsym->plt_offset();
1618
 
1619
      symval.set_output_value(value);
1620
 
1621
      psymval = &symval;
1622
    }
1623
 
1624
  const Sized_relobj<size, big_endian>* object = relinfo->object;
1625
  elfcpp::Elf_Xword addend = rela.get_r_addend();
1626
 
1627
  // Get the GOT offset if needed.  Unlike i386 and x86_64, our GOT
1628
  // pointer points to the beginning, not the end, of the table.
1629
  // So we just use the plain offset.
1630
  bool have_got_offset = false;
1631
  unsigned int got_offset = 0;
1632
  unsigned int got2_offset = 0;
1633
  switch (r_type)
1634
    {
1635
    case elfcpp::R_PPC64_TOC16:
1636
    case elfcpp::R_PPC64_TOC16_LO:
1637
    case elfcpp::R_PPC64_TOC16_HI:
1638
    case elfcpp::R_PPC64_TOC16_HA:
1639
    case elfcpp::R_PPC64_TOC16_DS:
1640
    case elfcpp::R_PPC64_TOC16_LO_DS:
1641
        // Subtract the TOC base address.
1642
        addend -= target->toc_section()->address() + toc_base_offset;
1643
        /* FALLTHRU */
1644
 
1645
    case elfcpp::R_POWERPC_GOT16:
1646
    case elfcpp::R_POWERPC_GOT16_LO:
1647
    case elfcpp::R_POWERPC_GOT16_HI:
1648
    case elfcpp::R_POWERPC_GOT16_HA:
1649
    case elfcpp::R_PPC64_GOT16_DS:
1650
    case elfcpp::R_PPC64_GOT16_LO_DS:
1651
      if (gsym != NULL)
1652
        {
1653
          gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
1654
          got_offset = gsym->got_offset(GOT_TYPE_STANDARD);
1655
        }
1656
      else
1657
        {
1658
          unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
1659
          gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
1660
          got_offset = object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
1661
        }
1662
      have_got_offset = true;
1663
      break;
1664
 
1665
      // R_PPC_PLTREL24 is rather special.  If non-zero,
1666
      // the addend specifies the GOT pointer offset within .got2.  
1667
    case elfcpp::R_PPC_PLTREL24:
1668
      if (addend >= 32768)
1669
        {
1670
          Output_data_space* got2;
1671
          got2 = target->got2_section();
1672
          got2_offset = got2->offset();
1673
          addend += got2_offset;
1674
        }
1675
      have_got_offset = true;
1676
      break;
1677
 
1678
    default:
1679
      break;
1680
    }
1681
 
1682
  switch (r_type)
1683
    {
1684
    case elfcpp::R_POWERPC_NONE:
1685
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
1686
    case elfcpp::R_POWERPC_GNU_VTENTRY:
1687
      break;
1688
 
1689
    case elfcpp::R_POWERPC_REL32:
1690
      Reloc::rel32(view, object, psymval, addend, address);
1691
      break;
1692
 
1693
    case elfcpp::R_POWERPC_REL24:
1694
      Reloc::rel24(view, object, psymval, addend, address);
1695
      break;
1696
 
1697
    case elfcpp::R_POWERPC_REL14:
1698
      Reloc::rel14(view, object, psymval, addend, address);
1699
      break;
1700
 
1701
    case elfcpp::R_PPC_PLTREL24:
1702
      Reloc::rel24(view, object, psymval, addend, address);
1703
      break;
1704
 
1705
    case elfcpp::R_PPC_LOCAL24PC:
1706
      Reloc::rel24(view, object, psymval, addend, address);
1707
      break;
1708
 
1709
    case elfcpp::R_PPC64_ADDR64:
1710
      if (!parameters->options().output_is_position_independent())
1711
        Relocate_functions<size, big_endian>::rela64(view, object,
1712
                                                     psymval, addend);
1713
      break;
1714
 
1715
    case elfcpp::R_POWERPC_ADDR32:
1716
      if (!parameters->options().output_is_position_independent())
1717
        Relocate_functions<size, big_endian>::rela32(view, object,
1718
                                                     psymval, addend);
1719
      break;
1720
 
1721
    case elfcpp::R_POWERPC_ADDR16_LO:
1722
      Reloc::addr16_lo(view, object, psymval, addend);
1723
      break;
1724
 
1725
    case elfcpp::R_POWERPC_ADDR16_HI:
1726
      Reloc::addr16_hi(view, object, psymval, addend);
1727
      break;
1728
 
1729
    case elfcpp::R_POWERPC_ADDR16_HA:
1730
      Reloc::addr16_ha(view, object, psymval, addend);
1731
      break;
1732
 
1733
    case elfcpp::R_PPC_REL16_LO:
1734
      Reloc::rel16_lo(view, object, psymval, addend, address);
1735
      break;
1736
 
1737
    case elfcpp::R_PPC_REL16_HI:
1738
      Reloc::rel16_lo(view, object, psymval, addend, address);
1739
      break;
1740
 
1741
    case elfcpp::R_PPC_REL16_HA:
1742
      Reloc::rel16_ha(view, object, psymval, addend, address);
1743
      break;
1744
 
1745
    case elfcpp::R_POWERPC_GOT16:
1746
      Reloc::addr16(view, got_offset, addend);
1747
      break;
1748
 
1749
    case elfcpp::R_POWERPC_GOT16_LO:
1750
      Reloc::addr16_lo(view, got_offset, addend);
1751
      break;
1752
 
1753
    case elfcpp::R_POWERPC_GOT16_HI:
1754
      Reloc::addr16_hi(view, got_offset, addend);
1755
      break;
1756
 
1757
    case elfcpp::R_POWERPC_GOT16_HA:
1758
      Reloc::addr16_ha(view, got_offset, addend);
1759
      break;
1760
 
1761
    case elfcpp::R_PPC64_TOC16:
1762
      Reloc::addr16(view, got_offset, addend);
1763
      break;
1764
 
1765
    case elfcpp::R_PPC64_TOC16_LO:
1766
      Reloc::addr16_lo(view, got_offset, addend);
1767
      break;
1768
 
1769
    case elfcpp::R_PPC64_TOC16_HI:
1770
      Reloc::addr16_hi(view, got_offset, addend);
1771
      break;
1772
 
1773
    case elfcpp::R_PPC64_TOC16_HA:
1774
      Reloc::addr16_ha(view, got_offset, addend);
1775
      break;
1776
 
1777
    case elfcpp::R_PPC64_TOC16_DS:
1778
    case elfcpp::R_PPC64_TOC16_LO_DS:
1779
      Reloc::addr16_ds(view, got_offset, addend);
1780
      break;
1781
 
1782
    case elfcpp::R_PPC64_TOC:
1783
      {
1784
        elfcpp::Elf_types<64>::Elf_Addr value;
1785
        value = target->toc_section()->address() + toc_base_offset;
1786
        Relocate_functions<64, false>::rela64(view, value, addend);
1787
      }
1788
      break;
1789
 
1790
    case elfcpp::R_POWERPC_COPY:
1791
    case elfcpp::R_POWERPC_GLOB_DAT:
1792
    case elfcpp::R_POWERPC_JMP_SLOT:
1793
    case elfcpp::R_POWERPC_RELATIVE:
1794
      // This is an outstanding tls reloc, which is unexpected when
1795
      // linking.
1796
    case elfcpp::R_POWERPC_DTPMOD:
1797
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
1798
                             _("unexpected reloc %u in object file"),
1799
                             r_type);
1800
      break;
1801
 
1802
    default:
1803
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
1804
                             _("unsupported reloc %u"),
1805
                             r_type);
1806
      break;
1807
    }
1808
 
1809
  return true;
1810
}
1811
 
1812
// Perform a TLS relocation.
1813
 
1814
template<int size, bool big_endian>
1815
inline void
1816
Target_powerpc<size, big_endian>::Relocate::relocate_tls(
1817
                        const Relocate_info<size, big_endian>* relinfo,
1818
                        Target_powerpc<size, big_endian>* target,
1819
                        size_t relnum,
1820
                        const elfcpp::Rela<size, big_endian>& rela,
1821
                        unsigned int r_type,
1822
                        const Sized_symbol<size>* gsym,
1823
                        const Symbol_value<size>* psymval,
1824
                        unsigned char* view,
1825
                        typename elfcpp::Elf_types<size>::Elf_Addr address,
1826
                        section_size_type)
1827
{
1828
  Output_segment* tls_segment = relinfo->layout->tls_segment();
1829
  typedef Powerpc_relocate_functions<size, big_endian> Reloc;
1830
  const Sized_relobj<size, big_endian>* object = relinfo->object;
1831
 
1832
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
1833
  typename elfcpp::Elf_types<size>::Elf_Addr value = psymval->value(object, 0);
1834
 
1835
  const bool is_final =
1836
    (gsym == NULL
1837
     ? !parameters->options().output_is_position_independent()
1838
     : gsym->final_value_is_known());
1839
  const tls::Tls_optimization optimized_type
1840
      = optimize_tls_reloc(is_final, r_type);
1841
 
1842
  switch (r_type)
1843
    {
1844
      // XXX
1845
    }
1846
}
1847
 
1848
// Relocate section data.
1849
 
1850
template<int size, bool big_endian>
1851
void
1852
Target_powerpc<size, big_endian>::relocate_section(
1853
                        const Relocate_info<size, big_endian>* relinfo,
1854
                        unsigned int sh_type,
1855
                        const unsigned char* prelocs,
1856
                        size_t reloc_count,
1857
                        Output_section* output_section,
1858
                        bool needs_special_offset_handling,
1859
                        unsigned char* view,
1860
                        typename elfcpp::Elf_types<size>::Elf_Addr address,
1861
                        section_size_type view_size,
1862
                        const Reloc_symbol_changes* reloc_symbol_changes)
1863
{
1864
  typedef Target_powerpc<size, big_endian> Powerpc;
1865
  typedef typename Target_powerpc<size, big_endian>::Relocate Powerpc_relocate;
1866
 
1867
  gold_assert(sh_type == elfcpp::SHT_RELA);
1868
 
1869
  gold::relocate_section<size, big_endian, Powerpc, elfcpp::SHT_RELA,
1870
    Powerpc_relocate>(
1871
    relinfo,
1872
    this,
1873
    prelocs,
1874
    reloc_count,
1875
    output_section,
1876
    needs_special_offset_handling,
1877
    view,
1878
    address,
1879
    view_size,
1880
    reloc_symbol_changes);
1881
}
1882
 
1883
// Return the size of a relocation while scanning during a relocatable
1884
// link.
1885
 
1886
template<int size, bool big_endian>
1887
unsigned int
1888
Target_powerpc<size, big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
1889
    unsigned int,
1890
    Relobj*)
1891
{
1892
  // We are always SHT_RELA, so we should never get here.
1893
  gold_unreachable();
1894
  return 0;
1895
}
1896
 
1897
// Scan the relocs during a relocatable link.
1898
 
1899
template<int size, bool big_endian>
1900
void
1901
Target_powerpc<size, big_endian>::scan_relocatable_relocs(
1902
                        const General_options& options,
1903
                        Symbol_table* symtab,
1904
                        Layout* layout,
1905
                        Sized_relobj<size, big_endian>* object,
1906
                        unsigned int data_shndx,
1907
                        unsigned int sh_type,
1908
                        const unsigned char* prelocs,
1909
                        size_t reloc_count,
1910
                        Output_section* output_section,
1911
                        bool needs_special_offset_handling,
1912
                        size_t local_symbol_count,
1913
                        const unsigned char* plocal_symbols,
1914
                        Relocatable_relocs* rr)
1915
{
1916
  gold_assert(sh_type == elfcpp::SHT_RELA);
1917
 
1918
  typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_RELA,
1919
    Relocatable_size_for_reloc> Scan_relocatable_relocs;
1920
 
1921
  gold::scan_relocatable_relocs<size, big_endian, elfcpp::SHT_RELA,
1922
      Scan_relocatable_relocs>(
1923
    options,
1924
    symtab,
1925
    layout,
1926
    object,
1927
    data_shndx,
1928
    prelocs,
1929
    reloc_count,
1930
    output_section,
1931
    needs_special_offset_handling,
1932
    local_symbol_count,
1933
    plocal_symbols,
1934
    rr);
1935
}
1936
 
1937
// Relocate a section during a relocatable link.
1938
 
1939
template<int size, bool big_endian>
1940
void
1941
Target_powerpc<size, big_endian>::relocate_for_relocatable(
1942
    const Relocate_info<size, big_endian>* relinfo,
1943
    unsigned int sh_type,
1944
    const unsigned char* prelocs,
1945
    size_t reloc_count,
1946
    Output_section* output_section,
1947
    off_t offset_in_output_section,
1948
    const Relocatable_relocs* rr,
1949
    unsigned char* view,
1950
    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
1951
    section_size_type view_size,
1952
    unsigned char* reloc_view,
1953
    section_size_type reloc_view_size)
1954
{
1955
  gold_assert(sh_type == elfcpp::SHT_RELA);
1956
 
1957
  gold::relocate_for_relocatable<size, big_endian, elfcpp::SHT_RELA>(
1958
    relinfo,
1959
    prelocs,
1960
    reloc_count,
1961
    output_section,
1962
    offset_in_output_section,
1963
    rr,
1964
    view,
1965
    view_address,
1966
    view_size,
1967
    reloc_view,
1968
    reloc_view_size);
1969
}
1970
 
1971
// Return the value to use for a dynamic which requires special
1972
// treatment.  This is how we support equality comparisons of function
1973
// pointers across shared library boundaries, as described in the
1974
// processor specific ABI supplement.
1975
 
1976
template<int size, bool big_endian>
1977
uint64_t
1978
Target_powerpc<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
1979
{
1980
  gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
1981
  return this->plt_section()->address() + gsym->plt_offset();
1982
}
1983
 
1984
// The selector for powerpc object files.
1985
 
1986
template<int size, bool big_endian>
1987
class Target_selector_powerpc : public Target_selector
1988
{
1989
public:
1990
  Target_selector_powerpc()
1991
    : Target_selector(elfcpp::EM_NONE, size, big_endian,
1992
                      (size == 64 ?
1993
                       (big_endian ? "elf64-powerpc" : "elf64-powerpcle") :
1994
                       (big_endian ? "elf32-powerpc" : "elf32-powerpcle")))
1995
  { }
1996
 
1997
  Target* do_recognize(int machine, int, int)
1998
  {
1999
    switch (size)
2000
      {
2001
      case 64:
2002
        if (machine != elfcpp::EM_PPC64)
2003
          return NULL;
2004
        break;
2005
 
2006
      case 32:
2007
        if (machine != elfcpp::EM_PPC)
2008
          return NULL;
2009
        break;
2010
 
2011
      default:
2012
        return NULL;
2013
      }
2014
 
2015
    return this->instantiate_target();
2016
  }
2017
 
2018
  Target* do_instantiate_target()
2019
  { return new Target_powerpc<size, big_endian>(); }
2020
};
2021
 
2022
Target_selector_powerpc<32, true> target_selector_ppc32;
2023
Target_selector_powerpc<32, false> target_selector_ppc32le;
2024
Target_selector_powerpc<64, true> target_selector_ppc64;
2025
Target_selector_powerpc<64, false> target_selector_ppc64le;
2026
 
2027
} // End anonymous namespace.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.