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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [incremental.cc] - Blame information for rev 143

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

Line No. Rev Author Line
1 27 khays
// inremental.cc -- incremental linking support for gold
2
 
3
// Copyright 2009, 2010 Free Software Foundation, Inc.
4
// Written by Mikolaj Zalewski <mikolajz@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 <cstdarg>
26
#include "libiberty.h"
27
 
28
#include "elfcpp.h"
29
#include "options.h"
30
#include "output.h"
31
#include "symtab.h"
32
#include "incremental.h"
33
#include "archive.h"
34
#include "object.h"
35
#include "output.h"
36
#include "target-select.h"
37
#include "target.h"
38
#include "fileread.h"
39
#include "script.h"
40
 
41
namespace gold {
42
 
43
// Version information. Will change frequently during the development, later
44
// we could think about backward (and forward?) compatibility.
45
const unsigned int INCREMENTAL_LINK_VERSION = 1;
46
 
47
// This class manages the .gnu_incremental_inputs section, which holds
48
// the header information, a directory of input files, and separate
49
// entries for each input file.
50
 
51
template<int size, bool big_endian>
52
class Output_section_incremental_inputs : public Output_section_data
53
{
54
 public:
55
  Output_section_incremental_inputs(const Incremental_inputs* inputs,
56
                                    const Symbol_table* symtab)
57
    : Output_section_data(size / 8), inputs_(inputs), symtab_(symtab)
58
  { }
59
 
60
 protected:
61
  // This is called to update the section size prior to assigning
62
  // the address and file offset.
63
  void
64
  update_data_size()
65
  { this->set_final_data_size(); }
66
 
67
  // Set the final data size.
68
  void
69
  set_final_data_size();
70
 
71
  // Write the data to the file.
72
  void
73
  do_write(Output_file*);
74
 
75
  // Write to a map file.
76
  void
77
  do_print_to_mapfile(Mapfile* mapfile) const
78
  { mapfile->print_output_data(this, _("** incremental_inputs")); }
79
 
80
 private:
81
  // Write the section header.
82
  unsigned char*
83
  write_header(unsigned char* pov, unsigned int input_file_count,
84
               section_offset_type command_line_offset);
85
 
86
  // Write the input file entries.
87
  unsigned char*
88
  write_input_files(unsigned char* oview, unsigned char* pov,
89
                    Stringpool* strtab);
90
 
91
  // Write the supplemental information blocks.
92
  unsigned char*
93
  write_info_blocks(unsigned char* oview, unsigned char* pov,
94
                    Stringpool* strtab, unsigned int* global_syms,
95
                    unsigned int global_sym_count);
96
 
97
  // Write the contents of the .gnu_incremental_symtab section.
98
  void
99
  write_symtab(unsigned char* pov, unsigned int* global_syms,
100
               unsigned int global_sym_count);
101
 
102
  // Write the contents of the .gnu_incremental_got_plt section.
103
  void
104
  write_got_plt(unsigned char* pov, off_t view_size);
105
 
106
  // Typedefs for writing the data to the output sections.
107
  typedef elfcpp::Swap<size, big_endian> Swap;
108
  typedef elfcpp::Swap<16, big_endian> Swap16;
109
  typedef elfcpp::Swap<32, big_endian> Swap32;
110
  typedef elfcpp::Swap<64, big_endian> Swap64;
111
 
112
  // Sizes of various structures.
113
  static const int sizeof_addr = size / 8;
114
  static const int header_size = 16;
115
  static const int input_entry_size = 24;
116
 
117
  // The Incremental_inputs object.
118
  const Incremental_inputs* inputs_;
119
 
120
  // The symbol table.
121
  const Symbol_table* symtab_;
122
};
123
 
124
// Inform the user why we don't do an incremental link.  Not called in
125
// the obvious case of missing output file.  TODO: Is this helpful?
126
 
127
void
128
vexplain_no_incremental(const char* format, va_list args)
129
{
130
  char* buf = NULL;
131
  if (vasprintf(&buf, format, args) < 0)
132
    gold_nomem();
133
  gold_info(_("the link might take longer: "
134
              "cannot perform incremental link: %s"), buf);
135
  free(buf);
136
}
137
 
138
void
139
explain_no_incremental(const char* format, ...)
140
{
141
  va_list args;
142
  va_start(args, format);
143
  vexplain_no_incremental(format, args);
144
  va_end(args);
145
}
146
 
147
// Report an error.
148
 
149
void
150
Incremental_binary::error(const char* format, ...) const
151
{
152
  va_list args;
153
  va_start(args, format);
154
  // Current code only checks if the file can be used for incremental linking,
155
  // so errors shouldn't fail the build, but only result in a fallback to a
156
  // full build.
157
  // TODO: when we implement incremental editing of the file, we may need a
158
  // flag that will cause errors to be treated seriously.
159
  vexplain_no_incremental(format, args);
160
  va_end(args);
161
}
162
 
163
// Find the .gnu_incremental_inputs section and related sections.
164
 
165
template<int size, bool big_endian>
166
bool
167
Sized_incremental_binary<size, big_endian>::find_incremental_inputs_sections(
168
    unsigned int* p_inputs_shndx,
169
    unsigned int* p_symtab_shndx,
170
    unsigned int* p_relocs_shndx,
171
    unsigned int* p_got_plt_shndx,
172
    unsigned int* p_strtab_shndx)
173
{
174
  unsigned int inputs_shndx =
175
      this->elf_file_.find_section_by_type(elfcpp::SHT_GNU_INCREMENTAL_INPUTS);
176
  if (inputs_shndx == elfcpp::SHN_UNDEF)  // Not found.
177
    return false;
178
 
179
  unsigned int symtab_shndx =
180
      this->elf_file_.find_section_by_type(elfcpp::SHT_GNU_INCREMENTAL_SYMTAB);
181
  if (symtab_shndx == elfcpp::SHN_UNDEF)  // Not found.
182
    return false;
183
  if (this->elf_file_.section_link(symtab_shndx) != inputs_shndx)
184
    return false;
185
 
186
  unsigned int relocs_shndx =
187
      this->elf_file_.find_section_by_type(elfcpp::SHT_GNU_INCREMENTAL_RELOCS);
188
  if (relocs_shndx == elfcpp::SHN_UNDEF)  // Not found.
189
    return false;
190
  if (this->elf_file_.section_link(relocs_shndx) != inputs_shndx)
191
    return false;
192
 
193
  unsigned int got_plt_shndx =
194
      this->elf_file_.find_section_by_type(elfcpp::SHT_GNU_INCREMENTAL_GOT_PLT);
195
  if (got_plt_shndx == elfcpp::SHN_UNDEF)  // Not found.
196
    return false;
197
  if (this->elf_file_.section_link(got_plt_shndx) != inputs_shndx)
198
    return false;
199
 
200
  unsigned int strtab_shndx = this->elf_file_.section_link(inputs_shndx);
201
  if (strtab_shndx == elfcpp::SHN_UNDEF
202
      || strtab_shndx > this->elf_file_.shnum()
203
      || this->elf_file_.section_type(strtab_shndx) != elfcpp::SHT_STRTAB)
204
    return false;
205
 
206
  if (p_inputs_shndx != NULL)
207
    *p_inputs_shndx = inputs_shndx;
208
  if (p_symtab_shndx != NULL)
209
    *p_symtab_shndx = symtab_shndx;
210
  if (p_relocs_shndx != NULL)
211
    *p_relocs_shndx = relocs_shndx;
212
  if (p_got_plt_shndx != NULL)
213
    *p_got_plt_shndx = got_plt_shndx;
214
  if (p_strtab_shndx != NULL)
215
    *p_strtab_shndx = strtab_shndx;
216
  return true;
217
}
218
 
219
// Set up the readers into the incremental info sections.
220
 
221
template<int size, bool big_endian>
222
void
223
Sized_incremental_binary<size, big_endian>::setup_readers()
224
{
225
  unsigned int inputs_shndx;
226
  unsigned int symtab_shndx;
227
  unsigned int relocs_shndx;
228
  unsigned int got_plt_shndx;
229
  unsigned int strtab_shndx;
230
 
231
  if (!this->find_incremental_inputs_sections(&inputs_shndx, &symtab_shndx,
232
                                              &relocs_shndx, &got_plt_shndx,
233
                                              &strtab_shndx))
234
    return;
235
 
236
  Location inputs_location(this->elf_file_.section_contents(inputs_shndx));
237
  Location symtab_location(this->elf_file_.section_contents(symtab_shndx));
238
  Location relocs_location(this->elf_file_.section_contents(relocs_shndx));
239
  Location got_plt_location(this->elf_file_.section_contents(got_plt_shndx));
240
  Location strtab_location(this->elf_file_.section_contents(strtab_shndx));
241
 
242
  View inputs_view = this->view(inputs_location);
243
  View symtab_view = this->view(symtab_location);
244
  View relocs_view = this->view(relocs_location);
245
  View got_plt_view = this->view(got_plt_location);
246
  View strtab_view = this->view(strtab_location);
247
 
248
  elfcpp::Elf_strtab strtab(strtab_view.data(), strtab_location.data_size);
249
 
250
  this->inputs_reader_ =
251
      Incremental_inputs_reader<size, big_endian>(inputs_view.data(), strtab);
252
  this->symtab_reader_ =
253
      Incremental_symtab_reader<big_endian>(symtab_view.data(),
254
                                            symtab_location.data_size);
255
  this->relocs_reader_ =
256
      Incremental_relocs_reader<size, big_endian>(relocs_view.data(),
257
                                                  relocs_location.data_size);
258
  this->got_plt_reader_ =
259
      Incremental_got_plt_reader<big_endian>(got_plt_view.data());
260
 
261
  // Find the main symbol table.
262
  unsigned int main_symtab_shndx =
263
      this->elf_file_.find_section_by_type(elfcpp::SHT_SYMTAB);
264
  gold_assert(main_symtab_shndx != elfcpp::SHN_UNDEF);
265
  this->main_symtab_loc_ = this->elf_file_.section_contents(main_symtab_shndx);
266
 
267
  // Find the main symbol string table.
268
  unsigned int main_strtab_shndx =
269
      this->elf_file_.section_link(main_symtab_shndx);
270
  gold_assert(main_strtab_shndx != elfcpp::SHN_UNDEF
271
              && main_strtab_shndx < this->elf_file_.shnum());
272
  this->main_strtab_loc_ = this->elf_file_.section_contents(main_strtab_shndx);
273
 
274
  // Walk the list of input files (a) to setup an Input_reader for each
275
  // input file, and (b) to record maps of files added from archive
276
  // libraries and scripts.
277
  Incremental_inputs_reader<size, big_endian>& inputs = this->inputs_reader_;
278
  unsigned int count = inputs.input_file_count();
279
  this->input_objects_.resize(count);
280
  this->input_entry_readers_.reserve(count);
281
  this->library_map_.resize(count);
282
  this->script_map_.resize(count);
283
  for (unsigned int i = 0; i < count; i++)
284
    {
285
      Input_entry_reader input_file = inputs.input_file(i);
286
      this->input_entry_readers_.push_back(Sized_input_reader(input_file));
287
      switch (input_file.type())
288
        {
289
        case INCREMENTAL_INPUT_OBJECT:
290
        case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
291
        case INCREMENTAL_INPUT_SHARED_LIBRARY:
292
          // No special treatment necessary.
293
          break;
294
        case INCREMENTAL_INPUT_ARCHIVE:
295
          {
296
            Incremental_library* lib =
297
                new Incremental_library(input_file.filename(), i,
298
                                        &this->input_entry_readers_[i]);
299
            this->library_map_[i] = lib;
300
            unsigned int member_count = input_file.get_member_count();
301
            for (unsigned int j = 0; j < member_count; j++)
302
              {
303
                int member_offset = input_file.get_member_offset(j);
304
                int member_index = inputs.input_file_index(member_offset);
305
                this->library_map_[member_index] = lib;
306
              }
307
          }
308
          break;
309
        case INCREMENTAL_INPUT_SCRIPT:
310
          {
311
            Script_info* script = new Script_info(input_file.filename());
312
            this->script_map_[i] = script;
313
            unsigned int object_count = input_file.get_object_count();
314
            for (unsigned int j = 0; j < object_count; j++)
315
              {
316
                int object_offset = input_file.get_object_offset(j);
317
                int object_index = inputs.input_file_index(object_offset);
318
                this->script_map_[object_index] = script;
319
              }
320
          }
321
          break;
322
        default:
323
          gold_unreachable();
324
        }
325
    }
326
 
327
  // Initialize the map of global symbols.
328
  unsigned int nglobals = this->symtab_reader_.symbol_count();
329
  this->symbol_map_.resize(nglobals);
330
 
331
  this->has_incremental_info_ = true;
332
}
333
 
334
// Walk the list of input files given on the command line, and build
335
// a direct map of file index to the corresponding input argument.
336
 
337
void
338
check_input_args(std::vector<const Input_argument*>& input_args_map,
339
                 Input_arguments::const_iterator begin,
340
                 Input_arguments::const_iterator end)
341
{
342
  for (Input_arguments::const_iterator p = begin;
343
       p != end;
344
       ++p)
345
    {
346
      if (p->is_group())
347
        {
348
          const Input_file_group* group = p->group();
349
          check_input_args(input_args_map, group->begin(), group->end());
350
        }
351
      else if (p->is_lib())
352
        {
353
          const Input_file_lib* lib = p->lib();
354
          check_input_args(input_args_map, lib->begin(), lib->end());
355
        }
356
      else
357
        {
358
          gold_assert(p->is_file());
359
          unsigned int arg_serial = p->file().arg_serial();
360
          if (arg_serial > 0)
361
            {
362
              gold_assert(arg_serial <= input_args_map.size());
363
              gold_assert(input_args_map[arg_serial - 1] == 0);
364
              input_args_map[arg_serial - 1] = &*p;
365
            }
366
        }
367
    }
368
}
369
 
370
// Determine whether an incremental link based on the existing output file
371
// can be done.
372
 
373
template<int size, bool big_endian>
374
bool
375
Sized_incremental_binary<size, big_endian>::do_check_inputs(
376
    const Command_line& cmdline,
377
    Incremental_inputs* incremental_inputs)
378
{
379
  Incremental_inputs_reader<size, big_endian>& inputs = this->inputs_reader_;
380
 
381
  if (!this->has_incremental_info_)
382
    {
383
      explain_no_incremental(_("no incremental data from previous build"));
384
      return false;
385
    }
386
 
387
  if (inputs.version() != INCREMENTAL_LINK_VERSION)
388
    {
389
      explain_no_incremental(_("different version of incremental build data"));
390
      return false;
391
    }
392
 
393
  if (incremental_inputs->command_line() != inputs.command_line())
394
    {
395
      explain_no_incremental(_("command line changed"));
396
      return false;
397
    }
398
 
399
  // Walk the list of input files given on the command line, and build
400
  // a direct map of argument serial numbers to the corresponding input
401
  // arguments.
402
  this->input_args_map_.resize(cmdline.number_of_input_files());
403
  check_input_args(this->input_args_map_, cmdline.begin(), cmdline.end());
404
 
405
  // Walk the list of input files to check for conditions that prevent
406
  // an incremental update link.
407
  unsigned int count = inputs.input_file_count();
408
  for (unsigned int i = 0; i < count; i++)
409
    {
410
      Input_entry_reader input_file = inputs.input_file(i);
411
      switch (input_file.type())
412
        {
413
        case INCREMENTAL_INPUT_OBJECT:
414
        case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
415
        case INCREMENTAL_INPUT_SHARED_LIBRARY:
416
        case INCREMENTAL_INPUT_ARCHIVE:
417
          // No special treatment necessary.
418
          break;
419
        case INCREMENTAL_INPUT_SCRIPT:
420
          if (this->do_file_has_changed(i))
421
            {
422
              explain_no_incremental(_("%s: script file changed"),
423
                                     input_file.filename());
424
              return false;
425
            }
426
          break;
427
        default:
428
          gold_unreachable();
429
        }
430
    }
431
 
432
  return true;
433
}
434
 
435
// Return TRUE if input file N has changed since the last incremental link.
436
 
437
template<int size, bool big_endian>
438
bool
439
Sized_incremental_binary<size, big_endian>::do_file_has_changed(
440
    unsigned int n) const
441
{
442
  Input_entry_reader input_file = this->inputs_reader_.input_file(n);
443
  Incremental_disposition disp = INCREMENTAL_CHECK;
444
  const Input_argument* input_argument = this->get_input_argument(n);
445
  if (input_argument != NULL)
446
    disp = input_argument->file().options().incremental_disposition();
447
 
448
  if (disp != INCREMENTAL_CHECK)
449
    return disp == INCREMENTAL_CHANGED;
450
 
451
  const char* filename = input_file.filename();
452
  Timespec old_mtime = input_file.get_mtime();
453
  Timespec new_mtime;
454
  if (!get_mtime(filename, &new_mtime))
455
    {
456
      // If we can't open get the current modification time, assume it has
457
      // changed.  If the file doesn't exist, we'll issue an error when we
458
      // try to open it later.
459
      return true;
460
    }
461
 
462
  if (new_mtime.seconds > old_mtime.seconds)
463
    return true;
464
  if (new_mtime.seconds == old_mtime.seconds
465
      && new_mtime.nanoseconds > old_mtime.nanoseconds)
466
    return true;
467
  return false;
468
}
469
 
470
// Initialize the layout of the output file based on the existing
471
// output file.
472
 
473
template<int size, bool big_endian>
474
void
475
Sized_incremental_binary<size, big_endian>::do_init_layout(Layout* layout)
476
{
477
  typedef elfcpp::Shdr<size, big_endian> Shdr;
478
  const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
479
 
480
  // Get views of the section headers and the section string table.
481
  const off_t shoff = this->elf_file_.shoff();
482
  const unsigned int shnum = this->elf_file_.shnum();
483
  const unsigned int shstrndx = this->elf_file_.shstrndx();
484
  Location shdrs_location(shoff, shnum * shdr_size);
485
  Location shstrndx_location(this->elf_file_.section_contents(shstrndx));
486
  View shdrs_view = this->view(shdrs_location);
487
  View shstrndx_view = this->view(shstrndx_location);
488
  elfcpp::Elf_strtab shstrtab(shstrndx_view.data(),
489
                              shstrndx_location.data_size);
490
 
491
  layout->set_incremental_base(this);
492
 
493
  // Initialize the layout.
494
  this->section_map_.resize(shnum);
495
  const unsigned char* pshdr = shdrs_view.data() + shdr_size;
496
  for (unsigned int i = 1; i < shnum; i++)
497
    {
498
      Shdr shdr(pshdr);
499
      const char* name;
500
      if (!shstrtab.get_c_string(shdr.get_sh_name(), &name))
501
        name = NULL;
502
      gold_debug(DEBUG_INCREMENTAL,
503
                 "Output section: %2d %08lx %08lx %08lx %3d %s",
504
                 i,
505
                 static_cast<long>(shdr.get_sh_addr()),
506
                 static_cast<long>(shdr.get_sh_offset()),
507
                 static_cast<long>(shdr.get_sh_size()),
508
                 shdr.get_sh_type(), name ? name : "<null>");
509
      this->section_map_[i] = layout->init_fixed_output_section(name, shdr);
510
      pshdr += shdr_size;
511
    }
512
}
513
 
514
// Mark regions of the input file that must be kept unchanged.
515
 
516
template<int size, bool big_endian>
517
void
518
Sized_incremental_binary<size, big_endian>::do_reserve_layout(
519
    unsigned int input_file_index)
520
{
521
  Input_entry_reader input_file =
522
      this->inputs_reader_.input_file(input_file_index);
523
 
524
  if (input_file.type() == INCREMENTAL_INPUT_SHARED_LIBRARY)
525
    return;
526
 
527
  unsigned int shnum = input_file.get_input_section_count();
528
  for (unsigned int i = 0; i < shnum; i++)
529
    {
530
      typename Input_entry_reader::Input_section_info sect =
531
          input_file.get_input_section(i);
532
      if (sect.output_shndx == 0 || sect.sh_offset == -1)
533
        continue;
534
      Output_section* os = this->section_map_[sect.output_shndx];
535
      gold_assert(os != NULL);
536
      os->reserve(sect.sh_offset, sect.sh_size);
537
    }
538
}
539
 
540
// Process the GOT and PLT entries from the existing output file.
541
 
542
template<int size, bool big_endian>
543
void
544
Sized_incremental_binary<size, big_endian>::do_process_got_plt(
545
    Symbol_table* symtab,
546
    Layout* layout)
547
{
548
  Incremental_got_plt_reader<big_endian> got_plt_reader(this->got_plt_reader());
549
  Sized_target<size, big_endian>* target =
550
      parameters->sized_target<size, big_endian>();
551
 
552
  // Get the number of symbols in the main symbol table and in the
553
  // incremental symbol table.  The difference between the two counts
554
  // is the index of the first forced-local or global symbol in the
555
  // main symbol table.
556
  unsigned int symtab_count =
557
      this->main_symtab_loc_.data_size / elfcpp::Elf_sizes<size>::sym_size;
558
  unsigned int isym_count = this->symtab_reader_.symbol_count();
559
  unsigned int first_global = symtab_count - isym_count;
560
 
561
  // Tell the target how big the GOT and PLT sections are.
562
  unsigned int got_count = got_plt_reader.get_got_entry_count();
563
  unsigned int plt_count = got_plt_reader.get_plt_entry_count();
564
  Output_data_got<size, big_endian>* got =
565
      target->init_got_plt_for_update(symtab, layout, got_count, plt_count);
566
 
567
  // Read the GOT entries from the base file and build the outgoing GOT.
568
  for (unsigned int i = 0; i < got_count; ++i)
569
    {
570
      unsigned int got_type = got_plt_reader.get_got_type(i);
571
      if ((got_type & 0x7f) == 0x7f)
572
        {
573
          // This is the second entry of a pair.
574
          got->reserve_slot(i);
575
          continue;
576
        }
577
      unsigned int symndx = got_plt_reader.get_got_symndx(i);
578
      if (got_type & 0x80)
579
        {
580
          // This is an entry for a local symbol.  Ignore this entry if
581
          // the object file was replaced.
582
          unsigned int input_index = got_plt_reader.get_got_input_index(i);
583
          gold_debug(DEBUG_INCREMENTAL,
584
                     "GOT entry %d, type %02x: (local symbol)",
585
                     i, got_type & 0x7f);
586
          Sized_relobj_incr<size, big_endian>* obj =
587
              this->input_object(input_index);
588
          if (obj != NULL)
589
            target->reserve_local_got_entry(i, obj, symndx, got_type & 0x7f);
590
        }
591
      else
592
        {
593
          // This is an entry for a global symbol.  GOT_DESC is the symbol
594
          // table index.
595
          // FIXME: This should really be a fatal error (corrupt input).
596
          gold_assert(symndx >= first_global && symndx < symtab_count);
597
          Symbol* sym = this->global_symbol(symndx - first_global);
598
          gold_debug(DEBUG_INCREMENTAL,
599
                     "GOT entry %d, type %02x: %s",
600
                     i, got_type, sym->name());
601
          target->reserve_global_got_entry(i, sym, got_type);
602
        }
603
    }
604
 
605
  // Read the PLT entries from the base file and pass each to the target.
606
  for (unsigned int i = 0; i < plt_count; ++i)
607
    {
608
      unsigned int plt_desc = got_plt_reader.get_plt_desc(i);
609
      // FIXME: This should really be a fatal error (corrupt input).
610
      gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
611
      Symbol* sym = this->global_symbol(plt_desc - first_global);
612
      gold_debug(DEBUG_INCREMENTAL,
613
                 "PLT entry %d: %s",
614
                 i, sym->name());
615
      target->register_global_plt_entry(i, sym);
616
    }
617
}
618
 
619
// Apply incremental relocations for symbols whose values have changed.
620
 
621
template<int size, bool big_endian>
622
void
623
Sized_incremental_binary<size, big_endian>::do_apply_incremental_relocs(
624
    const Symbol_table* symtab,
625
    Layout* layout,
626
    Output_file* of)
627
{
628
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
629
  typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addend;
630
  Incremental_symtab_reader<big_endian> isymtab(this->symtab_reader());
631
  Incremental_relocs_reader<size, big_endian> irelocs(this->relocs_reader());
632
  unsigned int nglobals = isymtab.symbol_count();
633
  const unsigned int incr_reloc_size = irelocs.reloc_size;
634
 
635
  Relocate_info<size, big_endian> relinfo;
636
  relinfo.symtab = symtab;
637
  relinfo.layout = layout;
638
  relinfo.object = NULL;
639
  relinfo.reloc_shndx = 0;
640
  relinfo.reloc_shdr = NULL;
641
  relinfo.data_shndx = 0;
642
  relinfo.data_shdr = NULL;
643
 
644
  Sized_target<size, big_endian>* target =
645
      parameters->sized_target<size, big_endian>();
646
 
647
  for (unsigned int i = 0; i < nglobals; i++)
648
    {
649
      const Symbol* gsym = this->global_symbol(i);
650
 
651
      // If the symbol is not referenced from any unchanged input files,
652
      // we do not need to reapply any of its relocations.
653
      if (gsym == NULL)
654
        continue;
655
 
656
      // If the symbol is defined in an unchanged file, we do not need to
657
      // reapply any of its relocations.
658
      if (gsym->source() == Symbol::FROM_OBJECT
659
          && gsym->object()->is_incremental())
660
        continue;
661
 
662
      gold_debug(DEBUG_INCREMENTAL,
663
                 "Applying incremental relocations for global symbol %s [%d]",
664
                 gsym->name(), i);
665
 
666
      // Follow the linked list of input symbol table entries for this symbol.
667
      // We don't bother to figure out whether the symbol table entry belongs
668
      // to a changed or unchanged file because it's easier just to apply all
669
      // the relocations -- although we might scribble over an area that has
670
      // been reallocated, we do this before copying any new data into the
671
      // output file.
672
      unsigned int offset = isymtab.get_list_head(i);
673
      while (offset > 0)
674
        {
675
          Incremental_global_symbol_reader<big_endian> sym_info =
676
              this->inputs_reader().global_symbol_reader_at_offset(offset);
677
          unsigned int r_base = sym_info.reloc_offset();
678
          unsigned int r_count = sym_info.reloc_count();
679
 
680
          // Apply each relocation for this symbol table entry.
681
          for (unsigned int j = 0; j < r_count;
682
               ++j, r_base += incr_reloc_size)
683
            {
684
              unsigned int r_type = irelocs.get_r_type(r_base);
685
              unsigned int r_shndx = irelocs.get_r_shndx(r_base);
686
              Address r_offset = irelocs.get_r_offset(r_base);
687
              Addend r_addend = irelocs.get_r_addend(r_base);
688
              Output_section* os = this->output_section(r_shndx);
689
              Address address = os->address();
690
              off_t section_offset = os->offset();
691
              size_t view_size = os->data_size();
692
              unsigned char* const view = of->get_output_view(section_offset,
693
                                                              view_size);
694
 
695
              gold_debug(DEBUG_INCREMENTAL,
696
                         "  %08lx: %s + %d: type %d addend %ld",
697
                         (long)(section_offset + r_offset),
698
                         os->name(),
699
                         (int)r_offset,
700
                         r_type,
701
                         (long)r_addend);
702
 
703
              target->apply_relocation(&relinfo, r_offset, r_type, r_addend,
704
                                       gsym, view, address, view_size);
705
 
706
              // FIXME: Do something more efficient if write_output_view
707
              // ever becomes more than a no-op.
708
              of->write_output_view(section_offset, view_size, view);
709
            }
710
          offset = sym_info.next_offset();
711
        }
712
    }
713
}
714
 
715
// Get a view of the main symbol table and the symbol string table.
716
 
717
template<int size, bool big_endian>
718
void
719
Sized_incremental_binary<size, big_endian>::get_symtab_view(
720
    View* symtab_view,
721
    unsigned int* nsyms,
722
    elfcpp::Elf_strtab* strtab)
723
{
724
  *symtab_view = this->view(this->main_symtab_loc_);
725
  *nsyms = this->main_symtab_loc_.data_size / elfcpp::Elf_sizes<size>::sym_size;
726
 
727
  View strtab_view(this->view(this->main_strtab_loc_));
728
  *strtab = elfcpp::Elf_strtab(strtab_view.data(),
729
                               this->main_strtab_loc_.data_size);
730
}
731
 
732
namespace
733
{
734
 
735
// Create a Sized_incremental_binary object of the specified size and
736
// endianness. Fails if the target architecture is not supported.
737
 
738
template<int size, bool big_endian>
739
Incremental_binary*
740
make_sized_incremental_binary(Output_file* file,
741
                              const elfcpp::Ehdr<size, big_endian>& ehdr)
742
{
743
  Target* target = select_target(ehdr.get_e_machine(), size, big_endian,
744
                                 ehdr.get_e_ident()[elfcpp::EI_OSABI],
745
                                 ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]);
746
  if (target == NULL)
747
    {
748
      explain_no_incremental(_("unsupported ELF machine number %d"),
749
               ehdr.get_e_machine());
750
      return NULL;
751
    }
752
 
753
  if (!parameters->target_valid())
754
    set_parameters_target(target);
755
  else if (target != &parameters->target())
756
    gold_error(_("%s: incompatible target"), file->filename());
757
 
758
  return new Sized_incremental_binary<size, big_endian>(file, ehdr, target);
759
}
760
 
761
}  // End of anonymous namespace.
762
 
763
// Create an Incremental_binary object for FILE.  Returns NULL is this is not
764
// possible, e.g. FILE is not an ELF file or has an unsupported target.  FILE
765
// should be opened.
766
 
767
Incremental_binary*
768
open_incremental_binary(Output_file* file)
769
{
770
  off_t filesize = file->filesize();
771
  int want = elfcpp::Elf_recognizer::max_header_size;
772
  if (filesize < want)
773
    want = filesize;
774
 
775
  const unsigned char* p = file->get_input_view(0, want);
776
  if (!elfcpp::Elf_recognizer::is_elf_file(p, want))
777
    {
778
      explain_no_incremental(_("output is not an ELF file."));
779
      return NULL;
780
    }
781
 
782
  int size = 0;
783
  bool big_endian = false;
784
  std::string error;
785
  if (!elfcpp::Elf_recognizer::is_valid_header(p, want, &size, &big_endian,
786
                                               &error))
787
    {
788
      explain_no_incremental(error.c_str());
789
      return NULL;
790
    }
791
 
792
  Incremental_binary* result = NULL;
793
  if (size == 32)
794
    {
795
      if (big_endian)
796
        {
797
#ifdef HAVE_TARGET_32_BIG
798
          result = make_sized_incremental_binary<32, true>(
799
              file, elfcpp::Ehdr<32, true>(p));
800
#else
801
          explain_no_incremental(_("unsupported file: 32-bit, big-endian"));
802
#endif
803
        }
804
      else
805
        {
806
#ifdef HAVE_TARGET_32_LITTLE
807
          result = make_sized_incremental_binary<32, false>(
808
              file, elfcpp::Ehdr<32, false>(p));
809
#else
810
          explain_no_incremental(_("unsupported file: 32-bit, little-endian"));
811
#endif
812
        }
813
    }
814
  else if (size == 64)
815
    {
816
      if (big_endian)
817
        {
818
#ifdef HAVE_TARGET_64_BIG
819
          result = make_sized_incremental_binary<64, true>(
820
              file, elfcpp::Ehdr<64, true>(p));
821
#else
822
          explain_no_incremental(_("unsupported file: 64-bit, big-endian"));
823
#endif
824
        }
825
      else
826
        {
827
#ifdef HAVE_TARGET_64_LITTLE
828
          result = make_sized_incremental_binary<64, false>(
829
              file, elfcpp::Ehdr<64, false>(p));
830
#else
831
          explain_no_incremental(_("unsupported file: 64-bit, little-endian"));
832
#endif
833
        }
834
    }
835
  else
836
    gold_unreachable();
837
 
838
  return result;
839
}
840
 
841
// Class Incremental_inputs.
842
 
843
// Add the command line to the string table, setting
844
// command_line_key_.  In incremental builds, the command line is
845
// stored in .gnu_incremental_inputs so that the next linker run can
846
// check if the command line options didn't change.
847
 
848
void
849
Incremental_inputs::report_command_line(int argc, const char* const* argv)
850
{
851
  // Always store 'gold' as argv[0] to avoid a full relink if the user used a
852
  // different path to the linker.
853
  std::string args("gold");
854
  // Copied from collect_argv in main.cc.
855
  for (int i = 1; i < argc; ++i)
856
    {
857
      // Adding/removing these options should not result in a full relink.
858
      if (strcmp(argv[i], "--incremental") == 0
859
          || strcmp(argv[i], "--incremental-full") == 0
860
          || strcmp(argv[i], "--incremental-update") == 0
861
          || strcmp(argv[i], "--incremental-changed") == 0
862
          || strcmp(argv[i], "--incremental-unchanged") == 0
863
          || strcmp(argv[i], "--incremental-unknown") == 0
864
          || is_prefix_of("--incremental-base=", argv[i])
865
          || is_prefix_of("--debug=", argv[i]))
866
        continue;
867
      if (strcmp(argv[i], "--incremental-base") == 0
868
          || strcmp(argv[i], "--debug") == 0)
869
        {
870
          // When these options are used without the '=', skip the
871
          // following parameter as well.
872
          ++i;
873
          continue;
874
        }
875
 
876
      args.append(" '");
877
      // Now append argv[i], but with all single-quotes escaped
878
      const char* argpos = argv[i];
879
      while (1)
880
        {
881
          const int len = strcspn(argpos, "'");
882
          args.append(argpos, len);
883
          if (argpos[len] == '\0')
884
            break;
885
          args.append("'\"'\"'");
886
          argpos += len + 1;
887
        }
888
      args.append("'");
889
    }
890
 
891
  this->command_line_ = args;
892
  this->strtab_->add(this->command_line_.c_str(), false,
893
                     &this->command_line_key_);
894
}
895
 
896
// Record the input archive file ARCHIVE.  This is called by the
897
// Add_archive_symbols task before determining which archive members
898
// to include.  We create the Incremental_archive_entry here and
899
// attach it to the Archive, but we do not add it to the list of
900
// input objects until report_archive_end is called.
901
 
902
void
903
Incremental_inputs::report_archive_begin(Library_base* arch,
904
                                         unsigned int arg_serial,
905
                                         Script_info* script_info)
906
{
907
  Stringpool::Key filename_key;
908
  Timespec mtime = arch->get_mtime();
909
 
910
  // For a file loaded from a script, don't record its argument serial number.
911
  if (script_info != NULL)
912
    arg_serial = 0;
913
 
914
  this->strtab_->add(arch->filename().c_str(), false, &filename_key);
915
  Incremental_archive_entry* entry =
916
      new Incremental_archive_entry(filename_key, arg_serial, mtime);
917
  arch->set_incremental_info(entry);
918
 
919
  if (script_info != NULL)
920
    {
921
      Incremental_script_entry* script_entry = script_info->incremental_info();
922
      gold_assert(script_entry != NULL);
923
      script_entry->add_object(entry);
924
    }
925
}
926
 
927
// Visitor class for processing the unused global symbols in a library.
928
// An instance of this class is passed to the library's
929
// for_all_unused_symbols() iterator, which will call the visit()
930
// function for each global symbol defined in each unused library
931
// member.  We add those symbol names to the incremental info for the
932
// library.
933
 
934
class Unused_symbol_visitor : public Library_base::Symbol_visitor_base
935
{
936
 public:
937
  Unused_symbol_visitor(Incremental_archive_entry* entry, Stringpool* strtab)
938
    : entry_(entry), strtab_(strtab)
939
  { }
940
 
941
  void
942
  visit(const char* sym)
943
  {
944
    Stringpool::Key symbol_key;
945
    this->strtab_->add(sym, true, &symbol_key);
946
    this->entry_->add_unused_global_symbol(symbol_key);
947
  }
948
 
949
 private:
950
  Incremental_archive_entry* entry_;
951
  Stringpool* strtab_;
952
};
953
 
954
// Finish recording the input archive file ARCHIVE.  This is called by the
955
// Add_archive_symbols task after determining which archive members
956
// to include.
957
 
958
void
959
Incremental_inputs::report_archive_end(Library_base* arch)
960
{
961
  Incremental_archive_entry* entry = arch->incremental_info();
962
 
963
  gold_assert(entry != NULL);
964
  this->inputs_.push_back(entry);
965
 
966
  // Collect unused global symbols.
967
  Unused_symbol_visitor v(entry, this->strtab_);
968
  arch->for_all_unused_symbols(&v);
969
}
970
 
971
// Record the input object file OBJ.  If ARCH is not NULL, attach
972
// the object file to the archive.  This is called by the
973
// Add_symbols task after finding out the type of the file.
974
 
975
void
976
Incremental_inputs::report_object(Object* obj, unsigned int arg_serial,
977
                                  Library_base* arch, Script_info* script_info)
978
{
979
  Stringpool::Key filename_key;
980
  Timespec mtime = obj->get_mtime();
981
 
982
  // For a file loaded from a script, don't record its argument serial number.
983
  if (script_info != NULL)
984
    arg_serial = 0;
985
 
986
  this->strtab_->add(obj->name().c_str(), false, &filename_key);
987
 
988
  Incremental_input_entry* input_entry;
989
 
990
  this->current_object_ = obj;
991
 
992
  if (!obj->is_dynamic())
993
    {
994
      this->current_object_entry_ =
995
          new Incremental_object_entry(filename_key, obj, arg_serial, mtime);
996
      input_entry = this->current_object_entry_;
997
      if (arch != NULL)
998
        {
999
          Incremental_archive_entry* arch_entry = arch->incremental_info();
1000
          gold_assert(arch_entry != NULL);
1001
          arch_entry->add_object(this->current_object_entry_);
1002
        }
1003
    }
1004
  else
1005
    {
1006
      this->current_object_entry_ = NULL;
1007
      Stringpool::Key soname_key;
1008
      Dynobj* dynobj = obj->dynobj();
1009
      gold_assert(dynobj != NULL);
1010
      this->strtab_->add(dynobj->soname(), false, &soname_key);
1011
      input_entry = new Incremental_dynobj_entry(filename_key, soname_key, obj,
1012
                                                 arg_serial, mtime);
1013
    }
1014
 
1015
  if (obj->is_in_system_directory())
1016
    input_entry->set_is_in_system_directory();
1017
 
1018
  if (obj->as_needed())
1019
    input_entry->set_as_needed();
1020
 
1021
  this->inputs_.push_back(input_entry);
1022
 
1023
  if (script_info != NULL)
1024
    {
1025
      Incremental_script_entry* script_entry = script_info->incremental_info();
1026
      gold_assert(script_entry != NULL);
1027
      script_entry->add_object(input_entry);
1028
    }
1029
}
1030
 
1031
// Record an input section SHNDX from object file OBJ.
1032
 
1033
void
1034
Incremental_inputs::report_input_section(Object* obj, unsigned int shndx,
1035
                                         const char* name, off_t sh_size)
1036
{
1037
  Stringpool::Key key = 0;
1038
 
1039
  if (name != NULL)
1040
    this->strtab_->add(name, true, &key);
1041
 
1042
  gold_assert(obj == this->current_object_);
1043
  gold_assert(this->current_object_entry_ != NULL);
1044
  this->current_object_entry_->add_input_section(shndx, key, sh_size);
1045
}
1046
 
1047
// Record a kept COMDAT group belonging to object file OBJ.
1048
 
1049
void
1050
Incremental_inputs::report_comdat_group(Object* obj, const char* name)
1051
{
1052
  Stringpool::Key key = 0;
1053
 
1054
  if (name != NULL)
1055
    this->strtab_->add(name, true, &key);
1056
  gold_assert(obj == this->current_object_);
1057
  gold_assert(this->current_object_entry_ != NULL);
1058
  this->current_object_entry_->add_comdat_group(key);
1059
}
1060
 
1061
// Record that the input argument INPUT is a script SCRIPT.  This is
1062
// called by read_script after parsing the script and reading the list
1063
// of inputs added by this script.
1064
 
1065
void
1066
Incremental_inputs::report_script(Script_info* script,
1067
                                  unsigned int arg_serial,
1068
                                  Timespec mtime)
1069
{
1070
  Stringpool::Key filename_key;
1071
 
1072
  this->strtab_->add(script->filename().c_str(), false, &filename_key);
1073
  Incremental_script_entry* entry =
1074
      new Incremental_script_entry(filename_key, arg_serial, script, mtime);
1075
  this->inputs_.push_back(entry);
1076
  script->set_incremental_info(entry);
1077
}
1078
 
1079
// Finalize the incremental link information.  Called from
1080
// Layout::finalize.
1081
 
1082
void
1083
Incremental_inputs::finalize()
1084
{
1085
  // Finalize the string table.
1086
  this->strtab_->set_string_offsets();
1087
}
1088
 
1089
// Create the .gnu_incremental_inputs, _symtab, and _relocs input sections.
1090
 
1091
void
1092
Incremental_inputs::create_data_sections(Symbol_table* symtab)
1093
{
1094
  switch (parameters->size_and_endianness())
1095
    {
1096
#ifdef HAVE_TARGET_32_LITTLE
1097
    case Parameters::TARGET_32_LITTLE:
1098
      this->inputs_section_ =
1099
          new Output_section_incremental_inputs<32, false>(this, symtab);
1100
      break;
1101
#endif
1102
#ifdef HAVE_TARGET_32_BIG
1103
    case Parameters::TARGET_32_BIG:
1104
      this->inputs_section_ =
1105
          new Output_section_incremental_inputs<32, true>(this, symtab);
1106
      break;
1107
#endif
1108
#ifdef HAVE_TARGET_64_LITTLE
1109
    case Parameters::TARGET_64_LITTLE:
1110
      this->inputs_section_ =
1111
          new Output_section_incremental_inputs<64, false>(this, symtab);
1112
      break;
1113
#endif
1114
#ifdef HAVE_TARGET_64_BIG
1115
    case Parameters::TARGET_64_BIG:
1116
      this->inputs_section_ =
1117
          new Output_section_incremental_inputs<64, true>(this, symtab);
1118
      break;
1119
#endif
1120
    default:
1121
      gold_unreachable();
1122
    }
1123
  this->symtab_section_ = new Output_data_space(4, "** incremental_symtab");
1124
  this->relocs_section_ = new Output_data_space(4, "** incremental_relocs");
1125
  this->got_plt_section_ = new Output_data_space(4, "** incremental_got_plt");
1126
}
1127
 
1128
// Return the sh_entsize value for the .gnu_incremental_relocs section.
1129
unsigned int
1130
Incremental_inputs::relocs_entsize() const
1131
{
1132
  return 8 + 2 * parameters->target().get_size() / 8;
1133
}
1134
 
1135
// Class Output_section_incremental_inputs.
1136
 
1137
// Finalize the offsets for each input section and supplemental info block,
1138
// and set the final data size of the incremental output sections.
1139
 
1140
template<int size, bool big_endian>
1141
void
1142
Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
1143
{
1144
  const Incremental_inputs* inputs = this->inputs_;
1145
  const unsigned int sizeof_addr = size / 8;
1146
  const unsigned int rel_size = 8 + 2 * sizeof_addr;
1147
 
1148
  // Offset of each input entry.
1149
  unsigned int input_offset = this->header_size;
1150
 
1151
  // Offset of each supplemental info block.
1152
  unsigned int file_index = 0;
1153
  unsigned int info_offset = this->header_size;
1154
  info_offset += this->input_entry_size * inputs->input_file_count();
1155
 
1156
  // Count each input file and its supplemental information block.
1157
  for (Incremental_inputs::Input_list::const_iterator p =
1158
           inputs->input_files().begin();
1159
       p != inputs->input_files().end();
1160
       ++p)
1161
    {
1162
      // Set the index and offset of the input file entry.
1163
      (*p)->set_offset(file_index, input_offset);
1164
      ++file_index;
1165
      input_offset += this->input_entry_size;
1166
 
1167
      // Set the offset of the supplemental info block.
1168
      switch ((*p)->type())
1169
        {
1170
        case INCREMENTAL_INPUT_SCRIPT:
1171
          {
1172
            Incremental_script_entry *entry = (*p)->script_entry();
1173
            gold_assert(entry != NULL);
1174
            (*p)->set_info_offset(info_offset);
1175
            // Object count.
1176
            info_offset += 4;
1177
            // Each member.
1178
            info_offset += (entry->get_object_count() * 4);
1179
          }
1180
          break;
1181
        case INCREMENTAL_INPUT_OBJECT:
1182
        case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
1183
          {
1184
            Incremental_object_entry* entry = (*p)->object_entry();
1185
            gold_assert(entry != NULL);
1186
            (*p)->set_info_offset(info_offset);
1187
            // Input section count, global symbol count, local symbol offset,
1188
            // local symbol count, first dynamic reloc, dynamic reloc count,
1189
            // comdat group count.
1190
            info_offset += 28;
1191
            // Each input section.
1192
            info_offset += (entry->get_input_section_count()
1193
                            * (8 + 2 * sizeof_addr));
1194
            // Each global symbol.
1195
            const Object::Symbols* syms = entry->object()->get_global_symbols();
1196
            info_offset += syms->size() * 20;
1197
            // Each comdat group.
1198
            info_offset += entry->get_comdat_group_count() * 4;
1199
          }
1200
          break;
1201
        case INCREMENTAL_INPUT_SHARED_LIBRARY:
1202
          {
1203
            Incremental_dynobj_entry* entry = (*p)->dynobj_entry();
1204
            gold_assert(entry != NULL);
1205
            (*p)->set_info_offset(info_offset);
1206
            // Global symbol count, soname index.
1207
            info_offset += 8;
1208
            // Each global symbol.
1209
            const Object::Symbols* syms = entry->object()->get_global_symbols();
1210
            gold_assert(syms != NULL);
1211
            unsigned int nsyms = syms->size();
1212
            unsigned int nsyms_out = 0;
1213
            for (unsigned int i = 0; i < nsyms; ++i)
1214
              {
1215
                const Symbol* sym = (*syms)[i];
1216
                if (sym == NULL)
1217
                  continue;
1218
                if (sym->is_forwarder())
1219
                  sym = this->symtab_->resolve_forwards(sym);
1220
                if (sym->symtab_index() != -1U)
1221
                  ++nsyms_out;
1222
              }
1223
            info_offset += nsyms_out * 4;
1224
          }
1225
          break;
1226
        case INCREMENTAL_INPUT_ARCHIVE:
1227
          {
1228
            Incremental_archive_entry* entry = (*p)->archive_entry();
1229
            gold_assert(entry != NULL);
1230
            (*p)->set_info_offset(info_offset);
1231
            // Member count + unused global symbol count.
1232
            info_offset += 8;
1233
            // Each member.
1234
            info_offset += (entry->get_member_count() * 4);
1235
            // Each global symbol.
1236
            info_offset += (entry->get_unused_global_symbol_count() * 4);
1237
          }
1238
          break;
1239
        default:
1240
          gold_unreachable();
1241
        }
1242
    }
1243
 
1244
  this->set_data_size(info_offset);
1245
 
1246
  // Set the size of the .gnu_incremental_symtab section.
1247
  inputs->symtab_section()->set_current_data_size(this->symtab_->output_count()
1248
                                                  * sizeof(unsigned int));
1249
 
1250
  // Set the size of the .gnu_incremental_relocs section.
1251
  inputs->relocs_section()->set_current_data_size(inputs->get_reloc_count()
1252
                                                  * rel_size);
1253
 
1254
  // Set the size of the .gnu_incremental_got_plt section.
1255
  Sized_target<size, big_endian>* target =
1256
    parameters->sized_target<size, big_endian>();
1257
  unsigned int got_count = target->got_entry_count();
1258
  unsigned int plt_count = target->plt_entry_count();
1259
  unsigned int got_plt_size = 8;  // GOT entry count, PLT entry count.
1260
  got_plt_size = (got_plt_size + got_count + 3) & ~3;  // GOT type array.
1261
  got_plt_size += got_count * 8 + plt_count * 4;  // GOT array, PLT array.
1262
  inputs->got_plt_section()->set_current_data_size(got_plt_size);
1263
}
1264
 
1265
// Write the contents of the .gnu_incremental_inputs and
1266
// .gnu_incremental_symtab sections.
1267
 
1268
template<int size, bool big_endian>
1269
void
1270
Output_section_incremental_inputs<size, big_endian>::do_write(Output_file* of)
1271
{
1272
  const Incremental_inputs* inputs = this->inputs_;
1273
  Stringpool* strtab = inputs->get_stringpool();
1274
 
1275
  // Get a view into the .gnu_incremental_inputs section.
1276
  const off_t off = this->offset();
1277
  const off_t oview_size = this->data_size();
1278
  unsigned char* const oview = of->get_output_view(off, oview_size);
1279
  unsigned char* pov = oview;
1280
 
1281
  // Get a view into the .gnu_incremental_symtab section.
1282
  const off_t symtab_off = inputs->symtab_section()->offset();
1283
  const off_t symtab_size = inputs->symtab_section()->data_size();
1284
  unsigned char* const symtab_view = of->get_output_view(symtab_off,
1285
                                                         symtab_size);
1286
 
1287
  // Allocate an array of linked list heads for the .gnu_incremental_symtab
1288
  // section.  Each element corresponds to a global symbol in the output
1289
  // symbol table, and points to the head of the linked list that threads
1290
  // through the object file input entries.  The value of each element
1291
  // is the section-relative offset to a global symbol entry in a
1292
  // supplemental information block.
1293
  unsigned int global_sym_count = this->symtab_->output_count();
1294
  unsigned int* global_syms = new unsigned int[global_sym_count];
1295
  memset(global_syms, 0, global_sym_count * sizeof(unsigned int));
1296
 
1297
  // Write the section header.
1298
  Stringpool::Key command_line_key = inputs->command_line_key();
1299
  pov = this->write_header(pov, inputs->input_file_count(),
1300
                           strtab->get_offset_from_key(command_line_key));
1301
 
1302
  // Write the list of input files.
1303
  pov = this->write_input_files(oview, pov, strtab);
1304
 
1305
  // Write the supplemental information blocks for each input file.
1306
  pov = this->write_info_blocks(oview, pov, strtab, global_syms,
1307
                                global_sym_count);
1308
 
1309
  gold_assert(pov - oview == oview_size);
1310
 
1311
  // Write the .gnu_incremental_symtab section.
1312
  gold_assert(global_sym_count * 4 == symtab_size);
1313
  this->write_symtab(symtab_view, global_syms, global_sym_count);
1314
 
1315
  delete[] global_syms;
1316
 
1317
  // Write the .gnu_incremental_got_plt section.
1318
  const off_t got_plt_off = inputs->got_plt_section()->offset();
1319
  const off_t got_plt_size = inputs->got_plt_section()->data_size();
1320
  unsigned char* const got_plt_view = of->get_output_view(got_plt_off,
1321
                                                          got_plt_size);
1322
  this->write_got_plt(got_plt_view, got_plt_size);
1323
 
1324
  of->write_output_view(off, oview_size, oview);
1325
  of->write_output_view(symtab_off, symtab_size, symtab_view);
1326
  of->write_output_view(got_plt_off, got_plt_size, got_plt_view);
1327
}
1328
 
1329
// Write the section header: version, input file count, offset of command line
1330
// in the string table, and 4 bytes of padding.
1331
 
1332
template<int size, bool big_endian>
1333
unsigned char*
1334
Output_section_incremental_inputs<size, big_endian>::write_header(
1335
    unsigned char* pov,
1336
    unsigned int input_file_count,
1337
    section_offset_type command_line_offset)
1338
{
1339
  Swap32::writeval(pov, INCREMENTAL_LINK_VERSION);
1340
  Swap32::writeval(pov + 4, input_file_count);
1341
  Swap32::writeval(pov + 8, command_line_offset);
1342
  Swap32::writeval(pov + 12, 0);
1343
  return pov + this->header_size;
1344
}
1345
 
1346
// Write the input file entries.
1347
 
1348
template<int size, bool big_endian>
1349
unsigned char*
1350
Output_section_incremental_inputs<size, big_endian>::write_input_files(
1351
    unsigned char* oview,
1352
    unsigned char* pov,
1353
    Stringpool* strtab)
1354
{
1355
  const Incremental_inputs* inputs = this->inputs_;
1356
 
1357
  for (Incremental_inputs::Input_list::const_iterator p =
1358
           inputs->input_files().begin();
1359
       p != inputs->input_files().end();
1360
       ++p)
1361
    {
1362
      gold_assert(static_cast<unsigned int>(pov - oview) == (*p)->get_offset());
1363
      section_offset_type filename_offset =
1364
          strtab->get_offset_from_key((*p)->get_filename_key());
1365
      const Timespec& mtime = (*p)->get_mtime();
1366
      unsigned int flags = (*p)->type();
1367
      if ((*p)->is_in_system_directory())
1368
        flags |= INCREMENTAL_INPUT_IN_SYSTEM_DIR;
1369
      if ((*p)->as_needed())
1370
        flags |= INCREMENTAL_INPUT_AS_NEEDED;
1371
      Swap32::writeval(pov, filename_offset);
1372
      Swap32::writeval(pov + 4, (*p)->get_info_offset());
1373
      Swap64::writeval(pov + 8, mtime.seconds);
1374
      Swap32::writeval(pov + 16, mtime.nanoseconds);
1375
      Swap16::writeval(pov + 20, flags);
1376
      Swap16::writeval(pov + 22, (*p)->arg_serial());
1377
      pov += this->input_entry_size;
1378
    }
1379
  return pov;
1380
}
1381
 
1382
// Write the supplemental information blocks.
1383
 
1384
template<int size, bool big_endian>
1385
unsigned char*
1386
Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
1387
    unsigned char* oview,
1388
    unsigned char* pov,
1389
    Stringpool* strtab,
1390
    unsigned int* global_syms,
1391
    unsigned int global_sym_count)
1392
{
1393
  const Incremental_inputs* inputs = this->inputs_;
1394
  unsigned int first_global_index = this->symtab_->first_global_index();
1395
 
1396
  for (Incremental_inputs::Input_list::const_iterator p =
1397
           inputs->input_files().begin();
1398
       p != inputs->input_files().end();
1399
       ++p)
1400
    {
1401
      switch ((*p)->type())
1402
        {
1403
        case INCREMENTAL_INPUT_SCRIPT:
1404
          {
1405
            gold_assert(static_cast<unsigned int>(pov - oview)
1406
                        == (*p)->get_info_offset());
1407
            Incremental_script_entry* entry = (*p)->script_entry();
1408
            gold_assert(entry != NULL);
1409
 
1410
            // Write the object count.
1411
            unsigned int nobjects = entry->get_object_count();
1412
            Swap32::writeval(pov, nobjects);
1413
            pov += 4;
1414
 
1415
            // For each object, write the offset to its input file entry.
1416
            for (unsigned int i = 0; i < nobjects; ++i)
1417
              {
1418
                Incremental_input_entry* obj = entry->get_object(i);
1419
                Swap32::writeval(pov, obj->get_offset());
1420
                pov += 4;
1421
              }
1422
          }
1423
          break;
1424
 
1425
        case INCREMENTAL_INPUT_OBJECT:
1426
        case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
1427
          {
1428
            gold_assert(static_cast<unsigned int>(pov - oview)
1429
                        == (*p)->get_info_offset());
1430
            Incremental_object_entry* entry = (*p)->object_entry();
1431
            gold_assert(entry != NULL);
1432
            const Object* obj = entry->object();
1433
            const Relobj* relobj = static_cast<const Relobj*>(obj);
1434
            const Object::Symbols* syms = obj->get_global_symbols();
1435
            // Write the input section count and global symbol count.
1436
            unsigned int nsections = entry->get_input_section_count();
1437
            unsigned int nsyms = syms->size();
1438
            off_t locals_offset = relobj->local_symbol_offset();
1439
            unsigned int nlocals = relobj->output_local_symbol_count();
1440
            unsigned int first_dynrel = relobj->first_dyn_reloc();
1441
            unsigned int ndynrel = relobj->dyn_reloc_count();
1442
            unsigned int ncomdat = entry->get_comdat_group_count();
1443
            Swap32::writeval(pov, nsections);
1444
            Swap32::writeval(pov + 4, nsyms);
1445
            Swap32::writeval(pov + 8, static_cast<unsigned int>(locals_offset));
1446
            Swap32::writeval(pov + 12, nlocals);
1447
            Swap32::writeval(pov + 16, first_dynrel);
1448
            Swap32::writeval(pov + 20, ndynrel);
1449
            Swap32::writeval(pov + 24, ncomdat);
1450
            pov += 28;
1451
 
1452
            // Build a temporary array to map input section indexes
1453
            // from the original object file index to the index in the
1454
            // incremental info table.
1455
            unsigned int* index_map = new unsigned int[obj->shnum()];
1456
            memset(index_map, 0, obj->shnum() * sizeof(unsigned int));
1457
 
1458
            // For each input section, write the name, output section index,
1459
            // offset within output section, and input section size.
1460
            for (unsigned int i = 0; i < nsections; i++)
1461
              {
1462
                unsigned int shndx = entry->get_input_section_index(i);
1463
                index_map[shndx] = i + 1;
1464
                Stringpool::Key key = entry->get_input_section_name_key(i);
1465
                off_t name_offset = 0;
1466
                if (key != 0)
1467
                  name_offset = strtab->get_offset_from_key(key);
1468
                int out_shndx = 0;
1469
                off_t out_offset = 0;
1470
                off_t sh_size = 0;
1471
                Output_section* os = obj->output_section(shndx);
1472
                if (os != NULL)
1473
                  {
1474
                    out_shndx = os->out_shndx();
1475
                    out_offset = obj->output_section_offset(shndx);
1476
                    sh_size = entry->get_input_section_size(i);
1477
                  }
1478
                Swap32::writeval(pov, name_offset);
1479
                Swap32::writeval(pov + 4, out_shndx);
1480
                Swap::writeval(pov + 8, out_offset);
1481
                Swap::writeval(pov + 8 + sizeof_addr, sh_size);
1482
                pov += 8 + 2 * sizeof_addr;
1483
              }
1484
 
1485
            // For each global symbol, write its associated relocations,
1486
            // add it to the linked list of globals, then write the
1487
            // supplemental information:  global symbol table index,
1488
            // input section index, linked list chain pointer, relocation
1489
            // count, and offset to the relocations.
1490
            for (unsigned int i = 0; i < nsyms; i++)
1491
              {
1492
                const Symbol* sym = (*syms)[i];
1493
                if (sym->is_forwarder())
1494
                  sym = this->symtab_->resolve_forwards(sym);
1495
                unsigned int shndx = 0;
1496
                if (sym->source() == Symbol::FROM_OBJECT
1497
                    && sym->object() == obj
1498
                    && sym->is_defined())
1499
                  {
1500
                    bool is_ordinary;
1501
                    unsigned int orig_shndx = sym->shndx(&is_ordinary);
1502
                    if (is_ordinary)
1503
                      shndx = index_map[orig_shndx];
1504
                  }
1505
                unsigned int symtab_index = sym->symtab_index();
1506
                unsigned int chain = 0;
1507
                unsigned int first_reloc = 0;
1508
                unsigned int nrelocs = obj->get_incremental_reloc_count(i);
1509
                if (nrelocs > 0)
1510
                  {
1511
                    gold_assert(symtab_index != -1U
1512
                                && (symtab_index - first_global_index
1513
                                    < global_sym_count));
1514
                    first_reloc = obj->get_incremental_reloc_base(i);
1515
                    chain = global_syms[symtab_index - first_global_index];
1516
                    global_syms[symtab_index - first_global_index] =
1517
                        pov - oview;
1518
                  }
1519
                Swap32::writeval(pov, symtab_index);
1520
                Swap32::writeval(pov + 4, shndx);
1521
                Swap32::writeval(pov + 8, chain);
1522
                Swap32::writeval(pov + 12, nrelocs);
1523
                Swap32::writeval(pov + 16, first_reloc * 3 * sizeof_addr);
1524
                pov += 20;
1525
              }
1526
 
1527
            // For each kept COMDAT group, write the group signature.
1528
            for (unsigned int i = 0; i < ncomdat; i++)
1529
              {
1530
                Stringpool::Key key = entry->get_comdat_signature_key(i);
1531
                off_t name_offset = 0;
1532
                if (key != 0)
1533
                  name_offset = strtab->get_offset_from_key(key);
1534
                Swap32::writeval(pov, name_offset);
1535
                pov += 4;
1536
              }
1537
 
1538
            delete[] index_map;
1539
          }
1540
          break;
1541
 
1542
        case INCREMENTAL_INPUT_SHARED_LIBRARY:
1543
          {
1544
            gold_assert(static_cast<unsigned int>(pov - oview)
1545
                        == (*p)->get_info_offset());
1546
            Incremental_dynobj_entry* entry = (*p)->dynobj_entry();
1547
            gold_assert(entry != NULL);
1548
            const Object* obj = entry->object();
1549
            const Object::Symbols* syms = obj->get_global_symbols();
1550
 
1551
            // Write the soname string table index.
1552
            section_offset_type soname_offset =
1553
                strtab->get_offset_from_key(entry->get_soname_key());
1554
            Swap32::writeval(pov, soname_offset);
1555
            pov += 4;
1556
 
1557
            // Skip the global symbol count for now.
1558
            unsigned char* orig_pov = pov;
1559
            pov += 4;
1560
 
1561
            // For each global symbol, write the global symbol table index.
1562
            unsigned int nsyms = syms->size();
1563
            unsigned int nsyms_out = 0;
1564
            for (unsigned int i = 0; i < nsyms; i++)
1565
              {
1566
                const Symbol* sym = (*syms)[i];
1567
                if (sym == NULL)
1568
                  continue;
1569
                if (sym->is_forwarder())
1570
                  sym = this->symtab_->resolve_forwards(sym);
1571
                if (sym->symtab_index() == -1U)
1572
                  continue;
1573
                unsigned int def_flag = 0;
1574
                if (sym->source() == Symbol::FROM_OBJECT
1575
                    && sym->object() == obj
1576
                    && sym->is_defined())
1577
                  def_flag = 1U << 31;
1578
                Swap32::writeval(pov, sym->symtab_index() | def_flag);
1579
                pov += 4;
1580
                ++nsyms_out;
1581
              }
1582
 
1583
            // Now write the global symbol count.
1584
            Swap32::writeval(orig_pov, nsyms_out);
1585
          }
1586
          break;
1587
 
1588
        case INCREMENTAL_INPUT_ARCHIVE:
1589
          {
1590
            gold_assert(static_cast<unsigned int>(pov - oview)
1591
                        == (*p)->get_info_offset());
1592
            Incremental_archive_entry* entry = (*p)->archive_entry();
1593
            gold_assert(entry != NULL);
1594
 
1595
            // Write the member count and unused global symbol count.
1596
            unsigned int nmembers = entry->get_member_count();
1597
            unsigned int nsyms = entry->get_unused_global_symbol_count();
1598
            Swap32::writeval(pov, nmembers);
1599
            Swap32::writeval(pov + 4, nsyms);
1600
            pov += 8;
1601
 
1602
            // For each member, write the offset to its input file entry.
1603
            for (unsigned int i = 0; i < nmembers; ++i)
1604
              {
1605
                Incremental_object_entry* member = entry->get_member(i);
1606
                Swap32::writeval(pov, member->get_offset());
1607
                pov += 4;
1608
              }
1609
 
1610
            // For each global symbol, write the name offset.
1611
            for (unsigned int i = 0; i < nsyms; ++i)
1612
              {
1613
                Stringpool::Key key = entry->get_unused_global_symbol(i);
1614
                Swap32::writeval(pov, strtab->get_offset_from_key(key));
1615
                pov += 4;
1616
              }
1617
          }
1618
          break;
1619
 
1620
        default:
1621
          gold_unreachable();
1622
        }
1623
    }
1624
  return pov;
1625
}
1626
 
1627
// Write the contents of the .gnu_incremental_symtab section.
1628
 
1629
template<int size, bool big_endian>
1630
void
1631
Output_section_incremental_inputs<size, big_endian>::write_symtab(
1632
    unsigned char* pov,
1633
    unsigned int* global_syms,
1634
    unsigned int global_sym_count)
1635
{
1636
  for (unsigned int i = 0; i < global_sym_count; ++i)
1637
    {
1638
      Swap32::writeval(pov, global_syms[i]);
1639
      pov += 4;
1640
    }
1641
}
1642
 
1643
// This struct holds the view information needed to write the
1644
// .gnu_incremental_got_plt section.
1645
 
1646
struct Got_plt_view_info
1647
{
1648
  // Start of the GOT type array in the output view.
1649
  unsigned char* got_type_p;
1650
  // Start of the GOT descriptor array in the output view.
1651
  unsigned char* got_desc_p;
1652
  // Start of the PLT descriptor array in the output view.
1653
  unsigned char* plt_desc_p;
1654
  // Number of GOT entries.
1655
  unsigned int got_count;
1656
  // Number of PLT entries.
1657
  unsigned int plt_count;
1658
  // Offset of the first non-reserved PLT entry (this is a target-dependent value).
1659
  unsigned int first_plt_entry_offset;
1660
  // Size of a PLT entry (this is a target-dependent value).
1661
  unsigned int plt_entry_size;
1662
  // Symbol index to write in the GOT descriptor array.  For global symbols,
1663
  // this is the global symbol table index; for local symbols, it is the
1664
  // local symbol table index.
1665
  unsigned int sym_index;
1666
  // Input file index to write in the GOT descriptor array.  For global
1667
  // symbols, this is 0; for local symbols, it is the index of the input
1668
  // file entry in the .gnu_incremental_inputs section.
1669
  unsigned int input_index;
1670
};
1671
 
1672
// Functor class for processing a GOT offset list for local symbols.
1673
// Writes the GOT type and symbol index into the GOT type and descriptor
1674
// arrays in the output section.
1675
 
1676
template<int size, bool big_endian>
1677
class Local_got_offset_visitor : public Got_offset_list::Visitor
1678
{
1679
 public:
1680
  Local_got_offset_visitor(struct Got_plt_view_info& info)
1681
    : info_(info)
1682
  { }
1683
 
1684
  void
1685
  visit(unsigned int got_type, unsigned int got_offset)
1686
  {
1687
    unsigned int got_index = got_offset / this->got_entry_size_;
1688
    gold_assert(got_index < this->info_.got_count);
1689
    // We can only handle GOT entry types in the range 0..0x7e
1690
    // because we use a byte array to store them, and we use the
1691
    // high bit to flag a local symbol.
1692
    gold_assert(got_type < 0x7f);
1693
    this->info_.got_type_p[got_index] = got_type | 0x80;
1694
    unsigned char* pov = this->info_.got_desc_p + got_index * 8;
1695
    elfcpp::Swap<32, big_endian>::writeval(pov, this->info_.sym_index);
1696
    elfcpp::Swap<32, big_endian>::writeval(pov + 4, this->info_.input_index);
1697
  }
1698
 
1699
 private:
1700
  static const unsigned int got_entry_size_ = size / 8;
1701
  struct Got_plt_view_info& info_;
1702
};
1703
 
1704
// Functor class for processing a GOT offset list.  Writes the GOT type
1705
// and symbol index into the GOT type and descriptor arrays in the output
1706
// section.
1707
 
1708
template<int size, bool big_endian>
1709
class Global_got_offset_visitor : public Got_offset_list::Visitor
1710
{
1711
 public:
1712
  Global_got_offset_visitor(struct Got_plt_view_info& info)
1713
    : info_(info)
1714
  { }
1715
 
1716
  void
1717
  visit(unsigned int got_type, unsigned int got_offset)
1718
  {
1719
    unsigned int got_index = got_offset / this->got_entry_size_;
1720
    gold_assert(got_index < this->info_.got_count);
1721
    // We can only handle GOT entry types in the range 0..0x7e
1722
    // because we use a byte array to store them, and we use the
1723
    // high bit to flag a local symbol.
1724
    gold_assert(got_type < 0x7f);
1725
    this->info_.got_type_p[got_index] = got_type;
1726
    unsigned char* pov = this->info_.got_desc_p + got_index * 8;
1727
    elfcpp::Swap<32, big_endian>::writeval(pov, this->info_.sym_index);
1728
    elfcpp::Swap<32, big_endian>::writeval(pov + 4, 0);
1729
  }
1730
 
1731
 private:
1732
  static const unsigned int got_entry_size_ = size / 8;
1733
  struct Got_plt_view_info& info_;
1734
};
1735
 
1736
// Functor class for processing the global symbol table.  Processes the
1737
// GOT offset list for the symbol, and writes the symbol table index
1738
// into the PLT descriptor array in the output section.
1739
 
1740
template<int size, bool big_endian>
1741
class Global_symbol_visitor_got_plt
1742
{
1743
 public:
1744
  Global_symbol_visitor_got_plt(struct Got_plt_view_info& info)
1745
    : info_(info)
1746
  { }
1747
 
1748
  void
1749
  operator()(const Sized_symbol<size>* sym)
1750
  {
1751
    typedef Global_got_offset_visitor<size, big_endian> Got_visitor;
1752
    const Got_offset_list* got_offsets = sym->got_offset_list();
1753
    if (got_offsets != NULL)
1754
      {
1755
        this->info_.sym_index = sym->symtab_index();
1756
        this->info_.input_index = 0;
1757
        Got_visitor v(this->info_);
1758
        got_offsets->for_all_got_offsets(&v);
1759
      }
1760
    if (sym->has_plt_offset())
1761
      {
1762
        unsigned int plt_index =
1763
            ((sym->plt_offset() - this->info_.first_plt_entry_offset)
1764
             / this->info_.plt_entry_size);
1765
        gold_assert(plt_index < this->info_.plt_count);
1766
        unsigned char* pov = this->info_.plt_desc_p + plt_index * 4;
1767
        elfcpp::Swap<32, big_endian>::writeval(pov, sym->symtab_index());
1768
      }
1769
  }
1770
 
1771
 private:
1772
  struct Got_plt_view_info& info_;
1773
};
1774
 
1775
// Write the contents of the .gnu_incremental_got_plt section.
1776
 
1777
template<int size, bool big_endian>
1778
void
1779
Output_section_incremental_inputs<size, big_endian>::write_got_plt(
1780
    unsigned char* pov,
1781
    off_t view_size)
1782
{
1783
  Sized_target<size, big_endian>* target =
1784
    parameters->sized_target<size, big_endian>();
1785
 
1786
  // Set up the view information for the functors.
1787
  struct Got_plt_view_info view_info;
1788
  view_info.got_count = target->got_entry_count();
1789
  view_info.plt_count = target->plt_entry_count();
1790
  view_info.first_plt_entry_offset = target->first_plt_entry_offset();
1791
  view_info.plt_entry_size = target->plt_entry_size();
1792
  view_info.got_type_p = pov + 8;
1793
  view_info.got_desc_p = (view_info.got_type_p
1794
                          + ((view_info.got_count + 3) & ~3));
1795
  view_info.plt_desc_p = view_info.got_desc_p + view_info.got_count * 8;
1796
 
1797
  gold_assert(pov + view_size ==
1798
              view_info.plt_desc_p + view_info.plt_count * 4);
1799
 
1800
  // Write the section header.
1801
  Swap32::writeval(pov, view_info.got_count);
1802
  Swap32::writeval(pov + 4, view_info.plt_count);
1803
 
1804
  // Initialize the GOT type array to 0xff (reserved).
1805
  memset(view_info.got_type_p, 0xff, view_info.got_count);
1806
 
1807
  // Write the incremental GOT descriptors for local symbols.
1808
  typedef Local_got_offset_visitor<size, big_endian> Got_visitor;
1809
  for (Incremental_inputs::Input_list::const_iterator p =
1810
           this->inputs_->input_files().begin();
1811
       p != this->inputs_->input_files().end();
1812
       ++p)
1813
    {
1814
      if ((*p)->type() != INCREMENTAL_INPUT_OBJECT
1815
          && (*p)->type() != INCREMENTAL_INPUT_ARCHIVE_MEMBER)
1816
        continue;
1817
      Incremental_object_entry* entry = (*p)->object_entry();
1818
      gold_assert(entry != NULL);
1819
      const Object* obj = entry->object();
1820
      gold_assert(obj != NULL);
1821
      view_info.input_index = (*p)->get_file_index();
1822
      Got_visitor v(view_info);
1823
      obj->for_all_local_got_entries(&v);
1824
    }
1825
 
1826
  // Write the incremental GOT and PLT descriptors for global symbols.
1827
  typedef Global_symbol_visitor_got_plt<size, big_endian> Symbol_visitor;
1828
  symtab_->for_all_symbols<size, Symbol_visitor>(Symbol_visitor(view_info));
1829
}
1830
 
1831
// Class Sized_relobj_incr.  Most of these methods are not used for
1832
// Incremental objects, but are required to be implemented by the
1833
// base class Object.
1834
 
1835
template<int size, bool big_endian>
1836
Sized_relobj_incr<size, big_endian>::Sized_relobj_incr(
1837
    const std::string& name,
1838
    Sized_incremental_binary<size, big_endian>* ibase,
1839
    unsigned int input_file_index)
1840
  : Sized_relobj<size, big_endian>(name, NULL), ibase_(ibase),
1841
    input_file_index_(input_file_index),
1842
    input_reader_(ibase->inputs_reader().input_file(input_file_index)),
1843
    local_symbol_count_(0), output_local_dynsym_count_(0),
1844
    local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0),
1845
    symbols_(), incr_reloc_offset_(-1U), incr_reloc_count_(0),
1846
    incr_reloc_output_index_(0), incr_relocs_(NULL), local_symbols_()
1847
{
1848
  if (this->input_reader_.is_in_system_directory())
1849
    this->set_is_in_system_directory();
1850
  const unsigned int shnum = this->input_reader_.get_input_section_count() + 1;
1851
  this->set_shnum(shnum);
1852
  ibase->set_input_object(input_file_index, this);
1853
}
1854
 
1855
// Read the symbols.
1856
 
1857
template<int size, bool big_endian>
1858
void
1859
Sized_relobj_incr<size, big_endian>::do_read_symbols(Read_symbols_data*)
1860
{
1861
  gold_unreachable();
1862
}
1863
 
1864
// Lay out the input sections.
1865
 
1866
template<int size, bool big_endian>
1867
void
1868
Sized_relobj_incr<size, big_endian>::do_layout(
1869
    Symbol_table*,
1870
    Layout* layout,
1871
    Read_symbols_data*)
1872
{
1873
  const unsigned int shnum = this->shnum();
1874
  Incremental_inputs* incremental_inputs = layout->incremental_inputs();
1875
  gold_assert(incremental_inputs != NULL);
1876
  Output_sections& out_sections(this->output_sections());
1877
  out_sections.resize(shnum);
1878
  this->section_offsets().resize(shnum);
1879
  for (unsigned int i = 1; i < shnum; i++)
1880
    {
1881
      typename Input_entry_reader::Input_section_info sect =
1882
          this->input_reader_.get_input_section(i - 1);
1883
      // Add the section to the incremental inputs layout.
1884
      incremental_inputs->report_input_section(this, i, sect.name,
1885
                                               sect.sh_size);
1886
      if (sect.output_shndx == 0 || sect.sh_offset == -1)
1887
        continue;
1888
      Output_section* os = this->ibase_->output_section(sect.output_shndx);
1889
      gold_assert(os != NULL);
1890
      out_sections[i] = os;
1891
      this->section_offsets()[i] = static_cast<Address>(sect.sh_offset);
1892
    }
1893
 
1894
  // Process the COMDAT groups.
1895
  unsigned int ncomdat = this->input_reader_.get_comdat_group_count();
1896
  for (unsigned int i = 0; i < ncomdat; i++)
1897
    {
1898
      const char* signature = this->input_reader_.get_comdat_group_signature(i);
1899
      if (signature == NULL || signature[0] == '\0')
1900
        this->error(_("COMDAT group has no signature"));
1901
      bool keep = layout->find_or_add_kept_section(signature, this, i, true,
1902
                                                   true, NULL);
1903
      if (!keep)
1904
        this->error(_("COMDAT group %s included twice in incremental link"),
1905
                    signature);
1906
    }
1907
}
1908
 
1909
// Layout sections whose layout was deferred while waiting for
1910
// input files from a plugin.
1911
template<int size, bool big_endian>
1912
void
1913
Sized_relobj_incr<size, big_endian>::do_layout_deferred_sections(Layout*)
1914
{
1915
}
1916
 
1917
// Add the symbols to the symbol table.
1918
 
1919
template<int size, bool big_endian>
1920
void
1921
Sized_relobj_incr<size, big_endian>::do_add_symbols(
1922
    Symbol_table* symtab,
1923
    Read_symbols_data*,
1924
    Layout*)
1925
{
1926
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
1927
  unsigned char symbuf[sym_size];
1928
  elfcpp::Sym<size, big_endian> sym(symbuf);
1929
  elfcpp::Sym_write<size, big_endian> osym(symbuf);
1930
 
1931
  typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
1932
 
1933
  unsigned int nsyms = this->input_reader_.get_global_symbol_count();
1934
  this->symbols_.resize(nsyms);
1935
 
1936
  Incremental_binary::View symtab_view(NULL);
1937
  unsigned int symtab_count;
1938
  elfcpp::Elf_strtab strtab(NULL, 0);
1939
  this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
1940
 
1941
  Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
1942
  unsigned int isym_count = isymtab.symbol_count();
1943
  unsigned int first_global = symtab_count - isym_count;
1944
 
1945
  const unsigned char* sym_p;
1946
  for (unsigned int i = 0; i < nsyms; ++i)
1947
    {
1948
      Incremental_global_symbol_reader<big_endian> info =
1949
          this->input_reader_.get_global_symbol_reader(i);
1950
      unsigned int output_symndx = info.output_symndx();
1951
      sym_p = symtab_view.data() + output_symndx * sym_size;
1952
      elfcpp::Sym<size, big_endian> gsym(sym_p);
1953
      const char* name;
1954
      if (!strtab.get_c_string(gsym.get_st_name(), &name))
1955
        name = "";
1956
 
1957
      typename elfcpp::Elf_types<size>::Elf_Addr v = gsym.get_st_value();
1958
      unsigned int shndx = gsym.get_st_shndx();
1959
      elfcpp::STB st_bind = gsym.get_st_bind();
1960
      elfcpp::STT st_type = gsym.get_st_type();
1961
 
1962
      // Local hidden symbols start out as globals, but get converted to
1963
      // to local during output.
1964
      if (st_bind == elfcpp::STB_LOCAL)
1965
        st_bind = elfcpp::STB_GLOBAL;
1966
 
1967
      unsigned int input_shndx = info.shndx();
1968
      if (input_shndx == 0)
1969
        {
1970
          shndx = elfcpp::SHN_UNDEF;
1971
          v = 0;
1972
        }
1973
      else if (shndx != elfcpp::SHN_ABS)
1974
        {
1975
          // Find the input section and calculate the section-relative value.
1976
          gold_assert(shndx != elfcpp::SHN_UNDEF);
1977
          Output_section* os = this->ibase_->output_section(shndx);
1978
          gold_assert(os != NULL && os->has_fixed_layout());
1979
          typename Input_entry_reader::Input_section_info sect =
1980
              this->input_reader_.get_input_section(input_shndx - 1);
1981
          gold_assert(sect.output_shndx == shndx);
1982
          if (st_type != elfcpp::STT_TLS)
1983
            v -= os->address();
1984
          v -= sect.sh_offset;
1985
          shndx = input_shndx;
1986
        }
1987
 
1988
      osym.put_st_name(0);
1989
      osym.put_st_value(v);
1990
      osym.put_st_size(gsym.get_st_size());
1991
      osym.put_st_info(st_bind, st_type);
1992
      osym.put_st_other(gsym.get_st_other());
1993
      osym.put_st_shndx(shndx);
1994
 
1995
      this->symbols_[i] =
1996
        symtab->add_from_incrobj(this, name, NULL, &sym);
1997
      this->ibase_->add_global_symbol(output_symndx - first_global,
1998
                                      this->symbols_[i]);
1999
    }
2000
}
2001
 
2002
// Return TRUE if we should include this object from an archive library.
2003
 
2004
template<int size, bool big_endian>
2005
Archive::Should_include
2006
Sized_relobj_incr<size, big_endian>::do_should_include_member(
2007
    Symbol_table*,
2008
    Layout*,
2009
    Read_symbols_data*,
2010
    std::string*)
2011
{
2012
  gold_unreachable();
2013
}
2014
 
2015
// Iterate over global symbols, calling a visitor class V for each.
2016
 
2017
template<int size, bool big_endian>
2018
void
2019
Sized_relobj_incr<size, big_endian>::do_for_all_global_symbols(
2020
    Read_symbols_data*,
2021
    Library_base::Symbol_visitor_base*)
2022
{
2023
  // This routine is not used for incremental objects.
2024
}
2025
 
2026
// Get the size of a section.
2027
 
2028
template<int size, bool big_endian>
2029
uint64_t
2030
Sized_relobj_incr<size, big_endian>::do_section_size(unsigned int)
2031
{
2032
  gold_unreachable();
2033
}
2034
 
2035
// Get the name of a section.
2036
 
2037
template<int size, bool big_endian>
2038
std::string
2039
Sized_relobj_incr<size, big_endian>::do_section_name(unsigned int)
2040
{
2041
  gold_unreachable();
2042
}
2043
 
2044
// Return a view of the contents of a section.
2045
 
2046
template<int size, bool big_endian>
2047
Object::Location
2048
Sized_relobj_incr<size, big_endian>::do_section_contents(unsigned int)
2049
{
2050
  gold_unreachable();
2051
}
2052
 
2053
// Return section flags.
2054
 
2055
template<int size, bool big_endian>
2056
uint64_t
2057
Sized_relobj_incr<size, big_endian>::do_section_flags(unsigned int)
2058
{
2059
  gold_unreachable();
2060
}
2061
 
2062
// Return section entsize.
2063
 
2064
template<int size, bool big_endian>
2065
uint64_t
2066
Sized_relobj_incr<size, big_endian>::do_section_entsize(unsigned int)
2067
{
2068
  gold_unreachable();
2069
}
2070
 
2071
// Return section address.
2072
 
2073
template<int size, bool big_endian>
2074
uint64_t
2075
Sized_relobj_incr<size, big_endian>::do_section_address(unsigned int)
2076
{
2077
  gold_unreachable();
2078
}
2079
 
2080
// Return section type.
2081
 
2082
template<int size, bool big_endian>
2083
unsigned int
2084
Sized_relobj_incr<size, big_endian>::do_section_type(unsigned int)
2085
{
2086
  gold_unreachable();
2087
}
2088
 
2089
// Return the section link field.
2090
 
2091
template<int size, bool big_endian>
2092
unsigned int
2093
Sized_relobj_incr<size, big_endian>::do_section_link(unsigned int)
2094
{
2095
  gold_unreachable();
2096
}
2097
 
2098
// Return the section link field.
2099
 
2100
template<int size, bool big_endian>
2101
unsigned int
2102
Sized_relobj_incr<size, big_endian>::do_section_info(unsigned int)
2103
{
2104
  gold_unreachable();
2105
}
2106
 
2107
// Return the section alignment.
2108
 
2109
template<int size, bool big_endian>
2110
uint64_t
2111
Sized_relobj_incr<size, big_endian>::do_section_addralign(unsigned int)
2112
{
2113
  gold_unreachable();
2114
}
2115
 
2116
// Return the Xindex structure to use.
2117
 
2118
template<int size, bool big_endian>
2119
Xindex*
2120
Sized_relobj_incr<size, big_endian>::do_initialize_xindex()
2121
{
2122
  gold_unreachable();
2123
}
2124
 
2125
// Get symbol counts.
2126
 
2127
template<int size, bool big_endian>
2128
void
2129
Sized_relobj_incr<size, big_endian>::do_get_global_symbol_counts(
2130
    const Symbol_table*, size_t*, size_t*) const
2131
{
2132
  gold_unreachable();
2133
}
2134
 
2135
// Read the relocs.
2136
 
2137
template<int size, bool big_endian>
2138
void
2139
Sized_relobj_incr<size, big_endian>::do_read_relocs(Read_relocs_data*)
2140
{
2141
}
2142
 
2143
// Process the relocs to find list of referenced sections. Used only
2144
// during garbage collection.
2145
 
2146
template<int size, bool big_endian>
2147
void
2148
Sized_relobj_incr<size, big_endian>::do_gc_process_relocs(Symbol_table*,
2149
                                                          Layout*,
2150
                                                          Read_relocs_data*)
2151
{
2152
  gold_unreachable();
2153
}
2154
 
2155
// Scan the relocs and adjust the symbol table.
2156
 
2157
template<int size, bool big_endian>
2158
void
2159
Sized_relobj_incr<size, big_endian>::do_scan_relocs(Symbol_table*,
2160
                                                    Layout* layout,
2161
                                                    Read_relocs_data*)
2162
{
2163
  // Count the incremental relocations for this object.
2164
  unsigned int nsyms = this->input_reader_.get_global_symbol_count();
2165
  this->allocate_incremental_reloc_counts();
2166
  for (unsigned int i = 0; i < nsyms; i++)
2167
    {
2168
      Incremental_global_symbol_reader<big_endian> sym =
2169
          this->input_reader_.get_global_symbol_reader(i);
2170
      unsigned int reloc_count = sym.reloc_count();
2171
      if (reloc_count > 0 && this->incr_reloc_offset_ == -1U)
2172
        this->incr_reloc_offset_ = sym.reloc_offset();
2173
      this->incr_reloc_count_ += reloc_count;
2174
      for (unsigned int j = 0; j < reloc_count; j++)
2175
        this->count_incremental_reloc(i);
2176
    }
2177
  this->incr_reloc_output_index_ =
2178
      layout->incremental_inputs()->get_reloc_count();
2179
  this->finalize_incremental_relocs(layout, false);
2180
 
2181
  // The incoming incremental relocations may not end up in the same
2182
  // location after the incremental update, because the incremental info
2183
  // is regenerated in each link.  Because the new location may overlap
2184
  // with other data in the updated output file, we need to copy the
2185
  // relocations into a buffer so that we can still read them safely
2186
  // after we start writing updates to the output file.
2187
  if (this->incr_reloc_count_ > 0)
2188
    {
2189
      const Incremental_relocs_reader<size, big_endian>& relocs_reader =
2190
          this->ibase_->relocs_reader();
2191
      const unsigned int incr_reloc_size = relocs_reader.reloc_size;
2192
      unsigned int len = this->incr_reloc_count_ * incr_reloc_size;
2193
      this->incr_relocs_ = new unsigned char[len];
2194
      memcpy(this->incr_relocs_,
2195
             relocs_reader.data(this->incr_reloc_offset_),
2196
             len);
2197
    }
2198
}
2199
 
2200
// Count the local symbols.
2201
 
2202
template<int size, bool big_endian>
2203
void
2204
Sized_relobj_incr<size, big_endian>::do_count_local_symbols(
2205
    Stringpool_template<char>* pool,
2206
    Stringpool_template<char>*)
2207
{
2208
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
2209
 
2210
  // Set the count of local symbols based on the incremental info.
2211
  unsigned int nlocals = this->input_reader_.get_local_symbol_count();
2212
  this->local_symbol_count_ = nlocals;
2213
  this->local_symbols_.reserve(nlocals);
2214
 
2215
  // Get views of the base file's symbol table and string table.
2216
  Incremental_binary::View symtab_view(NULL);
2217
  unsigned int symtab_count;
2218
  elfcpp::Elf_strtab strtab(NULL, 0);
2219
  this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
2220
 
2221
  // Read the local symbols from the base file's symbol table.
2222
  off_t off = this->input_reader_.get_local_symbol_offset();
2223
  const unsigned char* symp = symtab_view.data() + off;
2224
  for (unsigned int i = 0; i < nlocals; ++i, symp += sym_size)
2225
    {
2226
      elfcpp::Sym<size, big_endian> sym(symp);
2227
      const char* name;
2228
      if (!strtab.get_c_string(sym.get_st_name(), &name))
2229
        name = "";
2230
      gold_debug(DEBUG_INCREMENTAL, "Local symbol %d: %s", i, name);
2231
      name = pool->add(name, true, NULL);
2232
      this->local_symbols_.push_back(Local_symbol(name,
2233
                                                  sym.get_st_value(),
2234
                                                  sym.get_st_size(),
2235
                                                  sym.get_st_shndx(),
2236
                                                  sym.get_st_type(),
2237
                                                  false));
2238
    }
2239
}
2240
 
2241
// Finalize the local symbols.
2242
 
2243
template<int size, bool big_endian>
2244
unsigned int
2245
Sized_relobj_incr<size, big_endian>::do_finalize_local_symbols(
2246
    unsigned int index,
2247
    off_t off,
2248
    Symbol_table*)
2249
{
2250
  this->local_symbol_index_ = index;
2251
  this->local_symbol_offset_ = off;
2252
  return index + this->local_symbol_count_;
2253
}
2254
 
2255
// Set the offset where local dynamic symbol information will be stored.
2256
 
2257
template<int size, bool big_endian>
2258
unsigned int
2259
Sized_relobj_incr<size, big_endian>::do_set_local_dynsym_indexes(
2260
    unsigned int index)
2261
{
2262
  // FIXME: set local dynsym indexes.
2263
  return index;
2264
}
2265
 
2266
// Set the offset where local dynamic symbol information will be stored.
2267
 
2268
template<int size, bool big_endian>
2269
unsigned int
2270
Sized_relobj_incr<size, big_endian>::do_set_local_dynsym_offset(off_t)
2271
{
2272
  return 0;
2273
}
2274
 
2275
// Relocate the input sections and write out the local symbols.
2276
// We don't actually do any relocation here.  For unchanged input files,
2277
// we reapply relocations only for symbols that have changed; that happens
2278
// in queue_final_tasks.  We do need to rewrite the incremental relocations
2279
// for this object.
2280
 
2281
template<int size, bool big_endian>
2282
void
2283
Sized_relobj_incr<size, big_endian>::do_relocate(const Symbol_table*,
2284
                                                 const Layout* layout,
2285
                                                 Output_file* of)
2286
{
2287
  if (this->incr_reloc_count_ == 0)
2288
    return;
2289
 
2290
  const unsigned int incr_reloc_size =
2291
      Incremental_relocs_reader<size, big_endian>::reloc_size;
2292
 
2293
  // Get a view for the .gnu_incremental_relocs section.
2294
  Incremental_inputs* inputs = layout->incremental_inputs();
2295
  gold_assert(inputs != NULL);
2296
  const off_t relocs_off = inputs->relocs_section()->offset();
2297
  const off_t relocs_size = inputs->relocs_section()->data_size();
2298
  unsigned char* const view = of->get_output_view(relocs_off, relocs_size);
2299
 
2300
  // Copy the relocations from the buffer.
2301
  off_t off = this->incr_reloc_output_index_ * incr_reloc_size;
2302
  unsigned int len = this->incr_reloc_count_ * incr_reloc_size;
2303
  memcpy(view + off, this->incr_relocs_, len);
2304
 
2305
  // The output section table may have changed, so we need to map
2306
  // the old section index to the new section index for each relocation.
2307
  for (unsigned int i = 0; i < this->incr_reloc_count_; ++i)
2308
    {
2309
      unsigned char* pov = view + off + i * incr_reloc_size;
2310
      unsigned int shndx = elfcpp::Swap<32, big_endian>::readval(pov + 4);
2311
      Output_section* os = this->ibase_->output_section(shndx);
2312
      gold_assert(os != NULL);
2313
      shndx = os->out_shndx();
2314
      elfcpp::Swap<32, big_endian>::writeval(pov + 4, shndx);
2315
    }
2316
 
2317
  of->write_output_view(off, len, view);
2318
 
2319
  // Get views into the output file for the portions of the symbol table
2320
  // and the dynamic symbol table that we will be writing.
2321
  off_t symtab_off = layout->symtab_section()->offset();
2322
  off_t output_size = this->local_symbol_count_ * This::sym_size;
2323
  unsigned char* oview = NULL;
2324
  if (output_size > 0)
2325
    oview = of->get_output_view(symtab_off + this->local_symbol_offset_,
2326
                                output_size);
2327
 
2328
  off_t dyn_output_size = this->output_local_dynsym_count_ * sym_size;
2329
  unsigned char* dyn_oview = NULL;
2330
  if (dyn_output_size > 0)
2331
    dyn_oview = of->get_output_view(this->local_dynsym_offset_,
2332
                                    dyn_output_size);
2333
 
2334
  // Write the local symbols.
2335
  unsigned char* ov = oview;
2336
  unsigned char* dyn_ov = dyn_oview;
2337
  const Stringpool* sympool = layout->sympool();
2338
  const Stringpool* dynpool = layout->dynpool();
2339
  Output_symtab_xindex* symtab_xindex = layout->symtab_xindex();
2340
  Output_symtab_xindex* dynsym_xindex = layout->dynsym_xindex();
2341
  for (unsigned int i = 0; i < this->local_symbol_count_; ++i)
2342
    {
2343
      Local_symbol& lsym(this->local_symbols_[i]);
2344
 
2345
      bool is_ordinary;
2346
      unsigned int st_shndx = this->adjust_sym_shndx(i, lsym.st_shndx,
2347
                                                     &is_ordinary);
2348
      if (is_ordinary)
2349
        {
2350
          Output_section* os = this->ibase_->output_section(st_shndx);
2351
          st_shndx = os->out_shndx();
2352
          if (st_shndx >= elfcpp::SHN_LORESERVE)
2353
            {
2354
              symtab_xindex->add(this->local_symbol_index_ + i, st_shndx);
2355
              if (lsym.needs_dynsym_entry)
2356
                dynsym_xindex->add(lsym.output_dynsym_index, st_shndx);
2357
              st_shndx = elfcpp::SHN_XINDEX;
2358
            }
2359
        }
2360
 
2361
      // Write the symbol to the output symbol table.
2362
      {
2363
        elfcpp::Sym_write<size, big_endian> osym(ov);
2364
        osym.put_st_name(sympool->get_offset(lsym.name));
2365
        osym.put_st_value(lsym.st_value);
2366
        osym.put_st_size(lsym.st_size);
2367
        osym.put_st_info(elfcpp::STB_LOCAL,
2368
                         static_cast<elfcpp::STT>(lsym.st_type));
2369
        osym.put_st_other(0);
2370
        osym.put_st_shndx(st_shndx);
2371
        ov += sym_size;
2372
      }
2373
 
2374
      // Write the symbol to the output dynamic symbol table.
2375
      if (lsym.needs_dynsym_entry)
2376
        {
2377
          gold_assert(dyn_ov < dyn_oview + dyn_output_size);
2378
          elfcpp::Sym_write<size, big_endian> osym(dyn_ov);
2379
          osym.put_st_name(dynpool->get_offset(lsym.name));
2380
          osym.put_st_value(lsym.st_value);
2381
          osym.put_st_size(lsym.st_size);
2382
          osym.put_st_info(elfcpp::STB_LOCAL,
2383
                           static_cast<elfcpp::STT>(lsym.st_type));
2384
          osym.put_st_other(0);
2385
          osym.put_st_shndx(st_shndx);
2386
          dyn_ov += sym_size;
2387
        }
2388
    }
2389
 
2390
  if (output_size > 0)
2391
    {
2392
      gold_assert(ov - oview == output_size);
2393
      of->write_output_view(symtab_off + this->local_symbol_offset_,
2394
                            output_size, oview);
2395
    }
2396
 
2397
  if (dyn_output_size > 0)
2398
    {
2399
      gold_assert(dyn_ov - dyn_oview == dyn_output_size);
2400
      of->write_output_view(this->local_dynsym_offset_, dyn_output_size,
2401
                            dyn_oview);
2402
    }
2403
}
2404
 
2405
// Set the offset of a section.
2406
 
2407
template<int size, bool big_endian>
2408
void
2409
Sized_relobj_incr<size, big_endian>::do_set_section_offset(unsigned int,
2410
                                                           uint64_t)
2411
{
2412
}
2413
 
2414
// Class Sized_incr_dynobj.  Most of these methods are not used for
2415
// Incremental objects, but are required to be implemented by the
2416
// base class Object.
2417
 
2418
template<int size, bool big_endian>
2419
Sized_incr_dynobj<size, big_endian>::Sized_incr_dynobj(
2420
    const std::string& name,
2421
    Sized_incremental_binary<size, big_endian>* ibase,
2422
    unsigned int input_file_index)
2423
  : Dynobj(name, NULL), ibase_(ibase),
2424
    input_file_index_(input_file_index),
2425
    input_reader_(ibase->inputs_reader().input_file(input_file_index)),
2426
    symbols_()
2427
{
2428
  if (this->input_reader_.is_in_system_directory())
2429
    this->set_is_in_system_directory();
2430
  if (this->input_reader_.as_needed())
2431
    this->set_as_needed();
2432
  this->set_soname_string(this->input_reader_.get_soname());
2433
  this->set_shnum(0);
2434
}
2435
 
2436
// Read the symbols.
2437
 
2438
template<int size, bool big_endian>
2439
void
2440
Sized_incr_dynobj<size, big_endian>::do_read_symbols(Read_symbols_data*)
2441
{
2442
  gold_unreachable();
2443
}
2444
 
2445
// Lay out the input sections.
2446
 
2447
template<int size, bool big_endian>
2448
void
2449
Sized_incr_dynobj<size, big_endian>::do_layout(
2450
    Symbol_table*,
2451
    Layout*,
2452
    Read_symbols_data*)
2453
{
2454
}
2455
 
2456
// Add the symbols to the symbol table.
2457
 
2458
template<int size, bool big_endian>
2459
void
2460
Sized_incr_dynobj<size, big_endian>::do_add_symbols(
2461
    Symbol_table* symtab,
2462
    Read_symbols_data*,
2463
    Layout*)
2464
{
2465
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
2466
  unsigned char symbuf[sym_size];
2467
  elfcpp::Sym<size, big_endian> sym(symbuf);
2468
  elfcpp::Sym_write<size, big_endian> osym(symbuf);
2469
 
2470
  typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
2471
 
2472
  unsigned int nsyms = this->input_reader_.get_global_symbol_count();
2473
  this->symbols_.resize(nsyms);
2474
 
2475
  Incremental_binary::View symtab_view(NULL);
2476
  unsigned int symtab_count;
2477
  elfcpp::Elf_strtab strtab(NULL, 0);
2478
  this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
2479
 
2480
  Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
2481
  unsigned int isym_count = isymtab.symbol_count();
2482
  unsigned int first_global = symtab_count - isym_count;
2483
 
2484
  const unsigned char* sym_p;
2485
  for (unsigned int i = 0; i < nsyms; ++i)
2486
    {
2487
      bool is_def;
2488
      unsigned int output_symndx =
2489
          this->input_reader_.get_output_symbol_index(i, &is_def);
2490
      sym_p = symtab_view.data() + output_symndx * sym_size;
2491
      elfcpp::Sym<size, big_endian> gsym(sym_p);
2492
      const char* name;
2493
      if (!strtab.get_c_string(gsym.get_st_name(), &name))
2494
        name = "";
2495
 
2496
      typename elfcpp::Elf_types<size>::Elf_Addr v;
2497
      unsigned int shndx;
2498
      elfcpp::STB st_bind = gsym.get_st_bind();
2499
      elfcpp::STT st_type = gsym.get_st_type();
2500
 
2501
      // Local hidden symbols start out as globals, but get converted to
2502
      // to local during output.
2503
      if (st_bind == elfcpp::STB_LOCAL)
2504
        st_bind = elfcpp::STB_GLOBAL;
2505
 
2506
      if (!is_def)
2507
        {
2508
          shndx = elfcpp::SHN_UNDEF;
2509
          v = 0;
2510
        }
2511
      else
2512
        {
2513
          // For a symbol defined in a shared object, the section index
2514
          // is meaningless, as long as it's not SHN_UNDEF.
2515
          shndx = 1;
2516
          v = gsym.get_st_value();
2517
        }
2518
 
2519
      osym.put_st_name(0);
2520
      osym.put_st_value(v);
2521
      osym.put_st_size(gsym.get_st_size());
2522
      osym.put_st_info(st_bind, st_type);
2523
      osym.put_st_other(gsym.get_st_other());
2524
      osym.put_st_shndx(shndx);
2525
 
2526
      this->symbols_[i] =
2527
        symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
2528
      this->ibase_->add_global_symbol(output_symndx - first_global,
2529
                                      this->symbols_[i]);
2530
    }
2531
}
2532
 
2533
// Return TRUE if we should include this object from an archive library.
2534
 
2535
template<int size, bool big_endian>
2536
Archive::Should_include
2537
Sized_incr_dynobj<size, big_endian>::do_should_include_member(
2538
    Symbol_table*,
2539
    Layout*,
2540
    Read_symbols_data*,
2541
    std::string*)
2542
{
2543
  gold_unreachable();
2544
}
2545
 
2546
// Iterate over global symbols, calling a visitor class V for each.
2547
 
2548
template<int size, bool big_endian>
2549
void
2550
Sized_incr_dynobj<size, big_endian>::do_for_all_global_symbols(
2551
    Read_symbols_data*,
2552
    Library_base::Symbol_visitor_base*)
2553
{
2554
  // This routine is not used for dynamic libraries.
2555
}
2556
 
2557
// Iterate over local symbols, calling a visitor class V for each GOT offset
2558
// associated with a local symbol.
2559
 
2560
template<int size, bool big_endian>
2561
void
2562
Sized_incr_dynobj<size, big_endian>::do_for_all_local_got_entries(
2563
    Got_offset_list::Visitor*) const
2564
{
2565
}
2566
 
2567
// Get the size of a section.
2568
 
2569
template<int size, bool big_endian>
2570
uint64_t
2571
Sized_incr_dynobj<size, big_endian>::do_section_size(unsigned int)
2572
{
2573
  gold_unreachable();
2574
}
2575
 
2576
// Get the name of a section.
2577
 
2578
template<int size, bool big_endian>
2579
std::string
2580
Sized_incr_dynobj<size, big_endian>::do_section_name(unsigned int)
2581
{
2582
  gold_unreachable();
2583
}
2584
 
2585
// Return a view of the contents of a section.
2586
 
2587
template<int size, bool big_endian>
2588
Object::Location
2589
Sized_incr_dynobj<size, big_endian>::do_section_contents(unsigned int)
2590
{
2591
  gold_unreachable();
2592
}
2593
 
2594
// Return section flags.
2595
 
2596
template<int size, bool big_endian>
2597
uint64_t
2598
Sized_incr_dynobj<size, big_endian>::do_section_flags(unsigned int)
2599
{
2600
  gold_unreachable();
2601
}
2602
 
2603
// Return section entsize.
2604
 
2605
template<int size, bool big_endian>
2606
uint64_t
2607
Sized_incr_dynobj<size, big_endian>::do_section_entsize(unsigned int)
2608
{
2609
  gold_unreachable();
2610
}
2611
 
2612
// Return section address.
2613
 
2614
template<int size, bool big_endian>
2615
uint64_t
2616
Sized_incr_dynobj<size, big_endian>::do_section_address(unsigned int)
2617
{
2618
  gold_unreachable();
2619
}
2620
 
2621
// Return section type.
2622
 
2623
template<int size, bool big_endian>
2624
unsigned int
2625
Sized_incr_dynobj<size, big_endian>::do_section_type(unsigned int)
2626
{
2627
  gold_unreachable();
2628
}
2629
 
2630
// Return the section link field.
2631
 
2632
template<int size, bool big_endian>
2633
unsigned int
2634
Sized_incr_dynobj<size, big_endian>::do_section_link(unsigned int)
2635
{
2636
  gold_unreachable();
2637
}
2638
 
2639
// Return the section link field.
2640
 
2641
template<int size, bool big_endian>
2642
unsigned int
2643
Sized_incr_dynobj<size, big_endian>::do_section_info(unsigned int)
2644
{
2645
  gold_unreachable();
2646
}
2647
 
2648
// Return the section alignment.
2649
 
2650
template<int size, bool big_endian>
2651
uint64_t
2652
Sized_incr_dynobj<size, big_endian>::do_section_addralign(unsigned int)
2653
{
2654
  gold_unreachable();
2655
}
2656
 
2657
// Return the Xindex structure to use.
2658
 
2659
template<int size, bool big_endian>
2660
Xindex*
2661
Sized_incr_dynobj<size, big_endian>::do_initialize_xindex()
2662
{
2663
  gold_unreachable();
2664
}
2665
 
2666
// Get symbol counts.
2667
 
2668
template<int size, bool big_endian>
2669
void
2670
Sized_incr_dynobj<size, big_endian>::do_get_global_symbol_counts(
2671
    const Symbol_table*, size_t*, size_t*) const
2672
{
2673
  gold_unreachable();
2674
}
2675
 
2676
// Allocate an incremental object of the appropriate size and endianness.
2677
 
2678
Object*
2679
make_sized_incremental_object(
2680
    Incremental_binary* ibase,
2681
    unsigned int input_file_index,
2682
    Incremental_input_type input_type,
2683
    const Incremental_binary::Input_reader* input_reader)
2684
{
2685
  Object* obj = NULL;
2686
  std::string name(input_reader->filename());
2687
 
2688
  switch (parameters->size_and_endianness())
2689
    {
2690
#ifdef HAVE_TARGET_32_LITTLE
2691
    case Parameters::TARGET_32_LITTLE:
2692
      {
2693
        Sized_incremental_binary<32, false>* sized_ibase =
2694
            static_cast<Sized_incremental_binary<32, false>*>(ibase);
2695
        if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2696
          obj = new Sized_incr_dynobj<32, false>(name, sized_ibase,
2697
                                                 input_file_index);
2698
        else
2699
          obj = new Sized_relobj_incr<32, false>(name, sized_ibase,
2700
                                                 input_file_index);
2701
      }
2702
      break;
2703
#endif
2704
#ifdef HAVE_TARGET_32_BIG
2705
    case Parameters::TARGET_32_BIG:
2706
      {
2707
        Sized_incremental_binary<32, true>* sized_ibase =
2708
            static_cast<Sized_incremental_binary<32, true>*>(ibase);
2709
        if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2710
          obj = new Sized_incr_dynobj<32, true>(name, sized_ibase,
2711
                                                input_file_index);
2712
        else
2713
          obj = new Sized_relobj_incr<32, true>(name, sized_ibase,
2714
                                                input_file_index);
2715
      }
2716
      break;
2717
#endif
2718
#ifdef HAVE_TARGET_64_LITTLE
2719
    case Parameters::TARGET_64_LITTLE:
2720
      {
2721
        Sized_incremental_binary<64, false>* sized_ibase =
2722
            static_cast<Sized_incremental_binary<64, false>*>(ibase);
2723
        if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2724
          obj = new Sized_incr_dynobj<64, false>(name, sized_ibase,
2725
                                                 input_file_index);
2726
        else
2727
          obj = new Sized_relobj_incr<64, false>(name, sized_ibase,
2728
                                                 input_file_index);
2729
     }
2730
      break;
2731
#endif
2732
#ifdef HAVE_TARGET_64_BIG
2733
    case Parameters::TARGET_64_BIG:
2734
      {
2735
        Sized_incremental_binary<64, true>* sized_ibase =
2736
            static_cast<Sized_incremental_binary<64, true>*>(ibase);
2737
        if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2738
          obj = new Sized_incr_dynobj<64, true>(name, sized_ibase,
2739
                                                input_file_index);
2740
        else
2741
          obj = new Sized_relobj_incr<64, true>(name, sized_ibase,
2742
                                                input_file_index);
2743
      }
2744
      break;
2745
#endif
2746
    default:
2747
      gold_unreachable();
2748
    }
2749
 
2750
  gold_assert(obj != NULL);
2751
  return obj;
2752
}
2753
 
2754
// Copy the unused symbols from the incremental input info.
2755
// We need to do this because we may be overwriting the incremental
2756
// input info in the base file before we write the new incremental
2757
// info.
2758
void
2759
Incremental_library::copy_unused_symbols()
2760
{
2761
  unsigned int symcount = this->input_reader_->get_unused_symbol_count();
2762
  this->unused_symbols_.reserve(symcount);
2763
  for (unsigned int i = 0; i < symcount; ++i)
2764
    {
2765
      std::string name(this->input_reader_->get_unused_symbol(i));
2766
      this->unused_symbols_.push_back(name);
2767
    }
2768
}
2769
 
2770
// Iterator for unused global symbols in the library.
2771
void
2772
Incremental_library::do_for_all_unused_symbols(Symbol_visitor_base* v) const
2773
{
2774
  for (Symbol_list::const_iterator p = this->unused_symbols_.begin();
2775
       p != this->unused_symbols_.end();
2776
       ++p)
2777
  v->visit(p->c_str());
2778
}
2779
 
2780
// Instantiate the templates we need.
2781
 
2782
#ifdef HAVE_TARGET_32_LITTLE
2783
template
2784
class Sized_incremental_binary<32, false>;
2785
 
2786
template
2787
class Sized_relobj_incr<32, false>;
2788
 
2789
template
2790
class Sized_incr_dynobj<32, false>;
2791
#endif
2792
 
2793
#ifdef HAVE_TARGET_32_BIG
2794
template
2795
class Sized_incremental_binary<32, true>;
2796
 
2797
template
2798
class Sized_relobj_incr<32, true>;
2799
 
2800
template
2801
class Sized_incr_dynobj<32, true>;
2802
#endif
2803
 
2804
#ifdef HAVE_TARGET_64_LITTLE
2805
template
2806
class Sized_incremental_binary<64, false>;
2807
 
2808
template
2809
class Sized_relobj_incr<64, false>;
2810
 
2811
template
2812
class Sized_incr_dynobj<64, false>;
2813
#endif
2814
 
2815
#ifdef HAVE_TARGET_64_BIG
2816
template
2817
class Sized_incremental_binary<64, true>;
2818
 
2819
template
2820
class Sized_relobj_incr<64, true>;
2821
 
2822
template
2823
class Sized_incr_dynobj<64, true>;
2824
#endif
2825
 
2826
} // End namespace gold.

powered by: WebSVN 2.1.0

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