OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gold/] [reloc.cc] - Blame information for rev 454

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
// reloc.cc -- relocate input files for gold.
2
 
3
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4
// Written by Ian Lance Taylor <iant@google.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 <algorithm>
26
 
27
#include "workqueue.h"
28
#include "symtab.h"
29
#include "output.h"
30
#include "merge.h"
31
#include "object.h"
32
#include "target-reloc.h"
33
#include "reloc.h"
34
#include "icf.h"
35
 
36
namespace gold
37
{
38
 
39
// Read_relocs methods.
40
 
41
// These tasks just read the relocation information from the file.
42
// After reading it, the start another task to process the
43
// information.  These tasks requires access to the file.
44
 
45
Task_token*
46
Read_relocs::is_runnable()
47
{
48
  return this->object_->is_locked() ? this->object_->token() : NULL;
49
}
50
 
51
// Lock the file.
52
 
53
void
54
Read_relocs::locks(Task_locker* tl)
55
{
56
  tl->add(this, this->object_->token());
57
}
58
 
59
// Read the relocations and then start a Scan_relocs_task.
60
 
61
void
62
Read_relocs::run(Workqueue* workqueue)
63
{
64
  Read_relocs_data *rd = new Read_relocs_data;
65
  this->object_->read_relocs(rd);
66
  this->object_->set_relocs_data(rd);
67
  this->object_->release();
68
 
69
  // If garbage collection or identical comdat folding is desired, we  
70
  // process the relocs first before scanning them.  Scanning of relocs is
71
  // done only after garbage or identical sections is identified.
72
  if (parameters->options().gc_sections()
73
      || parameters->options().icf_enabled())
74
    {
75
      workqueue->queue_next(new Gc_process_relocs(this->options_,
76
                                                  this->symtab_,
77
                                                  this->layout_,
78
                                                  this->object_, rd,
79
                                                  this->symtab_lock_,
80
                                                  this->blocker_));
81
    }
82
  else
83
    {
84
      workqueue->queue_next(new Scan_relocs(this->options_, this->symtab_,
85
                                            this->layout_, this->object_, rd,
86
                                            this->symtab_lock_,
87
                                            this->blocker_));
88
    }
89
}
90
 
91
// Return a debugging name for the task.
92
 
93
std::string
94
Read_relocs::get_name() const
95
{
96
  return "Read_relocs " + this->object_->name();
97
}
98
 
99
// Gc_process_relocs methods.
100
 
101
// These tasks process the relocations read by Read_relocs and 
102
// determine which sections are referenced and which are garbage.
103
// This task is done only when --gc-sections is used.
104
 
105
Task_token*
106
Gc_process_relocs::is_runnable()
107
{
108
  if (this->object_->is_locked())
109
    return this->object_->token();
110
  return NULL;
111
}
112
 
113
void
114
Gc_process_relocs::locks(Task_locker* tl)
115
{
116
  tl->add(this, this->object_->token());
117
  tl->add(this, this->blocker_);
118
}
119
 
120
void
121
Gc_process_relocs::run(Workqueue*)
122
{
123
  this->object_->gc_process_relocs(this->options_, this->symtab_, this->layout_,
124
                     this->rd_);
125
  this->object_->release();
126
}
127
 
128
// Return a debugging name for the task.
129
 
130
std::string
131
Gc_process_relocs::get_name() const
132
{
133
  return "Gc_process_relocs " + this->object_->name();
134
}
135
 
136
// Scan_relocs methods.
137
 
138
// These tasks scan the relocations read by Read_relocs and mark up
139
// the symbol table to indicate which relocations are required.  We
140
// use a lock on the symbol table to keep them from interfering with
141
// each other.
142
 
143
Task_token*
144
Scan_relocs::is_runnable()
145
{
146
  if (!this->symtab_lock_->is_writable())
147
    return this->symtab_lock_;
148
  if (this->object_->is_locked())
149
    return this->object_->token();
150
  return NULL;
151
}
152
 
153
// Return the locks we hold: one on the file, one on the symbol table
154
// and one blocker.
155
 
156
void
157
Scan_relocs::locks(Task_locker* tl)
158
{
159
  tl->add(this, this->object_->token());
160
  tl->add(this, this->symtab_lock_);
161
  tl->add(this, this->blocker_);
162
}
163
 
164
// Scan the relocs.
165
 
166
void
167
Scan_relocs::run(Workqueue*)
168
{
169
  this->object_->scan_relocs(this->options_, this->symtab_, this->layout_,
170
                             this->rd_);
171
  this->object_->release();
172
  delete this->rd_;
173
  this->rd_ = NULL;
174
}
175
 
176
// Return a debugging name for the task.
177
 
178
std::string
179
Scan_relocs::get_name() const
180
{
181
  return "Scan_relocs " + this->object_->name();
182
}
183
 
184
// Relocate_task methods.
185
 
186
// We may have to wait for the output sections to be written.
187
 
188
Task_token*
189
Relocate_task::is_runnable()
190
{
191
  if (this->object_->relocs_must_follow_section_writes()
192
      && this->output_sections_blocker_->is_blocked())
193
    return this->output_sections_blocker_;
194
 
195
  if (this->object_->is_locked())
196
    return this->object_->token();
197
 
198
  return NULL;
199
}
200
 
201
// We want to lock the file while we run.  We want to unblock
202
// INPUT_SECTIONS_BLOCKER and FINAL_BLOCKER when we are done.
203
// INPUT_SECTIONS_BLOCKER may be NULL.
204
 
205
void
206
Relocate_task::locks(Task_locker* tl)
207
{
208
  if (this->input_sections_blocker_ != NULL)
209
    tl->add(this, this->input_sections_blocker_);
210
  tl->add(this, this->final_blocker_);
211
  tl->add(this, this->object_->token());
212
}
213
 
214
// Run the task.
215
 
216
void
217
Relocate_task::run(Workqueue*)
218
{
219
  this->object_->relocate(this->options_, this->symtab_, this->layout_,
220
                          this->of_);
221
 
222
  // This is normally the last thing we will do with an object, so
223
  // uncache all views.
224
  this->object_->clear_view_cache_marks();
225
 
226
  this->object_->release();
227
}
228
 
229
// Return a debugging name for the task.
230
 
231
std::string
232
Relocate_task::get_name() const
233
{
234
  return "Relocate_task " + this->object_->name();
235
}
236
 
237
// Read the relocs and local symbols from the object file and store
238
// the information in RD.
239
 
240
template<int size, bool big_endian>
241
void
242
Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
243
{
244
  rd->relocs.clear();
245
 
246
  unsigned int shnum = this->shnum();
247
  if (shnum == 0)
248
    return;
249
 
250
  rd->relocs.reserve(shnum / 2);
251
 
252
  const Output_sections& out_sections(this->output_sections());
253
  const std::vector<Address>& out_offsets(this->section_offsets_);
254
 
255
  const unsigned char *pshdrs = this->get_view(this->elf_file_.shoff(),
256
                                               shnum * This::shdr_size,
257
                                               true, true);
258
  // Skip the first, dummy, section.
259
  const unsigned char *ps = pshdrs + This::shdr_size;
260
  for (unsigned int i = 1; i < shnum; ++i, ps += This::shdr_size)
261
    {
262
      typename This::Shdr shdr(ps);
263
 
264
      unsigned int sh_type = shdr.get_sh_type();
265
      if (sh_type != elfcpp::SHT_REL && sh_type != elfcpp::SHT_RELA)
266
        continue;
267
 
268
      unsigned int shndx = this->adjust_shndx(shdr.get_sh_info());
269
      if (shndx >= shnum)
270
        {
271
          this->error(_("relocation section %u has bad info %u"),
272
                      i, shndx);
273
          continue;
274
        }
275
 
276
      Output_section* os = out_sections[shndx];
277
      if (os == NULL)
278
        continue;
279
 
280
      // We are scanning relocations in order to fill out the GOT and
281
      // PLT sections.  Relocations for sections which are not
282
      // allocated (typically debugging sections) should not add new
283
      // GOT and PLT entries.  So we skip them unless this is a
284
      // relocatable link or we need to emit relocations.  FIXME: What
285
      // should we do if a linker script maps a section with SHF_ALLOC
286
      // clear to a section with SHF_ALLOC set?
287
      typename This::Shdr secshdr(pshdrs + shndx * This::shdr_size);
288
      bool is_section_allocated = ((secshdr.get_sh_flags() & elfcpp::SHF_ALLOC)
289
                                   != 0);
290
      if (!is_section_allocated
291
          && !parameters->options().relocatable()
292
          && !parameters->options().emit_relocs())
293
        continue;
294
 
295
      if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx_)
296
        {
297
          this->error(_("relocation section %u uses unexpected "
298
                        "symbol table %u"),
299
                      i, this->adjust_shndx(shdr.get_sh_link()));
300
          continue;
301
        }
302
 
303
      off_t sh_size = shdr.get_sh_size();
304
 
305
      unsigned int reloc_size;
306
      if (sh_type == elfcpp::SHT_REL)
307
        reloc_size = elfcpp::Elf_sizes<size>::rel_size;
308
      else
309
        reloc_size = elfcpp::Elf_sizes<size>::rela_size;
310
      if (reloc_size != shdr.get_sh_entsize())
311
        {
312
          this->error(_("unexpected entsize for reloc section %u: %lu != %u"),
313
                      i, static_cast<unsigned long>(shdr.get_sh_entsize()),
314
                      reloc_size);
315
          continue;
316
        }
317
 
318
      size_t reloc_count = sh_size / reloc_size;
319
      if (static_cast<off_t>(reloc_count * reloc_size) != sh_size)
320
        {
321
          this->error(_("reloc section %u size %lu uneven"),
322
                      i, static_cast<unsigned long>(sh_size));
323
          continue;
324
        }
325
 
326
      rd->relocs.push_back(Section_relocs());
327
      Section_relocs& sr(rd->relocs.back());
328
      sr.reloc_shndx = i;
329
      sr.data_shndx = shndx;
330
      sr.contents = this->get_lasting_view(shdr.get_sh_offset(), sh_size,
331
                                           true, true);
332
      sr.sh_type = sh_type;
333
      sr.reloc_count = reloc_count;
334
      sr.output_section = os;
335
      sr.needs_special_offset_handling = out_offsets[shndx] == invalid_address;
336
      sr.is_data_section_allocated = is_section_allocated;
337
    }
338
 
339
  // Read the local symbols.
340
  gold_assert(this->symtab_shndx_ != -1U);
341
  if (this->symtab_shndx_ == 0 || this->local_symbol_count_ == 0)
342
    rd->local_symbols = NULL;
343
  else
344
    {
345
      typename This::Shdr symtabshdr(pshdrs
346
                                     + this->symtab_shndx_ * This::shdr_size);
347
      gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
348
      const int sym_size = This::sym_size;
349
      const unsigned int loccount = this->local_symbol_count_;
350
      gold_assert(loccount == symtabshdr.get_sh_info());
351
      off_t locsize = loccount * sym_size;
352
      rd->local_symbols = this->get_lasting_view(symtabshdr.get_sh_offset(),
353
                                                 locsize, true, true);
354
    }
355
}
356
 
357
// Process the relocs to generate mappings from source sections to referenced
358
// sections.  This is used during garbage colletion to determine garbage 
359
// sections.
360
 
361
template<int size, bool big_endian>
362
void
363
Sized_relobj<size, big_endian>::do_gc_process_relocs(const General_options& options,
364
                                               Symbol_table* symtab,
365
                                               Layout* layout,
366
                                               Read_relocs_data* rd)
367
{
368
  Sized_target<size, big_endian>* target =
369
    parameters->sized_target<size, big_endian>();
370
 
371
  const unsigned char* local_symbols;
372
  if (rd->local_symbols == NULL)
373
    local_symbols = NULL;
374
  else
375
    local_symbols = rd->local_symbols->data();
376
 
377
  for (Read_relocs_data::Relocs_list::iterator p = rd->relocs.begin();
378
       p != rd->relocs.end();
379
       ++p)
380
    {
381
      if (!parameters->options().relocatable())
382
          {
383
            // As noted above, when not generating an object file, we
384
            // only scan allocated sections.  We may see a non-allocated
385
            // section here if we are emitting relocs.
386
            if (p->is_data_section_allocated)
387
              target->gc_process_relocs(options, symtab, layout, this,
388
                                        p->data_shndx, p->sh_type,
389
                                        p->contents->data(), p->reloc_count,
390
                                        p->output_section,
391
                                        p->needs_special_offset_handling,
392
                                        this->local_symbol_count_,
393
                                        local_symbols);
394
        }
395
    }
396
}
397
 
398
 
399
// Scan the relocs and adjust the symbol table.  This looks for
400
// relocations which require GOT/PLT/COPY relocations.
401
 
402
template<int size, bool big_endian>
403
void
404
Sized_relobj<size, big_endian>::do_scan_relocs(const General_options& options,
405
                                               Symbol_table* symtab,
406
                                               Layout* layout,
407
                                               Read_relocs_data* rd)
408
{
409
  Sized_target<size, big_endian>* target =
410
    parameters->sized_target<size, big_endian>();
411
 
412
  const unsigned char* local_symbols;
413
  if (rd->local_symbols == NULL)
414
    local_symbols = NULL;
415
  else
416
    local_symbols = rd->local_symbols->data();
417
 
418
  for (Read_relocs_data::Relocs_list::iterator p = rd->relocs.begin();
419
       p != rd->relocs.end();
420
       ++p)
421
    {
422
      // When garbage collection is on, unreferenced sections are not included
423
      // in the link that would have been included normally. This is known only
424
      // after Read_relocs hence this check has to be done again.
425
      if (parameters->options().gc_sections()
426
          || parameters->options().icf_enabled())
427
        {
428
          if (p->output_section == NULL)
429
            continue;
430
        }
431
      if (!parameters->options().relocatable())
432
        {
433
          // As noted above, when not generating an object file, we
434
          // only scan allocated sections.  We may see a non-allocated
435
          // section here if we are emitting relocs.
436
          if (p->is_data_section_allocated)
437
            target->scan_relocs(options, symtab, layout, this, p->data_shndx,
438
                                p->sh_type, p->contents->data(),
439
                                p->reloc_count, p->output_section,
440
                                p->needs_special_offset_handling,
441
                                this->local_symbol_count_,
442
                                local_symbols);
443
          if (parameters->options().emit_relocs())
444
            this->emit_relocs_scan(options, symtab, layout, local_symbols, p);
445
        }
446
      else
447
        {
448
          Relocatable_relocs* rr = this->relocatable_relocs(p->reloc_shndx);
449
          gold_assert(rr != NULL);
450
          rr->set_reloc_count(p->reloc_count);
451
          target->scan_relocatable_relocs(options, symtab, layout, this,
452
                                          p->data_shndx, p->sh_type,
453
                                          p->contents->data(),
454
                                          p->reloc_count,
455
                                          p->output_section,
456
                                          p->needs_special_offset_handling,
457
                                          this->local_symbol_count_,
458
                                          local_symbols,
459
                                          rr);
460
        }
461
 
462
      delete p->contents;
463
      p->contents = NULL;
464
    }
465
 
466
  if (rd->local_symbols != NULL)
467
    {
468
      delete rd->local_symbols;
469
      rd->local_symbols = NULL;
470
    }
471
}
472
 
473
// This is a strategy class we use when scanning for --emit-relocs.
474
 
475
template<int sh_type>
476
class Emit_relocs_strategy
477
{
478
 public:
479
  // A local non-section symbol.
480
  inline Relocatable_relocs::Reloc_strategy
481
  local_non_section_strategy(unsigned int, Relobj*, unsigned int)
482
  { return Relocatable_relocs::RELOC_COPY; }
483
 
484
  // A local section symbol.
485
  inline Relocatable_relocs::Reloc_strategy
486
  local_section_strategy(unsigned int, Relobj*)
487
  {
488
    if (sh_type == elfcpp::SHT_RELA)
489
      return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
490
    else
491
      {
492
        // The addend is stored in the section contents.  Since this
493
        // is not a relocatable link, we are going to apply the
494
        // relocation contents to the section as usual.  This means
495
        // that we have no way to record the original addend.  If the
496
        // original addend is not zero, there is basically no way for
497
        // the user to handle this correctly.  Caveat emptor.
498
        return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
499
      }
500
  }
501
 
502
  // A global symbol.
503
  inline Relocatable_relocs::Reloc_strategy
504
  global_strategy(unsigned int, Relobj*, unsigned int)
505
  { return Relocatable_relocs::RELOC_COPY; }
506
};
507
 
508
// Scan the input relocations for --emit-relocs.
509
 
510
template<int size, bool big_endian>
511
void
512
Sized_relobj<size, big_endian>::emit_relocs_scan(
513
    const General_options& options,
514
    Symbol_table* symtab,
515
    Layout* layout,
516
    const unsigned char* plocal_syms,
517
    const Read_relocs_data::Relocs_list::iterator& p)
518
{
519
  Relocatable_relocs* rr = this->relocatable_relocs(p->reloc_shndx);
520
  gold_assert(rr != NULL);
521
  rr->set_reloc_count(p->reloc_count);
522
 
523
  if (p->sh_type == elfcpp::SHT_REL)
524
    this->emit_relocs_scan_reltype<elfcpp::SHT_REL>(options, symtab, layout,
525
                                                    plocal_syms, p, rr);
526
  else
527
    {
528
      gold_assert(p->sh_type == elfcpp::SHT_RELA);
529
      this->emit_relocs_scan_reltype<elfcpp::SHT_RELA>(options, symtab,
530
                                                       layout, plocal_syms, p,
531
                                                       rr);
532
    }
533
}
534
 
535
// Scan the input relocation for --emit-relocs, templatized on the
536
// type of the relocation section.
537
 
538
template<int size, bool big_endian>
539
template<int sh_type>
540
void
541
Sized_relobj<size, big_endian>::emit_relocs_scan_reltype(
542
    const General_options& options,
543
    Symbol_table* symtab,
544
    Layout* layout,
545
    const unsigned char* plocal_syms,
546
    const Read_relocs_data::Relocs_list::iterator& p,
547
    Relocatable_relocs* rr)
548
{
549
  scan_relocatable_relocs<size, big_endian, sh_type,
550
                          Emit_relocs_strategy<sh_type> >(
551
    options,
552
    symtab,
553
    layout,
554
    this,
555
    p->data_shndx,
556
    p->contents->data(),
557
    p->reloc_count,
558
    p->output_section,
559
    p->needs_special_offset_handling,
560
    this->local_symbol_count_,
561
    plocal_syms,
562
    rr);
563
}
564
 
565
// Relocate the input sections and write out the local symbols.
566
 
567
template<int size, bool big_endian>
568
void
569
Sized_relobj<size, big_endian>::do_relocate(const General_options& options,
570
                                            const Symbol_table* symtab,
571
                                            const Layout* layout,
572
                                            Output_file* of)
573
{
574
  unsigned int shnum = this->shnum();
575
 
576
  // Read the section headers.
577
  const unsigned char* pshdrs = this->get_view(this->elf_file_.shoff(),
578
                                               shnum * This::shdr_size,
579
                                               true, true);
580
 
581
  Views views;
582
  views.resize(shnum);
583
 
584
  // Make two passes over the sections.  The first one copies the
585
  // section data to the output file.  The second one applies
586
  // relocations.
587
 
588
  this->write_sections(pshdrs, of, &views);
589
 
590
  // To speed up relocations, we set up hash tables for fast lookup of
591
  // input offsets to output addresses.
592
  this->initialize_input_to_output_maps();
593
 
594
  // Apply relocations.
595
 
596
  this->relocate_sections(options, symtab, layout, pshdrs, &views);
597
 
598
  // After we've done the relocations, we release the hash tables,
599
  // since we no longer need them.
600
  this->free_input_to_output_maps();
601
 
602
  // Write out the accumulated views.
603
  for (unsigned int i = 1; i < shnum; ++i)
604
    {
605
      if (views[i].view != NULL)
606
        {
607
          if (!views[i].is_postprocessing_view)
608
            {
609
              if (views[i].is_input_output_view)
610
                of->write_input_output_view(views[i].offset,
611
                                            views[i].view_size,
612
                                            views[i].view);
613
              else
614
                of->write_output_view(views[i].offset, views[i].view_size,
615
                                      views[i].view);
616
            }
617
        }
618
    }
619
 
620
  // Write out the local symbols.
621
  this->write_local_symbols(of, layout->sympool(), layout->dynpool(),
622
                            layout->symtab_xindex(), layout->dynsym_xindex());
623
 
624
  // We should no longer need the local symbol values.
625
  this->clear_local_symbols();
626
}
627
 
628
// Sort a Read_multiple vector by file offset.
629
struct Read_multiple_compare
630
{
631
  inline bool
632
  operator()(const File_read::Read_multiple_entry& rme1,
633
             const File_read::Read_multiple_entry& rme2) const
634
  { return rme1.file_offset < rme2.file_offset; }
635
};
636
 
637
// Write section data to the output file.  PSHDRS points to the
638
// section headers.  Record the views in *PVIEWS for use when
639
// relocating.
640
 
641
template<int size, bool big_endian>
642
void
643
Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
644
                                               Output_file* of,
645
                                               Views* pviews)
646
{
647
  unsigned int shnum = this->shnum();
648
  const Output_sections& out_sections(this->output_sections());
649
  const std::vector<Address>& out_offsets(this->section_offsets_);
650
 
651
  File_read::Read_multiple rm;
652
  bool is_sorted = true;
653
 
654
  const unsigned char* p = pshdrs + This::shdr_size;
655
  for (unsigned int i = 1; i < shnum; ++i, p += This::shdr_size)
656
    {
657
      View_size* pvs = &(*pviews)[i];
658
 
659
      pvs->view = NULL;
660
 
661
      const Output_section* os = out_sections[i];
662
      if (os == NULL)
663
        continue;
664
      Address output_offset = out_offsets[i];
665
 
666
      typename This::Shdr shdr(p);
667
 
668
      if (shdr.get_sh_type() == elfcpp::SHT_NOBITS)
669
        continue;
670
 
671
      if ((parameters->options().relocatable()
672
           || parameters->options().emit_relocs())
673
          && (shdr.get_sh_type() == elfcpp::SHT_REL
674
              || shdr.get_sh_type() == elfcpp::SHT_RELA)
675
          && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
676
        {
677
          // This is a reloc section in a relocatable link or when
678
          // emitting relocs.  We don't need to read the input file.
679
          // The size and file offset are stored in the
680
          // Relocatable_relocs structure.
681
          Relocatable_relocs* rr = this->relocatable_relocs(i);
682
          gold_assert(rr != NULL);
683
          Output_data* posd = rr->output_data();
684
          gold_assert(posd != NULL);
685
 
686
          pvs->offset = posd->offset();
687
          pvs->view_size = posd->data_size();
688
          pvs->view = of->get_output_view(pvs->offset, pvs->view_size);
689
          pvs->address = posd->address();
690
          pvs->is_input_output_view = false;
691
          pvs->is_postprocessing_view = false;
692
 
693
          continue;
694
        }
695
 
696
      // In the normal case, this input section is simply mapped to
697
      // the output section at offset OUTPUT_OFFSET.
698
 
699
      // However, if OUTPUT_OFFSET == INVALID_ADDRESS, then input data is
700
      // handled specially--e.g., a .eh_frame section.  The relocation
701
      // routines need to check for each reloc where it should be
702
      // applied.  For this case, we need an input/output view for the
703
      // entire contents of the section in the output file.  We don't
704
      // want to copy the contents of the input section to the output
705
      // section; the output section contents were already written,
706
      // and we waited for them in Relocate_task::is_runnable because
707
      // relocs_must_follow_section_writes is set for the object.
708
 
709
      // Regardless of which of the above cases is true, we have to
710
      // check requires_postprocessing of the output section.  If that
711
      // is false, then we work with views of the output file
712
      // directly.  If it is true, then we work with a separate
713
      // buffer, and the output section is responsible for writing the
714
      // final data to the output file.
715
 
716
      off_t output_section_offset;
717
      Address output_section_size;
718
      if (!os->requires_postprocessing())
719
        {
720
          output_section_offset = os->offset();
721
          output_section_size = convert_types<Address, off_t>(os->data_size());
722
        }
723
      else
724
        {
725
          output_section_offset = 0;
726
          output_section_size =
727
              convert_types<Address, off_t>(os->postprocessing_buffer_size());
728
        }
729
 
730
      off_t view_start;
731
      section_size_type view_size;
732
      if (output_offset != invalid_address)
733
        {
734
          view_start = output_section_offset + output_offset;
735
          view_size = convert_to_section_size_type(shdr.get_sh_size());
736
        }
737
      else
738
        {
739
          view_start = output_section_offset;
740
          view_size = convert_to_section_size_type(output_section_size);
741
        }
742
 
743
      if (view_size == 0)
744
        continue;
745
 
746
      gold_assert(output_offset == invalid_address
747
                  || output_offset + view_size <= output_section_size);
748
 
749
      unsigned char* view;
750
      if (os->requires_postprocessing())
751
        {
752
          unsigned char* buffer = os->postprocessing_buffer();
753
          view = buffer + view_start;
754
          if (output_offset != invalid_address)
755
            {
756
              off_t sh_offset = shdr.get_sh_offset();
757
              if (!rm.empty() && rm.back().file_offset > sh_offset)
758
                is_sorted = false;
759
              rm.push_back(File_read::Read_multiple_entry(sh_offset,
760
                                                          view_size, view));
761
            }
762
        }
763
      else
764
        {
765
          if (output_offset == invalid_address)
766
            view = of->get_input_output_view(view_start, view_size);
767
          else
768
            {
769
              view = of->get_output_view(view_start, view_size);
770
              off_t sh_offset = shdr.get_sh_offset();
771
              if (!rm.empty() && rm.back().file_offset > sh_offset)
772
                is_sorted = false;
773
              rm.push_back(File_read::Read_multiple_entry(sh_offset,
774
                                                          view_size, view));
775
            }
776
        }
777
 
778
      pvs->view = view;
779
      pvs->address = os->address();
780
      if (output_offset != invalid_address)
781
        pvs->address += output_offset;
782
      pvs->offset = view_start;
783
      pvs->view_size = view_size;
784
      pvs->is_input_output_view = output_offset == invalid_address;
785
      pvs->is_postprocessing_view = os->requires_postprocessing();
786
    }
787
 
788
  // Actually read the data.
789
  if (!rm.empty())
790
    {
791
      if (!is_sorted)
792
        std::sort(rm.begin(), rm.end(), Read_multiple_compare());
793
      this->read_multiple(rm);
794
    }
795
}
796
 
797
// Relocate section data.  VIEWS points to the section data as views
798
// in the output file.
799
 
800
template<int size, bool big_endian>
801
void
802
Sized_relobj<size, big_endian>::relocate_sections(
803
    const General_options& options,
804
    const Symbol_table* symtab,
805
    const Layout* layout,
806
    const unsigned char* pshdrs,
807
    Views* pviews)
808
{
809
  unsigned int shnum = this->shnum();
810
  Sized_target<size, big_endian>* target =
811
    parameters->sized_target<size, big_endian>();
812
 
813
  const Output_sections& out_sections(this->output_sections());
814
  const std::vector<Address>& out_offsets(this->section_offsets_);
815
 
816
  Relocate_info<size, big_endian> relinfo;
817
  relinfo.options = &options;
818
  relinfo.symtab = symtab;
819
  relinfo.layout = layout;
820
  relinfo.object = this;
821
 
822
  const unsigned char* p = pshdrs + This::shdr_size;
823
  for (unsigned int i = 1; i < shnum; ++i, p += This::shdr_size)
824
    {
825
      typename This::Shdr shdr(p);
826
 
827
      unsigned int sh_type = shdr.get_sh_type();
828
      if (sh_type != elfcpp::SHT_REL && sh_type != elfcpp::SHT_RELA)
829
        continue;
830
 
831
      off_t sh_size = shdr.get_sh_size();
832
      if (sh_size == 0)
833
        continue;
834
 
835
      unsigned int index = this->adjust_shndx(shdr.get_sh_info());
836
      if (index >= this->shnum())
837
        {
838
          this->error(_("relocation section %u has bad info %u"),
839
                      i, index);
840
          continue;
841
        }
842
 
843
      Output_section* os = out_sections[index];
844
      if (os == NULL)
845
        {
846
          // This relocation section is against a section which we
847
          // discarded.
848
          continue;
849
        }
850
      Address output_offset = out_offsets[index];
851
 
852
      gold_assert((*pviews)[index].view != NULL);
853
      if (parameters->options().relocatable())
854
        gold_assert((*pviews)[i].view != NULL);
855
 
856
      if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx_)
857
        {
858
          gold_error(_("relocation section %u uses unexpected "
859
                       "symbol table %u"),
860
                     i, this->adjust_shndx(shdr.get_sh_link()));
861
          continue;
862
        }
863
 
864
      const unsigned char* prelocs = this->get_view(shdr.get_sh_offset(),
865
                                                    sh_size, true, false);
866
 
867
      unsigned int reloc_size;
868
      if (sh_type == elfcpp::SHT_REL)
869
        reloc_size = elfcpp::Elf_sizes<size>::rel_size;
870
      else
871
        reloc_size = elfcpp::Elf_sizes<size>::rela_size;
872
 
873
      if (reloc_size != shdr.get_sh_entsize())
874
        {
875
          gold_error(_("unexpected entsize for reloc section %u: %lu != %u"),
876
                     i, static_cast<unsigned long>(shdr.get_sh_entsize()),
877
                     reloc_size);
878
          continue;
879
        }
880
 
881
      size_t reloc_count = sh_size / reloc_size;
882
      if (static_cast<off_t>(reloc_count * reloc_size) != sh_size)
883
        {
884
          gold_error(_("reloc section %u size %lu uneven"),
885
                     i, static_cast<unsigned long>(sh_size));
886
          continue;
887
        }
888
 
889
      gold_assert(output_offset != invalid_address
890
                  || this->relocs_must_follow_section_writes());
891
 
892
      relinfo.reloc_shndx = i;
893
      relinfo.reloc_shdr = p;
894
      relinfo.data_shndx = index;
895
      relinfo.data_shdr = pshdrs + index * This::shdr_size;
896
      unsigned char* view = (*pviews)[index].view;
897
      Address address = (*pviews)[index].address;
898
      section_size_type view_size = (*pviews)[index].view_size;
899
 
900
      Reloc_symbol_changes* reloc_map = NULL;
901
      if (this->uses_split_stack() && output_offset != invalid_address)
902
        {
903
          typename This::Shdr data_shdr(pshdrs + index * This::shdr_size);
904
          if ((data_shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
905
            this->split_stack_adjust(symtab, pshdrs, sh_type, index,
906
                                     prelocs, reloc_count, view, view_size,
907
                                     &reloc_map);
908
        }
909
 
910
      if (!parameters->options().relocatable())
911
        {
912
          target->relocate_section(&relinfo, sh_type, prelocs, reloc_count, os,
913
                                   output_offset == invalid_address,
914
                                   view, address, view_size, reloc_map);
915
          if (parameters->options().emit_relocs())
916
            this->emit_relocs(&relinfo, i, sh_type, prelocs, reloc_count,
917
                              os, output_offset, view, address, view_size,
918
                              (*pviews)[i].view, (*pviews)[i].view_size);
919
        }
920
      else
921
        {
922
          Relocatable_relocs* rr = this->relocatable_relocs(i);
923
          target->relocate_for_relocatable(&relinfo, sh_type, prelocs,
924
                                           reloc_count, os, output_offset, rr,
925
                                           view, address, view_size,
926
                                           (*pviews)[i].view,
927
                                           (*pviews)[i].view_size);
928
        }
929
    }
930
}
931
 
932
// Emit the relocs for --emit-relocs.
933
 
934
template<int size, bool big_endian>
935
void
936
Sized_relobj<size, big_endian>::emit_relocs(
937
    const Relocate_info<size, big_endian>* relinfo,
938
    unsigned int i,
939
    unsigned int sh_type,
940
    const unsigned char* prelocs,
941
    size_t reloc_count,
942
    Output_section* output_section,
943
    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
944
    unsigned char* view,
945
    typename elfcpp::Elf_types<size>::Elf_Addr address,
946
    section_size_type view_size,
947
    unsigned char* reloc_view,
948
    section_size_type reloc_view_size)
949
{
950
  if (sh_type == elfcpp::SHT_REL)
951
    this->emit_relocs_reltype<elfcpp::SHT_REL>(relinfo, i, prelocs,
952
                                               reloc_count, output_section,
953
                                               offset_in_output_section,
954
                                               view, address, view_size,
955
                                               reloc_view, reloc_view_size);
956
  else
957
    {
958
      gold_assert(sh_type == elfcpp::SHT_RELA);
959
      this->emit_relocs_reltype<elfcpp::SHT_RELA>(relinfo, i, prelocs,
960
                                                  reloc_count, output_section,
961
                                                  offset_in_output_section,
962
                                                  view, address, view_size,
963
                                                  reloc_view, reloc_view_size);
964
    }
965
}
966
 
967
// Emit the relocs for --emit-relocs, templatized on the type of the
968
// relocation section.
969
 
970
template<int size, bool big_endian>
971
template<int sh_type>
972
void
973
Sized_relobj<size, big_endian>::emit_relocs_reltype(
974
    const Relocate_info<size, big_endian>* relinfo,
975
    unsigned int i,
976
    const unsigned char* prelocs,
977
    size_t reloc_count,
978
    Output_section* output_section,
979
    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
980
    unsigned char* view,
981
    typename elfcpp::Elf_types<size>::Elf_Addr address,
982
    section_size_type view_size,
983
    unsigned char* reloc_view,
984
    section_size_type reloc_view_size)
985
{
986
  const Relocatable_relocs* rr = this->relocatable_relocs(i);
987
  relocate_for_relocatable<size, big_endian, sh_type>(
988
    relinfo,
989
    prelocs,
990
    reloc_count,
991
    output_section,
992
    offset_in_output_section,
993
    rr,
994
    view,
995
    address,
996
    view_size,
997
    reloc_view,
998
    reloc_view_size);
999
}
1000
 
1001
// Create merge hash tables for the local symbols.  These are used to
1002
// speed up relocations.
1003
 
1004
template<int size, bool big_endian>
1005
void
1006
Sized_relobj<size, big_endian>::initialize_input_to_output_maps()
1007
{
1008
  const unsigned int loccount = this->local_symbol_count_;
1009
  for (unsigned int i = 1; i < loccount; ++i)
1010
    {
1011
      Symbol_value<size>& lv(this->local_values_[i]);
1012
      lv.initialize_input_to_output_map(this);
1013
    }
1014
}
1015
 
1016
// Free merge hash tables for the local symbols.
1017
 
1018
template<int size, bool big_endian>
1019
void
1020
Sized_relobj<size, big_endian>::free_input_to_output_maps()
1021
{
1022
  const unsigned int loccount = this->local_symbol_count_;
1023
  for (unsigned int i = 1; i < loccount; ++i)
1024
    {
1025
      Symbol_value<size>& lv(this->local_values_[i]);
1026
      lv.free_input_to_output_map();
1027
    }
1028
}
1029
 
1030
// If an object was compiled with -fsplit-stack, this is called to
1031
// check whether any relocations refer to functions defined in objects
1032
// which were not compiled with -fsplit-stack.  If they were, then we
1033
// need to apply some target-specific adjustments to request
1034
// additional stack space.
1035
 
1036
template<int size, bool big_endian>
1037
void
1038
Sized_relobj<size, big_endian>::split_stack_adjust(
1039
    const Symbol_table* symtab,
1040
    const unsigned char* pshdrs,
1041
    unsigned int sh_type,
1042
    unsigned int shndx,
1043
    const unsigned char* prelocs,
1044
    size_t reloc_count,
1045
    unsigned char* view,
1046
    section_size_type view_size,
1047
    Reloc_symbol_changes** reloc_map)
1048
{
1049
  if (sh_type == elfcpp::SHT_REL)
1050
    this->split_stack_adjust_reltype<elfcpp::SHT_REL>(symtab, pshdrs, shndx,
1051
                                                      prelocs, reloc_count,
1052
                                                      view, view_size,
1053
                                                      reloc_map);
1054
  else
1055
    {
1056
      gold_assert(sh_type == elfcpp::SHT_RELA);
1057
      this->split_stack_adjust_reltype<elfcpp::SHT_RELA>(symtab, pshdrs, shndx,
1058
                                                         prelocs, reloc_count,
1059
                                                         view, view_size,
1060
                                                         reloc_map);
1061
    }
1062
}
1063
 
1064
// Adjust for -fsplit-stack, templatized on the type of the relocation
1065
// section.
1066
 
1067
template<int size, bool big_endian>
1068
template<int sh_type>
1069
void
1070
Sized_relobj<size, big_endian>::split_stack_adjust_reltype(
1071
    const Symbol_table* symtab,
1072
    const unsigned char* pshdrs,
1073
    unsigned int shndx,
1074
    const unsigned char* prelocs,
1075
    size_t reloc_count,
1076
    unsigned char* view,
1077
    section_size_type view_size,
1078
    Reloc_symbol_changes** reloc_map)
1079
{
1080
  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
1081
  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
1082
 
1083
  size_t local_count = this->local_symbol_count();
1084
 
1085
  std::vector<section_offset_type> non_split_refs;
1086
 
1087
  const unsigned char* pr = prelocs;
1088
  for (size_t i = 0; i < reloc_count; ++i, pr += reloc_size)
1089
    {
1090
      Reltype reloc(pr);
1091
 
1092
      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
1093
      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
1094
      if (r_sym < local_count)
1095
        continue;
1096
 
1097
      const Symbol* gsym = this->global_symbol(r_sym);
1098
      gold_assert(gsym != NULL);
1099
      if (gsym->is_forwarder())
1100
        gsym = symtab->resolve_forwards(gsym);
1101
 
1102
      // See if this relocation refers to a function defined in an
1103
      // object compiled without -fsplit-stack.  Note that we don't
1104
      // care about the type of relocation--this means that in some
1105
      // cases we will ask for a large stack unnecessarily, but this
1106
      // is not fatal.  FIXME: Some targets have symbols which are
1107
      // functions but are not type STT_FUNC, e.g., STT_ARM_TFUNC.
1108
      if (gsym->type() == elfcpp::STT_FUNC
1109
          && !gsym->is_undefined()
1110
          && gsym->source() == Symbol::FROM_OBJECT
1111
          && !gsym->object()->uses_split_stack())
1112
        {
1113
          section_offset_type offset =
1114
            convert_to_section_size_type(reloc.get_r_offset());
1115
          non_split_refs.push_back(offset);
1116
        }
1117
    }
1118
 
1119
  if (non_split_refs.empty())
1120
    return;
1121
 
1122
  // At this point, every entry in NON_SPLIT_REFS indicates a
1123
  // relocation which refers to a function in an object compiled
1124
  // without -fsplit-stack.  We now have to convert that list into a
1125
  // set of offsets to functions.  First, we find all the functions.
1126
 
1127
  Function_offsets function_offsets;
1128
  this->find_functions(pshdrs, shndx, &function_offsets);
1129
  if (function_offsets.empty())
1130
    return;
1131
 
1132
  // Now get a list of the function with references to non split-stack
1133
  // code.
1134
 
1135
  Function_offsets calls_non_split;
1136
  for (std::vector<section_offset_type>::const_iterator p
1137
         = non_split_refs.begin();
1138
       p != non_split_refs.end();
1139
       ++p)
1140
    {
1141
      Function_offsets::const_iterator low = function_offsets.lower_bound(*p);
1142
      if (low == function_offsets.end())
1143
        --low;
1144
      else if (low->first == *p)
1145
        ;
1146
      else if (low == function_offsets.begin())
1147
        continue;
1148
      else
1149
        --low;
1150
 
1151
      calls_non_split.insert(*low);
1152
    }
1153
  if (calls_non_split.empty())
1154
    return;
1155
 
1156
  // Now we have a set of functions to adjust.  The adjustments are
1157
  // target specific.  Besides changing the output section view
1158
  // however, it likes, the target may request a relocation change
1159
  // from one global symbol name to another.
1160
 
1161
  for (Function_offsets::const_iterator p = calls_non_split.begin();
1162
       p != calls_non_split.end();
1163
       ++p)
1164
    {
1165
      std::string from;
1166
      std::string to;
1167
      parameters->target().calls_non_split(this, shndx, p->first, p->second,
1168
                                           view, view_size, &from, &to);
1169
      if (!from.empty())
1170
        {
1171
          gold_assert(!to.empty());
1172
          Symbol* tosym = NULL;
1173
 
1174
          // Find relocations in the relevant function which are for
1175
          // FROM.
1176
          pr = prelocs;
1177
          for (size_t i = 0; i < reloc_count; ++i, pr += reloc_size)
1178
            {
1179
              Reltype reloc(pr);
1180
 
1181
              typename elfcpp::Elf_types<size>::Elf_WXword r_info =
1182
                reloc.get_r_info();
1183
              unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
1184
              if (r_sym < local_count)
1185
                continue;
1186
 
1187
              section_offset_type offset =
1188
                convert_to_section_size_type(reloc.get_r_offset());
1189
              if (offset < p->first
1190
                  || (offset
1191
                      >= (p->first
1192
                          + static_cast<section_offset_type>(p->second))))
1193
                continue;
1194
 
1195
              const Symbol* gsym = this->global_symbol(r_sym);
1196
              if (from == gsym->name())
1197
                {
1198
                  if (tosym == NULL)
1199
                    {
1200
                      tosym = symtab->lookup(to.c_str());
1201
                      if (tosym == NULL)
1202
                        {
1203
                          this->error(_("could not convert call "
1204
                                        "to '%s' to '%s'"),
1205
                                      from.c_str(), to.c_str());
1206
                          break;
1207
                        }
1208
                    }
1209
 
1210
                  if (*reloc_map == NULL)
1211
                    *reloc_map = new Reloc_symbol_changes(reloc_count);
1212
                  (*reloc_map)->set(i, tosym);
1213
                }
1214
            }
1215
        }
1216
    }
1217
}
1218
 
1219
// Find all the function in this object defined in section SHNDX.
1220
// Store their offsets in the section in FUNCTION_OFFSETS.
1221
 
1222
template<int size, bool big_endian>
1223
void
1224
Sized_relobj<size, big_endian>::find_functions(
1225
    const unsigned char* pshdrs,
1226
    unsigned int shndx,
1227
    Sized_relobj<size, big_endian>::Function_offsets* function_offsets)
1228
{
1229
  // We need to read the symbols to find the functions.  If we wanted
1230
  // to, we could cache reading the symbols across all sections in the
1231
  // object.
1232
  const unsigned int symtab_shndx = this->symtab_shndx_;
1233
  typename This::Shdr symtabshdr(pshdrs + symtab_shndx * This::shdr_size);
1234
  gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
1235
 
1236
  typename elfcpp::Elf_types<size>::Elf_WXword sh_size =
1237
    symtabshdr.get_sh_size();
1238
  const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
1239
                                              sh_size, true, true);
1240
 
1241
  const int sym_size = This::sym_size;
1242
  const unsigned int symcount = sh_size / sym_size;
1243
  for (unsigned int i = 0; i < symcount; ++i, psyms += sym_size)
1244
    {
1245
      typename elfcpp::Sym<size, big_endian> isym(psyms);
1246
 
1247
      // FIXME: Some targets can have functions which do not have type
1248
      // STT_FUNC, e.g., STT_ARM_TFUNC.
1249
      if (isym.get_st_type() != elfcpp::STT_FUNC
1250
          || isym.get_st_size() == 0)
1251
        continue;
1252
 
1253
      bool is_ordinary;
1254
      unsigned int sym_shndx = this->adjust_sym_shndx(i, isym.get_st_shndx(),
1255
                                                      &is_ordinary);
1256
      if (!is_ordinary || sym_shndx != shndx)
1257
        continue;
1258
 
1259
      section_offset_type value =
1260
        convert_to_section_size_type(isym.get_st_value());
1261
      section_size_type fnsize =
1262
        convert_to_section_size_type(isym.get_st_size());
1263
 
1264
      (*function_offsets)[value] = fnsize;
1265
    }
1266
}
1267
 
1268
// Class Merged_symbol_value.
1269
 
1270
template<int size>
1271
void
1272
Merged_symbol_value<size>::initialize_input_to_output_map(
1273
    const Relobj* object,
1274
    unsigned int input_shndx)
1275
{
1276
  Object_merge_map* map = object->merge_map();
1277
  map->initialize_input_to_output_map<size>(input_shndx,
1278
                                            this->output_start_address_,
1279
                                            &this->output_addresses_);
1280
}
1281
 
1282
// Get the output value corresponding to an input offset if we
1283
// couldn't find it in the hash table.
1284
 
1285
template<int size>
1286
typename elfcpp::Elf_types<size>::Elf_Addr
1287
Merged_symbol_value<size>::value_from_output_section(
1288
    const Relobj* object,
1289
    unsigned int input_shndx,
1290
    typename elfcpp::Elf_types<size>::Elf_Addr input_offset) const
1291
{
1292
  section_offset_type output_offset;
1293
  bool found = object->merge_map()->get_output_offset(NULL, input_shndx,
1294
                                                      input_offset,
1295
                                                      &output_offset);
1296
 
1297
  // If this assertion fails, it means that some relocation was
1298
  // against a portion of an input merge section which we didn't map
1299
  // to the output file and we didn't explicitly discard.  We should
1300
  // always map all portions of input merge sections.
1301
  gold_assert(found);
1302
 
1303
  if (output_offset == -1)
1304
    return 0;
1305
  else
1306
    return this->output_start_address_ + output_offset;
1307
}
1308
 
1309
// Track_relocs methods.
1310
 
1311
// Initialize the class to track the relocs.  This gets the object,
1312
// the reloc section index, and the type of the relocs.  This returns
1313
// false if something goes wrong.
1314
 
1315
template<int size, bool big_endian>
1316
bool
1317
Track_relocs<size, big_endian>::initialize(
1318
    Object* object,
1319
    unsigned int reloc_shndx,
1320
    unsigned int reloc_type)
1321
{
1322
  // If RELOC_SHNDX is -1U, it means there is more than one reloc
1323
  // section for the .eh_frame section.  We can't handle that case.
1324
  if (reloc_shndx == -1U)
1325
    return false;
1326
 
1327
  // If RELOC_SHNDX is 0, there is no reloc section.
1328
  if (reloc_shndx == 0)
1329
    return true;
1330
 
1331
  // Get the contents of the reloc section.
1332
  this->prelocs_ = object->section_contents(reloc_shndx, &this->len_, false);
1333
 
1334
  if (reloc_type == elfcpp::SHT_REL)
1335
    this->reloc_size_ = elfcpp::Elf_sizes<size>::rel_size;
1336
  else if (reloc_type == elfcpp::SHT_RELA)
1337
    this->reloc_size_ = elfcpp::Elf_sizes<size>::rela_size;
1338
  else
1339
    gold_unreachable();
1340
 
1341
  if (this->len_ % this->reloc_size_ != 0)
1342
    {
1343
      object->error(_("reloc section size %zu is not a multiple of "
1344
                      "reloc size %d\n"),
1345
                    static_cast<size_t>(this->len_),
1346
                    this->reloc_size_);
1347
      return false;
1348
    }
1349
 
1350
  return true;
1351
}
1352
 
1353
// Return the offset of the next reloc, or -1 if there isn't one.
1354
 
1355
template<int size, bool big_endian>
1356
off_t
1357
Track_relocs<size, big_endian>::next_offset() const
1358
{
1359
  if (this->pos_ >= this->len_)
1360
    return -1;
1361
 
1362
  // Rel and Rela start out the same, so we can always use Rel to find
1363
  // the r_offset value.
1364
  elfcpp::Rel<size, big_endian> rel(this->prelocs_ + this->pos_);
1365
  return rel.get_r_offset();
1366
}
1367
 
1368
// Return the index of the symbol referenced by the next reloc, or -1U
1369
// if there aren't any more relocs.
1370
 
1371
template<int size, bool big_endian>
1372
unsigned int
1373
Track_relocs<size, big_endian>::next_symndx() const
1374
{
1375
  if (this->pos_ >= this->len_)
1376
    return -1U;
1377
 
1378
  // Rel and Rela start out the same, so we can use Rel to find the
1379
  // symbol index.
1380
  elfcpp::Rel<size, big_endian> rel(this->prelocs_ + this->pos_);
1381
  return elfcpp::elf_r_sym<size>(rel.get_r_info());
1382
}
1383
 
1384
// Advance to the next reloc whose r_offset is greater than or equal
1385
// to OFFSET.  Return the number of relocs we skip.
1386
 
1387
template<int size, bool big_endian>
1388
int
1389
Track_relocs<size, big_endian>::advance(off_t offset)
1390
{
1391
  int ret = 0;
1392
  while (this->pos_ < this->len_)
1393
    {
1394
      // Rel and Rela start out the same, so we can always use Rel to
1395
      // find the r_offset value.
1396
      elfcpp::Rel<size, big_endian> rel(this->prelocs_ + this->pos_);
1397
      if (static_cast<off_t>(rel.get_r_offset()) >= offset)
1398
        break;
1399
      ++ret;
1400
      this->pos_ += this->reloc_size_;
1401
    }
1402
  return ret;
1403
}
1404
 
1405
// Instantiate the templates we need.
1406
 
1407
#ifdef HAVE_TARGET_32_LITTLE
1408
template
1409
void
1410
Sized_relobj<32, false>::do_read_relocs(Read_relocs_data* rd);
1411
#endif
1412
 
1413
#ifdef HAVE_TARGET_32_BIG
1414
template
1415
void
1416
Sized_relobj<32, true>::do_read_relocs(Read_relocs_data* rd);
1417
#endif
1418
 
1419
#ifdef HAVE_TARGET_64_LITTLE
1420
template
1421
void
1422
Sized_relobj<64, false>::do_read_relocs(Read_relocs_data* rd);
1423
#endif
1424
 
1425
#ifdef HAVE_TARGET_64_BIG
1426
template
1427
void
1428
Sized_relobj<64, true>::do_read_relocs(Read_relocs_data* rd);
1429
#endif
1430
 
1431
#ifdef HAVE_TARGET_32_LITTLE
1432
template
1433
void
1434
Sized_relobj<32, false>::do_gc_process_relocs(const General_options& options,
1435
                                        Symbol_table* symtab,
1436
                                        Layout* layout,
1437
                                        Read_relocs_data* rd);
1438
#endif
1439
 
1440
#ifdef HAVE_TARGET_32_BIG
1441
template
1442
void
1443
Sized_relobj<32, true>::do_gc_process_relocs(const General_options& options,
1444
                                       Symbol_table* symtab,
1445
                                       Layout* layout,
1446
                                       Read_relocs_data* rd);
1447
#endif
1448
 
1449
#ifdef HAVE_TARGET_64_LITTLE
1450
template
1451
void
1452
Sized_relobj<64, false>::do_gc_process_relocs(const General_options& options,
1453
                                        Symbol_table* symtab,
1454
                                        Layout* layout,
1455
                                        Read_relocs_data* rd);
1456
#endif
1457
 
1458
#ifdef HAVE_TARGET_64_BIG
1459
template
1460
void
1461
Sized_relobj<64, true>::do_gc_process_relocs(const General_options& options,
1462
                                       Symbol_table* symtab,
1463
                                       Layout* layout,
1464
                                       Read_relocs_data* rd);
1465
#endif
1466
 
1467
#ifdef HAVE_TARGET_32_LITTLE
1468
template
1469
void
1470
Sized_relobj<32, false>::do_scan_relocs(const General_options& options,
1471
                                        Symbol_table* symtab,
1472
                                        Layout* layout,
1473
                                        Read_relocs_data* rd);
1474
#endif
1475
 
1476
#ifdef HAVE_TARGET_32_BIG
1477
template
1478
void
1479
Sized_relobj<32, true>::do_scan_relocs(const General_options& options,
1480
                                       Symbol_table* symtab,
1481
                                       Layout* layout,
1482
                                       Read_relocs_data* rd);
1483
#endif
1484
 
1485
#ifdef HAVE_TARGET_64_LITTLE
1486
template
1487
void
1488
Sized_relobj<64, false>::do_scan_relocs(const General_options& options,
1489
                                        Symbol_table* symtab,
1490
                                        Layout* layout,
1491
                                        Read_relocs_data* rd);
1492
#endif
1493
 
1494
#ifdef HAVE_TARGET_64_BIG
1495
template
1496
void
1497
Sized_relobj<64, true>::do_scan_relocs(const General_options& options,
1498
                                       Symbol_table* symtab,
1499
                                       Layout* layout,
1500
                                       Read_relocs_data* rd);
1501
#endif
1502
 
1503
#ifdef HAVE_TARGET_32_LITTLE
1504
template
1505
void
1506
Sized_relobj<32, false>::do_relocate(const General_options& options,
1507
                                     const Symbol_table* symtab,
1508
                                     const Layout* layout,
1509
                                     Output_file* of);
1510
#endif
1511
 
1512
#ifdef HAVE_TARGET_32_BIG
1513
template
1514
void
1515
Sized_relobj<32, true>::do_relocate(const General_options& options,
1516
                                    const Symbol_table* symtab,
1517
                                    const Layout* layout,
1518
                                    Output_file* of);
1519
#endif
1520
 
1521
#ifdef HAVE_TARGET_64_LITTLE
1522
template
1523
void
1524
Sized_relobj<64, false>::do_relocate(const General_options& options,
1525
                                     const Symbol_table* symtab,
1526
                                     const Layout* layout,
1527
                                     Output_file* of);
1528
#endif
1529
 
1530
#ifdef HAVE_TARGET_64_BIG
1531
template
1532
void
1533
Sized_relobj<64, true>::do_relocate(const General_options& options,
1534
                                    const Symbol_table* symtab,
1535
                                    const Layout* layout,
1536
                                    Output_file* of);
1537
#endif
1538
 
1539
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
1540
template
1541
class Merged_symbol_value<32>;
1542
#endif
1543
 
1544
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
1545
template
1546
class Merged_symbol_value<64>;
1547
#endif
1548
 
1549
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
1550
template
1551
class Symbol_value<32>;
1552
#endif
1553
 
1554
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
1555
template
1556
class Symbol_value<64>;
1557
#endif
1558
 
1559
#ifdef HAVE_TARGET_32_LITTLE
1560
template
1561
class Track_relocs<32, false>;
1562
#endif
1563
 
1564
#ifdef HAVE_TARGET_32_BIG
1565
template
1566
class Track_relocs<32, true>;
1567
#endif
1568
 
1569
#ifdef HAVE_TARGET_64_LITTLE
1570
template
1571
class Track_relocs<64, false>;
1572
#endif
1573
 
1574
#ifdef HAVE_TARGET_64_BIG
1575
template
1576
class Track_relocs<64, true>;
1577
#endif
1578
 
1579
} // End namespace gold.

powered by: WebSVN 2.1.0

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