* archive.cc (Archive::include_member): Adjust call to
[deliverable/binutils-gdb.git] / gold / incremental.cc
CommitLineData
0e879927
ILT
1// inremental.cc -- incremental linking support for gold
2
09ec0418 3// Copyright 2009, 2010 Free Software Foundation, Inc.
0e879927
ILT
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"
c549a694
ILT
24
25#include <cstdarg>
a81ee015 26#include "libiberty.h"
c549a694 27
0e879927 28#include "elfcpp.h"
cdc29364 29#include "options.h"
3ce2c28e 30#include "output.h"
09ec0418 31#include "symtab.h"
3ce2c28e 32#include "incremental.h"
98fa85cb 33#include "archive.h"
cdc29364 34#include "object.h"
44453f85 35#include "output.h"
c549a694 36#include "target-select.h"
0e70b911 37#include "target.h"
cdc29364
CC
38#include "fileread.h"
39#include "script.h"
0e879927 40
0e879927
ILT
41namespace gold {
42
43// Version information. Will change frequently during the development, later
44// we could think about backward (and forward?) compatibility.
c4aa1e2d 45const unsigned int INCREMENTAL_LINK_VERSION = 1;
0e879927 46
09ec0418
CC
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
51template<int size, bool big_endian>
52class 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:
cdc29364
CC
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
09ec0418
CC
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
0e70b911
CC
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
09ec0418
CC
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
c549a694
ILT
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
127void
128vexplain_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
138void
139explain_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
149void
150Incremental_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
09ec0418
CC
163// Find the .gnu_incremental_inputs section and related sections.
164
c549a694
ILT
165template<int size, bool big_endian>
166bool
b961d0d7 167Sized_incremental_binary<size, big_endian>::find_incremental_inputs_sections(
09ec0418
CC
168 unsigned int* p_inputs_shndx,
169 unsigned int* p_symtab_shndx,
170 unsigned int* p_relocs_shndx,
0e70b911 171 unsigned int* p_got_plt_shndx,
09ec0418 172 unsigned int* p_strtab_shndx)
c549a694 173{
09ec0418
CC
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)
c549a694 184 return false;
09ec0418
CC
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
0e70b911
CC
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
09ec0418
CC
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;
0e70b911
CC
212 if (p_got_plt_shndx != NULL)
213 *p_got_plt_shndx = got_plt_shndx;
09ec0418
CC
214 if (p_strtab_shndx != NULL)
215 *p_strtab_shndx = strtab_shndx;
c549a694
ILT
216 return true;
217}
218
b961d0d7 219// Set up the readers into the incremental info sections.
09ec0418 220
c4aa1e2d 221template<int size, bool big_endian>
b961d0d7
CC
222void
223Sized_incremental_binary<size, big_endian>::setup_readers()
c4aa1e2d 224{
09ec0418
CC
225 unsigned int inputs_shndx;
226 unsigned int symtab_shndx;
227 unsigned int relocs_shndx;
b961d0d7 228 unsigned int got_plt_shndx;
c4aa1e2d 229 unsigned int strtab_shndx;
c4aa1e2d 230
b961d0d7
CC
231 if (!this->find_incremental_inputs_sections(&inputs_shndx, &symtab_shndx,
232 &relocs_shndx, &got_plt_shndx,
233 &strtab_shndx))
234 return;
c4aa1e2d 235
09ec0418
CC
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));
b961d0d7 239 Location got_plt_location(this->elf_file_.section_contents(got_plt_shndx));
c4aa1e2d 240 Location strtab_location(this->elf_file_.section_contents(strtab_shndx));
09ec0418 241
b961d0d7
CC
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);
09ec0418 247
c4aa1e2d 248 elfcpp::Elf_strtab strtab(strtab_view.data(), strtab_location.data_size);
c4aa1e2d 249
b961d0d7
CC
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());
cdc29364
CC
260
261 // Walk the list of input files (a) to setup an Input_reader for each
262 // input file, and (b) to record maps of files added from archive
263 // libraries and scripts.
264 Incremental_inputs_reader<size, big_endian>& inputs = this->inputs_reader_;
265 unsigned int count = inputs.input_file_count();
266 this->input_entry_readers_.reserve(count);
267 this->library_map_.resize(count);
268 this->script_map_.resize(count);
269 for (unsigned int i = 0; i < count; i++)
270 {
271 Input_entry_reader input_file = inputs.input_file(i);
272 this->input_entry_readers_.push_back(Sized_input_reader(input_file));
273 switch (input_file.type())
274 {
275 case INCREMENTAL_INPUT_OBJECT:
276 case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
277 case INCREMENTAL_INPUT_SHARED_LIBRARY:
278 // No special treatment necessary.
279 break;
280 case INCREMENTAL_INPUT_ARCHIVE:
281 {
282 Incremental_library* lib =
283 new Incremental_library(input_file.filename(), i,
284 &this->input_entry_readers_[i]);
285 this->library_map_[i] = lib;
286 unsigned int member_count = input_file.get_member_count();
287 for (unsigned int j = 0; j < member_count; j++)
288 {
289 int member_offset = input_file.get_member_offset(j);
290 int member_index = inputs.input_file_index(member_offset);
291 this->library_map_[member_index] = lib;
292 }
293 }
294 break;
295 case INCREMENTAL_INPUT_SCRIPT:
296 {
297 Script_info* script = new Script_info(input_file.filename());
298 this->script_map_[i] = script;
299 unsigned int object_count = input_file.get_object_count();
300 for (unsigned int j = 0; j < object_count; j++)
301 {
302 int object_offset = input_file.get_object_offset(j);
303 int object_index = inputs.input_file_index(object_offset);
304 this->script_map_[object_index] = script;
305 }
306 }
307 break;
308 default:
309 gold_unreachable();
310 }
311 }
312
b961d0d7
CC
313 this->has_incremental_info_ = true;
314}
315
cdc29364
CC
316// Walk the list of input files given on the command line, and build
317// a direct map of file index to the corresponding input argument.
318
319void
320check_input_args(std::vector<const Input_argument*>& input_args_map,
321 Input_arguments::const_iterator begin,
322 Input_arguments::const_iterator end)
323{
324 for (Input_arguments::const_iterator p = begin;
325 p != end;
326 ++p)
327 {
328 if (p->is_group())
329 {
330 const Input_file_group* group = p->group();
331 check_input_args(input_args_map, group->begin(), group->end());
332 }
333 else if (p->is_lib())
334 {
335 const Input_file_lib* lib = p->lib();
336 check_input_args(input_args_map, lib->begin(), lib->end());
337 }
338 else
339 {
340 gold_assert(p->is_file());
341 unsigned int arg_serial = p->file().arg_serial();
342 if (arg_serial > 0)
343 {
344 gold_assert(arg_serial <= input_args_map.size());
345 gold_assert(input_args_map[arg_serial - 1] == 0);
346 input_args_map[arg_serial - 1] = &*p;
347 }
348 }
349 }
350}
351
b961d0d7
CC
352// Determine whether an incremental link based on the existing output file
353// can be done.
354
355template<int size, bool big_endian>
356bool
357Sized_incremental_binary<size, big_endian>::do_check_inputs(
cdc29364 358 const Command_line& cmdline,
b961d0d7
CC
359 Incremental_inputs* incremental_inputs)
360{
cdc29364
CC
361 Incremental_inputs_reader<size, big_endian>& inputs = this->inputs_reader_;
362
b961d0d7
CC
363 if (!this->has_incremental_info_)
364 {
365 explain_no_incremental(_("no incremental data from previous build"));
366 return false;
367 }
c4aa1e2d 368
cdc29364 369 if (inputs.version() != INCREMENTAL_LINK_VERSION)
c4aa1e2d 370 {
09ec0418 371 explain_no_incremental(_("different version of incremental build data"));
c4aa1e2d
ILT
372 return false;
373 }
374
cdc29364 375 if (incremental_inputs->command_line() != inputs.command_line())
c4aa1e2d
ILT
376 {
377 explain_no_incremental(_("command line changed"));
378 return false;
379 }
380
cdc29364
CC
381 // Walk the list of input files given on the command line, and build
382 // a direct map of argument serial numbers to the corresponding input
383 // arguments.
384 this->input_args_map_.resize(cmdline.number_of_input_files());
385 check_input_args(this->input_args_map_, cmdline.begin(), cmdline.end());
386
387 // Walk the list of input files to check for conditions that prevent
388 // an incremental update link.
389 unsigned int count = inputs.input_file_count();
390 for (unsigned int i = 0; i < count; i++)
391 {
392 Input_entry_reader input_file = inputs.input_file(i);
393 switch (input_file.type())
394 {
395 case INCREMENTAL_INPUT_OBJECT:
396 case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
397 case INCREMENTAL_INPUT_SHARED_LIBRARY:
398 case INCREMENTAL_INPUT_ARCHIVE:
399 // No special treatment necessary.
400 break;
401 case INCREMENTAL_INPUT_SCRIPT:
402 if (this->do_file_has_changed(i))
403 {
404 explain_no_incremental(_("%s: script file changed"),
405 input_file.filename());
406 return false;
407 }
408 break;
409 default:
410 gold_unreachable();
411 }
412 }
413
c4aa1e2d
ILT
414 return true;
415}
416
cdc29364 417// Return TRUE if input file N has changed since the last incremental link.
b961d0d7
CC
418
419template<int size, bool big_endian>
420bool
cdc29364
CC
421Sized_incremental_binary<size, big_endian>::do_file_has_changed(
422 unsigned int n) const
b961d0d7 423{
cdc29364
CC
424 Input_entry_reader input_file = this->inputs_reader_.input_file(n);
425 Incremental_disposition disp = INCREMENTAL_CHECK;
426 const Input_argument* input_argument = this->get_input_argument(n);
427 if (input_argument != NULL)
428 disp = input_argument->file().options().incremental_disposition();
b961d0d7
CC
429
430 if (disp != INCREMENTAL_CHECK)
cdc29364 431 return disp == INCREMENTAL_CHANGED;
b961d0d7 432
cdc29364
CC
433 const char* filename = input_file.filename();
434 Timespec old_mtime = input_file.get_mtime();
435 Timespec new_mtime;
436 if (!get_mtime(filename, &new_mtime))
437 {
438 // If we can't open get the current modification time, assume it has
439 // changed. If the file doesn't exist, we'll issue an error when we
440 // try to open it later.
441 return true;
442 }
443
444 if (new_mtime.seconds > old_mtime.seconds)
445 return true;
446 if (new_mtime.seconds == old_mtime.seconds
447 && new_mtime.nanoseconds > old_mtime.nanoseconds)
448 return true;
b961d0d7
CC
449 return false;
450}
451
cdc29364
CC
452// Initialize the layout of the output file based on the existing
453// output file.
454
455template<int size, bool big_endian>
456void
457Sized_incremental_binary<size, big_endian>::do_init_layout(Layout* layout)
458{
459 typedef elfcpp::Shdr<size, big_endian> Shdr;
460 const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
461
462 // Get views of the section headers and the section string table.
463 const off_t shoff = this->elf_file_.shoff();
464 const unsigned int shnum = this->elf_file_.shnum();
465 const unsigned int shstrndx = this->elf_file_.shstrndx();
466 Location shdrs_location(shoff, shnum * shdr_size);
467 Location shstrndx_location(this->elf_file_.section_contents(shstrndx));
468 View shdrs_view = this->view(shdrs_location);
469 View shstrndx_view = this->view(shstrndx_location);
470 elfcpp::Elf_strtab shstrtab(shstrndx_view.data(),
471 shstrndx_location.data_size);
472
473 layout->set_incremental_base(this);
474
475 // Initialize the layout.
476 this->section_map_.resize(shnum);
477 const unsigned char* pshdr = shdrs_view.data() + shdr_size;
478 for (unsigned int i = 1; i < shnum; i++)
479 {
480 Shdr shdr(pshdr);
481 const char* name;
482 if (!shstrtab.get_c_string(shdr.get_sh_name(), &name))
483 name = NULL;
484 gold_debug(DEBUG_INCREMENTAL,
485 "Output section: %2d %08lx %08lx %08lx %3d %s",
486 i,
487 static_cast<long>(shdr.get_sh_addr()),
488 static_cast<long>(shdr.get_sh_offset()),
489 static_cast<long>(shdr.get_sh_size()),
490 shdr.get_sh_type(), name ? name : "<null>");
491 this->section_map_[i] = layout->init_fixed_output_section(name, shdr);
492 pshdr += shdr_size;
493 }
494}
495
496// Mark regions of the input file that must be kept unchanged.
497
498template<int size, bool big_endian>
499void
500Sized_incremental_binary<size, big_endian>::do_reserve_layout(
501 unsigned int input_file_index)
502{
503 Input_entry_reader input_file =
504 this->inputs_reader_.input_file(input_file_index);
505
506 if (input_file.type() == INCREMENTAL_INPUT_SHARED_LIBRARY)
507 return;
508
509 unsigned int shnum = input_file.get_input_section_count();
510 for (unsigned int i = 0; i < shnum; i++)
511 {
512 typename Input_entry_reader::Input_section_info sect =
513 input_file.get_input_section(i);
514 if (sect.output_shndx == 0 || sect.sh_offset == -1)
515 continue;
516 Output_section* os = this->section_map_[sect.output_shndx];
517 gold_assert(os != NULL);
518 os->reserve(sect.sh_offset, sect.sh_size);
519 }
520}
521
522// Get a view of the main symbol table and the symbol string table.
b961d0d7
CC
523
524template<int size, bool big_endian>
cdc29364
CC
525void
526Sized_incremental_binary<size, big_endian>::get_symtab_view(
527 View* symtab_view,
528 unsigned int* nsyms,
529 elfcpp::Elf_strtab* strtab)
b961d0d7 530{
cdc29364
CC
531 unsigned int symtab_shndx =
532 this->elf_file_.find_section_by_type(elfcpp::SHT_SYMTAB);
533 gold_assert(symtab_shndx != elfcpp::SHN_UNDEF);
534 Location symtab_location(this->elf_file_.section_contents(symtab_shndx));
535 *symtab_view = this->view(symtab_location);
536 *nsyms = symtab_location.data_size / elfcpp::Elf_sizes<size>::sym_size;
537
538 unsigned int strtab_shndx = this->elf_file_.section_link(symtab_shndx);
539 gold_assert(strtab_shndx != elfcpp::SHN_UNDEF
540 && strtab_shndx < this->elf_file_.shnum());
541
542 Location strtab_location(this->elf_file_.section_contents(strtab_shndx));
543 View strtab_view(this->view(strtab_location));
544 *strtab = elfcpp::Elf_strtab(strtab_view.data(), strtab_location.data_size);
b961d0d7
CC
545}
546
c549a694
ILT
547namespace
548{
549
550// Create a Sized_incremental_binary object of the specified size and
551// endianness. Fails if the target architecture is not supported.
552
553template<int size, bool big_endian>
554Incremental_binary*
555make_sized_incremental_binary(Output_file* file,
556 const elfcpp::Ehdr<size, big_endian>& ehdr)
557{
558 Target* target = select_target(ehdr.get_e_machine(), size, big_endian,
559 ehdr.get_e_ident()[elfcpp::EI_OSABI],
560 ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]);
561 if (target == NULL)
562 {
563 explain_no_incremental(_("unsupported ELF machine number %d"),
564 ehdr.get_e_machine());
565 return NULL;
566 }
567
3aec4f9c
RÁE
568 if (!parameters->target_valid())
569 set_parameters_target(target);
570 else if (target != &parameters->target())
571 gold_error(_("%s: incompatible target"), file->filename());
572
c549a694
ILT
573 return new Sized_incremental_binary<size, big_endian>(file, ehdr, target);
574}
575
576} // End of anonymous namespace.
577
09ec0418
CC
578// Create an Incremental_binary object for FILE. Returns NULL is this is not
579// possible, e.g. FILE is not an ELF file or has an unsupported target. FILE
c549a694
ILT
580// should be opened.
581
582Incremental_binary*
583open_incremental_binary(Output_file* file)
584{
585 off_t filesize = file->filesize();
586 int want = elfcpp::Elf_recognizer::max_header_size;
587 if (filesize < want)
588 want = filesize;
589
590 const unsigned char* p = file->get_input_view(0, want);
591 if (!elfcpp::Elf_recognizer::is_elf_file(p, want))
592 {
593 explain_no_incremental(_("output is not an ELF file."));
594 return NULL;
595 }
596
ac33a407
DK
597 int size = 0;
598 bool big_endian = false;
c549a694
ILT
599 std::string error;
600 if (!elfcpp::Elf_recognizer::is_valid_header(p, want, &size, &big_endian,
601 &error))
602 {
603 explain_no_incremental(error.c_str());
604 return NULL;
605 }
606
607 Incremental_binary* result = NULL;
608 if (size == 32)
609 {
610 if (big_endian)
611 {
612#ifdef HAVE_TARGET_32_BIG
613 result = make_sized_incremental_binary<32, true>(
614 file, elfcpp::Ehdr<32, true>(p));
615#else
616 explain_no_incremental(_("unsupported file: 32-bit, big-endian"));
617#endif
618 }
619 else
620 {
621#ifdef HAVE_TARGET_32_LITTLE
622 result = make_sized_incremental_binary<32, false>(
623 file, elfcpp::Ehdr<32, false>(p));
624#else
625 explain_no_incremental(_("unsupported file: 32-bit, little-endian"));
626#endif
627 }
628 }
629 else if (size == 64)
630 {
631 if (big_endian)
632 {
633#ifdef HAVE_TARGET_64_BIG
634 result = make_sized_incremental_binary<64, true>(
635 file, elfcpp::Ehdr<64, true>(p));
636#else
637 explain_no_incremental(_("unsupported file: 64-bit, big-endian"));
638#endif
639 }
640 else
641 {
642#ifdef HAVE_TARGET_64_LITTLE
643 result = make_sized_incremental_binary<64, false>(
644 file, elfcpp::Ehdr<64, false>(p));
645#else
646 explain_no_incremental(_("unsupported file: 64-bit, little-endian"));
647#endif
648 }
649 }
650 else
651 gold_unreachable();
652
653 return result;
654}
655
09ec0418
CC
656// Class Incremental_inputs.
657
3ce2c28e
ILT
658// Add the command line to the string table, setting
659// command_line_key_. In incremental builds, the command line is
660// stored in .gnu_incremental_inputs so that the next linker run can
661// check if the command line options didn't change.
662
663void
664Incremental_inputs::report_command_line(int argc, const char* const* argv)
665{
666 // Always store 'gold' as argv[0] to avoid a full relink if the user used a
667 // different path to the linker.
668 std::string args("gold");
669 // Copied from collect_argv in main.cc.
670 for (int i = 1; i < argc; ++i)
671 {
09ec0418 672 // Adding/removing these options should not result in a full relink.
8c21d9d3
CC
673 if (strcmp(argv[i], "--incremental") == 0
674 || strcmp(argv[i], "--incremental-full") == 0
675 || strcmp(argv[i], "--incremental-update") == 0
676 || strcmp(argv[i], "--incremental-changed") == 0
b19b0c6d 677 || strcmp(argv[i], "--incremental-unchanged") == 0
cdc29364
CC
678 || strcmp(argv[i], "--incremental-unknown") == 0
679 || is_prefix_of("--debug=", argv[i]))
b19b0c6d
ILT
680 continue;
681
3ce2c28e
ILT
682 args.append(" '");
683 // Now append argv[i], but with all single-quotes escaped
684 const char* argpos = argv[i];
685 while (1)
686 {
687 const int len = strcspn(argpos, "'");
688 args.append(argpos, len);
689 if (argpos[len] == '\0')
690 break;
691 args.append("'\"'\"'");
692 argpos += len + 1;
693 }
694 args.append("'");
695 }
c4aa1e2d
ILT
696
697 this->command_line_ = args;
698 this->strtab_->add(this->command_line_.c_str(), false,
699 &this->command_line_key_);
3ce2c28e
ILT
700}
701
09ec0418
CC
702// Record the input archive file ARCHIVE. This is called by the
703// Add_archive_symbols task before determining which archive members
704// to include. We create the Incremental_archive_entry here and
705// attach it to the Archive, but we do not add it to the list of
706// input objects until report_archive_end is called.
072fe7ce
ILT
707
708void
c7975edd 709Incremental_inputs::report_archive_begin(Library_base* arch,
cdc29364 710 unsigned int arg_serial,
c7975edd 711 Script_info* script_info)
072fe7ce 712{
09ec0418 713 Stringpool::Key filename_key;
e0c52780 714 Timespec mtime = arch->get_mtime();
072fe7ce 715
cdc29364
CC
716 // For a file loaded from a script, don't record its argument serial number.
717 if (script_info != NULL)
718 arg_serial = 0;
719
09ec0418
CC
720 this->strtab_->add(arch->filename().c_str(), false, &filename_key);
721 Incremental_archive_entry* entry =
cdc29364 722 new Incremental_archive_entry(filename_key, arg_serial, mtime);
09ec0418 723 arch->set_incremental_info(entry);
c7975edd
CC
724
725 if (script_info != NULL)
726 {
727 Incremental_script_entry* script_entry = script_info->incremental_info();
728 gold_assert(script_entry != NULL);
729 script_entry->add_object(entry);
730 }
072fe7ce
ILT
731}
732
e0c52780
CC
733// Visitor class for processing the unused global symbols in a library.
734// An instance of this class is passed to the library's
735// for_all_unused_symbols() iterator, which will call the visit()
736// function for each global symbol defined in each unused library
737// member. We add those symbol names to the incremental info for the
738// library.
739
740class Unused_symbol_visitor : public Library_base::Symbol_visitor_base
741{
742 public:
743 Unused_symbol_visitor(Incremental_archive_entry* entry, Stringpool* strtab)
744 : entry_(entry), strtab_(strtab)
745 { }
746
747 void
748 visit(const char* sym)
749 {
750 Stringpool::Key symbol_key;
751 this->strtab_->add(sym, true, &symbol_key);
752 this->entry_->add_unused_global_symbol(symbol_key);
753 }
754
755 private:
756 Incremental_archive_entry* entry_;
757 Stringpool* strtab_;
758};
759
09ec0418
CC
760// Finish recording the input archive file ARCHIVE. This is called by the
761// Add_archive_symbols task after determining which archive members
762// to include.
072fe7ce
ILT
763
764void
e0c52780 765Incremental_inputs::report_archive_end(Library_base* arch)
072fe7ce 766{
09ec0418
CC
767 Incremental_archive_entry* entry = arch->incremental_info();
768
769 gold_assert(entry != NULL);
cdc29364 770 this->inputs_.push_back(entry);
09ec0418
CC
771
772 // Collect unused global symbols.
e0c52780
CC
773 Unused_symbol_visitor v(entry, this->strtab_);
774 arch->for_all_unused_symbols(&v);
072fe7ce
ILT
775}
776
09ec0418
CC
777// Record the input object file OBJ. If ARCH is not NULL, attach
778// the object file to the archive. This is called by the
779// Add_symbols task after finding out the type of the file.
072fe7ce
ILT
780
781void
cdc29364
CC
782Incremental_inputs::report_object(Object* obj, unsigned int arg_serial,
783 Library_base* arch, Script_info* script_info)
072fe7ce 784{
09ec0418 785 Stringpool::Key filename_key;
cdc29364
CC
786 Timespec mtime = obj->get_mtime();
787
788 // For a file loaded from a script, don't record its argument serial number.
789 if (script_info != NULL)
790 arg_serial = 0;
09ec0418
CC
791
792 this->strtab_->add(obj->name().c_str(), false, &filename_key);
793 Incremental_object_entry* obj_entry =
cdc29364
CC
794 new Incremental_object_entry(filename_key, obj, arg_serial, mtime);
795 if (obj->is_in_system_directory())
796 obj_entry->set_is_in_system_directory();
09ec0418 797 this->inputs_.push_back(obj_entry);
072fe7ce 798
09ec0418
CC
799 if (arch != NULL)
800 {
801 Incremental_archive_entry* arch_entry = arch->incremental_info();
802 gold_assert(arch_entry != NULL);
803 arch_entry->add_object(obj_entry);
804 }
805
c7975edd
CC
806 if (script_info != NULL)
807 {
808 Incremental_script_entry* script_entry = script_info->incremental_info();
809 gold_assert(script_entry != NULL);
810 script_entry->add_object(obj_entry);
811 }
812
09ec0418
CC
813 this->current_object_ = obj;
814 this->current_object_entry_ = obj_entry;
072fe7ce
ILT
815}
816
09ec0418
CC
817// Record the input object file OBJ. If ARCH is not NULL, attach
818// the object file to the archive. This is called by the
819// Add_symbols task after finding out the type of the file.
072fe7ce
ILT
820
821void
09ec0418
CC
822Incremental_inputs::report_input_section(Object* obj, unsigned int shndx,
823 const char* name, off_t sh_size)
072fe7ce 824{
09ec0418 825 Stringpool::Key key = 0;
072fe7ce 826
09ec0418
CC
827 if (name != NULL)
828 this->strtab_->add(name, true, &key);
829
830 gold_assert(obj == this->current_object_);
831 this->current_object_entry_->add_input_section(shndx, key, sh_size);
832}
833
834// Record that the input argument INPUT is a script SCRIPT. This is
835// called by read_script after parsing the script and reading the list
836// of inputs added by this script.
837
838void
cdc29364
CC
839Incremental_inputs::report_script(Script_info* script,
840 unsigned int arg_serial,
841 Timespec mtime)
09ec0418
CC
842{
843 Stringpool::Key filename_key;
844
cdc29364 845 this->strtab_->add(script->filename().c_str(), false, &filename_key);
09ec0418 846 Incremental_script_entry* entry =
cdc29364 847 new Incremental_script_entry(filename_key, arg_serial, script, mtime);
09ec0418 848 this->inputs_.push_back(entry);
c7975edd 849 script->set_incremental_info(entry);
072fe7ce
ILT
850}
851
3ce2c28e
ILT
852// Finalize the incremental link information. Called from
853// Layout::finalize.
854
855void
856Incremental_inputs::finalize()
857{
09ec0418 858 // Finalize the string table.
3ce2c28e
ILT
859 this->strtab_->set_string_offsets();
860}
861
09ec0418 862// Create the .gnu_incremental_inputs, _symtab, and _relocs input sections.
3ce2c28e 863
09ec0418
CC
864void
865Incremental_inputs::create_data_sections(Symbol_table* symtab)
3ce2c28e
ILT
866{
867 switch (parameters->size_and_endianness())
868 {
869#ifdef HAVE_TARGET_32_LITTLE
870 case Parameters::TARGET_32_LITTLE:
09ec0418
CC
871 this->inputs_section_ =
872 new Output_section_incremental_inputs<32, false>(this, symtab);
873 break;
3ce2c28e
ILT
874#endif
875#ifdef HAVE_TARGET_32_BIG
876 case Parameters::TARGET_32_BIG:
09ec0418
CC
877 this->inputs_section_ =
878 new Output_section_incremental_inputs<32, true>(this, symtab);
879 break;
3ce2c28e
ILT
880#endif
881#ifdef HAVE_TARGET_64_LITTLE
882 case Parameters::TARGET_64_LITTLE:
09ec0418
CC
883 this->inputs_section_ =
884 new Output_section_incremental_inputs<64, false>(this, symtab);
885 break;
3ce2c28e
ILT
886#endif
887#ifdef HAVE_TARGET_64_BIG
888 case Parameters::TARGET_64_BIG:
09ec0418
CC
889 this->inputs_section_ =
890 new Output_section_incremental_inputs<64, true>(this, symtab);
891 break;
3ce2c28e
ILT
892#endif
893 default:
894 gold_unreachable();
072fe7ce 895 }
09ec0418
CC
896 this->symtab_section_ = new Output_data_space(4, "** incremental_symtab");
897 this->relocs_section_ = new Output_data_space(4, "** incremental_relocs");
0e70b911 898 this->got_plt_section_ = new Output_data_space(4, "** incremental_got_plt");
3ce2c28e
ILT
899}
900
09ec0418
CC
901// Return the sh_entsize value for the .gnu_incremental_relocs section.
902unsigned int
903Incremental_inputs::relocs_entsize() const
904{
905 return 8 + 2 * parameters->target().get_size() / 8;
906}
907
908// Class Output_section_incremental_inputs.
909
910// Finalize the offsets for each input section and supplemental info block,
911// and set the final data size of the incremental output sections.
3ce2c28e
ILT
912
913template<int size, bool big_endian>
09ec0418
CC
914void
915Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
072fe7ce 916{
09ec0418
CC
917 const Incremental_inputs* inputs = this->inputs_;
918 const unsigned int sizeof_addr = size / 8;
919 const unsigned int rel_size = 8 + 2 * sizeof_addr;
920
921 // Offset of each input entry.
922 unsigned int input_offset = this->header_size;
923
924 // Offset of each supplemental info block.
925 unsigned int info_offset = this->header_size;
926 info_offset += this->input_entry_size * inputs->input_file_count();
927
928 // Count each input file and its supplemental information block.
929 for (Incremental_inputs::Input_list::const_iterator p =
930 inputs->input_files().begin();
931 p != inputs->input_files().end();
932 ++p)
072fe7ce 933 {
09ec0418
CC
934 // Set the offset of the input file entry.
935 (*p)->set_offset(input_offset);
936 input_offset += this->input_entry_size;
937
938 // Set the offset of the supplemental info block.
939 switch ((*p)->type())
940 {
941 case INCREMENTAL_INPUT_SCRIPT:
c7975edd
CC
942 {
943 Incremental_script_entry *entry = (*p)->script_entry();
944 gold_assert(entry != NULL);
945 (*p)->set_info_offset(info_offset);
946 // Object count.
947 info_offset += 4;
948 // Each member.
949 info_offset += (entry->get_object_count() * 4);
950 }
09ec0418
CC
951 break;
952 case INCREMENTAL_INPUT_OBJECT:
953 case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
954 {
ca09d69a 955 Incremental_object_entry* entry = (*p)->object_entry();
09ec0418
CC
956 gold_assert(entry != NULL);
957 (*p)->set_info_offset(info_offset);
958 // Input section count + global symbol count.
959 info_offset += 8;
960 // Each input section.
961 info_offset += (entry->get_input_section_count()
962 * (8 + 2 * sizeof_addr));
963 // Each global symbol.
964 const Object::Symbols* syms = entry->object()->get_global_symbols();
cdc29364 965 info_offset += syms->size() * 20;
09ec0418
CC
966 }
967 break;
968 case INCREMENTAL_INPUT_SHARED_LIBRARY:
969 {
ca09d69a 970 Incremental_object_entry* entry = (*p)->object_entry();
09ec0418
CC
971 gold_assert(entry != NULL);
972 (*p)->set_info_offset(info_offset);
973 // Global symbol count.
974 info_offset += 4;
975 // Each global symbol.
976 const Object::Symbols* syms = entry->object()->get_global_symbols();
cdc29364
CC
977 gold_assert(syms != NULL);
978 unsigned int nsyms = syms->size();
979 unsigned int nsyms_out = 0;
980 for (unsigned int i = 0; i < nsyms; ++i)
981 {
982 const Symbol* sym = (*syms)[i];
983 if (sym == NULL)
984 continue;
985 if (sym->is_forwarder())
986 sym = this->symtab_->resolve_forwards(sym);
987 if (sym->symtab_index() != -1U)
988 ++nsyms_out;
989 }
990 info_offset += nsyms_out * 4;
09ec0418
CC
991 }
992 break;
993 case INCREMENTAL_INPUT_ARCHIVE:
994 {
ca09d69a 995 Incremental_archive_entry* entry = (*p)->archive_entry();
09ec0418
CC
996 gold_assert(entry != NULL);
997 (*p)->set_info_offset(info_offset);
998 // Member count + unused global symbol count.
999 info_offset += 8;
1000 // Each member.
1001 info_offset += (entry->get_member_count() * 4);
1002 // Each global symbol.
1003 info_offset += (entry->get_unused_global_symbol_count() * 4);
1004 }
1005 break;
1006 default:
1007 gold_unreachable();
1008 }
072fe7ce
ILT
1009 }
1010
09ec0418
CC
1011 this->set_data_size(info_offset);
1012
1013 // Set the size of the .gnu_incremental_symtab section.
1014 inputs->symtab_section()->set_current_data_size(this->symtab_->output_count()
1015 * sizeof(unsigned int));
1016
1017 // Set the size of the .gnu_incremental_relocs section.
1018 inputs->relocs_section()->set_current_data_size(inputs->get_reloc_count()
1019 * rel_size);
0e70b911
CC
1020
1021 // Set the size of the .gnu_incremental_got_plt section.
1022 Sized_target<size, big_endian>* target =
1023 parameters->sized_target<size, big_endian>();
1024 unsigned int got_count = target->got_entry_count();
1025 unsigned int plt_count = target->plt_entry_count();
1026 unsigned int got_plt_size = 8; // GOT entry count, PLT entry count.
1027 got_plt_size = (got_plt_size + got_count + 3) & ~3; // GOT type array.
1028 got_plt_size += got_count * 4 + plt_count * 4; // GOT array, PLT array.
1029 inputs->got_plt_section()->set_current_data_size(got_plt_size);
09ec0418
CC
1030}
1031
1032// Write the contents of the .gnu_incremental_inputs and
1033// .gnu_incremental_symtab sections.
1034
1035template<int size, bool big_endian>
1036void
1037Output_section_incremental_inputs<size, big_endian>::do_write(Output_file* of)
1038{
1039 const Incremental_inputs* inputs = this->inputs_;
1040 Stringpool* strtab = inputs->get_stringpool();
1041
1042 // Get a view into the .gnu_incremental_inputs section.
1043 const off_t off = this->offset();
1044 const off_t oview_size = this->data_size();
1045 unsigned char* const oview = of->get_output_view(off, oview_size);
1046 unsigned char* pov = oview;
1047
1048 // Get a view into the .gnu_incremental_symtab section.
1049 const off_t symtab_off = inputs->symtab_section()->offset();
1050 const off_t symtab_size = inputs->symtab_section()->data_size();
1051 unsigned char* const symtab_view = of->get_output_view(symtab_off,
1052 symtab_size);
1053
1054 // Allocate an array of linked list heads for the .gnu_incremental_symtab
1055 // section. Each element corresponds to a global symbol in the output
1056 // symbol table, and points to the head of the linked list that threads
1057 // through the object file input entries. The value of each element
1058 // is the section-relative offset to a global symbol entry in a
1059 // supplemental information block.
1060 unsigned int global_sym_count = this->symtab_->output_count();
1061 unsigned int* global_syms = new unsigned int[global_sym_count];
1062 memset(global_syms, 0, global_sym_count * sizeof(unsigned int));
1063
1064 // Write the section header.
1065 Stringpool::Key command_line_key = inputs->command_line_key();
1066 pov = this->write_header(pov, inputs->input_file_count(),
1067 strtab->get_offset_from_key(command_line_key));
1068
1069 // Write the list of input files.
1070 pov = this->write_input_files(oview, pov, strtab);
1071
1072 // Write the supplemental information blocks for each input file.
1073 pov = this->write_info_blocks(oview, pov, strtab, global_syms,
1074 global_sym_count);
1075
1076 gold_assert(pov - oview == oview_size);
1077
1078 // Write the .gnu_incremental_symtab section.
1079 gold_assert(global_sym_count * 4 == symtab_size);
1080 this->write_symtab(symtab_view, global_syms, global_sym_count);
1081
1082 delete[] global_syms;
1083
0e70b911
CC
1084 // Write the .gnu_incremental_got_plt section.
1085 const off_t got_plt_off = inputs->got_plt_section()->offset();
1086 const off_t got_plt_size = inputs->got_plt_section()->data_size();
1087 unsigned char* const got_plt_view = of->get_output_view(got_plt_off,
1088 got_plt_size);
1089 this->write_got_plt(got_plt_view, got_plt_size);
1090
09ec0418
CC
1091 of->write_output_view(off, oview_size, oview);
1092 of->write_output_view(symtab_off, symtab_size, symtab_view);
0e70b911 1093 of->write_output_view(got_plt_off, got_plt_size, got_plt_view);
09ec0418
CC
1094}
1095
1096// Write the section header: version, input file count, offset of command line
1097// in the string table, and 4 bytes of padding.
1098
1099template<int size, bool big_endian>
1100unsigned char*
1101Output_section_incremental_inputs<size, big_endian>::write_header(
1102 unsigned char* pov,
1103 unsigned int input_file_count,
1104 section_offset_type command_line_offset)
1105{
1106 Swap32::writeval(pov, INCREMENTAL_LINK_VERSION);
1107 Swap32::writeval(pov + 4, input_file_count);
1108 Swap32::writeval(pov + 8, command_line_offset);
1109 Swap32::writeval(pov + 12, 0);
1110 return pov + this->header_size;
1111}
1112
1113// Write the input file entries.
1114
1115template<int size, bool big_endian>
1116unsigned char*
1117Output_section_incremental_inputs<size, big_endian>::write_input_files(
1118 unsigned char* oview,
1119 unsigned char* pov,
1120 Stringpool* strtab)
1121{
1122 const Incremental_inputs* inputs = this->inputs_;
1123
1124 for (Incremental_inputs::Input_list::const_iterator p =
1125 inputs->input_files().begin();
1126 p != inputs->input_files().end();
1127 ++p)
1128 {
56f75c03 1129 gold_assert(static_cast<unsigned int>(pov - oview) == (*p)->get_offset());
09ec0418
CC
1130 section_offset_type filename_offset =
1131 strtab->get_offset_from_key((*p)->get_filename_key());
1132 const Timespec& mtime = (*p)->get_mtime();
cdc29364
CC
1133 unsigned int flags = (*p)->type();
1134 if ((*p)->is_in_system_directory())
1135 flags |= INCREMENTAL_INPUT_IN_SYSTEM_DIR;
09ec0418
CC
1136 Swap32::writeval(pov, filename_offset);
1137 Swap32::writeval(pov + 4, (*p)->get_info_offset());
1138 Swap64::writeval(pov + 8, mtime.seconds);
1139 Swap32::writeval(pov + 16, mtime.nanoseconds);
cdc29364
CC
1140 Swap16::writeval(pov + 20, flags);
1141 Swap16::writeval(pov + 22, (*p)->arg_serial());
09ec0418
CC
1142 pov += this->input_entry_size;
1143 }
1144 return pov;
1145}
1146
1147// Write the supplemental information blocks.
1148
1149template<int size, bool big_endian>
1150unsigned char*
1151Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
1152 unsigned char* oview,
1153 unsigned char* pov,
1154 Stringpool* strtab,
1155 unsigned int* global_syms,
1156 unsigned int global_sym_count)
1157{
1158 const Incremental_inputs* inputs = this->inputs_;
1159 unsigned int first_global_index = this->symtab_->first_global_index();
1160
1161 for (Incremental_inputs::Input_list::const_iterator p =
1162 inputs->input_files().begin();
1163 p != inputs->input_files().end();
1164 ++p)
1165 {
1166 switch ((*p)->type())
1167 {
1168 case INCREMENTAL_INPUT_SCRIPT:
c7975edd
CC
1169 {
1170 gold_assert(static_cast<unsigned int>(pov - oview)
1171 == (*p)->get_info_offset());
1172 Incremental_script_entry* entry = (*p)->script_entry();
1173 gold_assert(entry != NULL);
1174
1175 // Write the object count.
1176 unsigned int nobjects = entry->get_object_count();
1177 Swap32::writeval(pov, nobjects);
1178 pov += 4;
1179
1180 // For each object, write the offset to its input file entry.
1181 for (unsigned int i = 0; i < nobjects; ++i)
1182 {
1183 Incremental_input_entry* obj = entry->get_object(i);
1184 Swap32::writeval(pov, obj->get_offset());
1185 pov += 4;
1186 }
1187 }
09ec0418
CC
1188 break;
1189
1190 case INCREMENTAL_INPUT_OBJECT:
1191 case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
1192 {
56f75c03
ILT
1193 gold_assert(static_cast<unsigned int>(pov - oview)
1194 == (*p)->get_info_offset());
09ec0418
CC
1195 Incremental_object_entry* entry = (*p)->object_entry();
1196 gold_assert(entry != NULL);
1197 const Object* obj = entry->object();
1198 const Object::Symbols* syms = obj->get_global_symbols();
1199 // Write the input section count and global symbol count.
1200 unsigned int nsections = entry->get_input_section_count();
1201 unsigned int nsyms = syms->size();
1202 Swap32::writeval(pov, nsections);
1203 Swap32::writeval(pov + 4, nsyms);
1204 pov += 8;
1205
cdc29364
CC
1206 // Build a temporary array to map input section indexes
1207 // from the original object file index to the index in the
1208 // incremental info table.
1209 unsigned int* index_map = new unsigned int[obj->shnum()];
1210 memset(index_map, 0, obj->shnum() * sizeof(unsigned int));
1211
09ec0418
CC
1212 // For each input section, write the name, output section index,
1213 // offset within output section, and input section size.
1214 for (unsigned int i = 0; i < nsections; i++)
1215 {
cdc29364
CC
1216 unsigned int shndx = entry->get_input_section_index(i);
1217 index_map[shndx] = i + 1;
09ec0418
CC
1218 Stringpool::Key key = entry->get_input_section_name_key(i);
1219 off_t name_offset = 0;
1220 if (key != 0)
1221 name_offset = strtab->get_offset_from_key(key);
1222 int out_shndx = 0;
1223 off_t out_offset = 0;
1224 off_t sh_size = 0;
cdc29364 1225 Output_section* os = obj->output_section(shndx);
09ec0418
CC
1226 if (os != NULL)
1227 {
1228 out_shndx = os->out_shndx();
cdc29364 1229 out_offset = obj->output_section_offset(shndx);
09ec0418
CC
1230 sh_size = entry->get_input_section_size(i);
1231 }
1232 Swap32::writeval(pov, name_offset);
1233 Swap32::writeval(pov + 4, out_shndx);
1234 Swap::writeval(pov + 8, out_offset);
1235 Swap::writeval(pov + 8 + sizeof_addr, sh_size);
1236 pov += 8 + 2 * sizeof_addr;
1237 }
1238
1239 // For each global symbol, write its associated relocations,
1240 // add it to the linked list of globals, then write the
1241 // supplemental information: global symbol table index,
cdc29364
CC
1242 // input section index, linked list chain pointer, relocation
1243 // count, and offset to the relocations.
09ec0418
CC
1244 for (unsigned int i = 0; i < nsyms; i++)
1245 {
1246 const Symbol* sym = (*syms)[i];
793990de
CC
1247 if (sym->is_forwarder())
1248 sym = this->symtab_->resolve_forwards(sym);
cdc29364
CC
1249 unsigned int shndx = 0;
1250 if (sym->source() == Symbol::FROM_OBJECT
1251 && sym->object() == obj
1252 && sym->is_defined())
1253 {
1254 bool is_ordinary;
1255 unsigned int orig_shndx = sym->shndx(&is_ordinary);
1256 if (is_ordinary)
1257 shndx = index_map[orig_shndx];
1258 }
09ec0418
CC
1259 unsigned int symtab_index = sym->symtab_index();
1260 unsigned int chain = 0;
1261 unsigned int first_reloc = 0;
1262 unsigned int nrelocs = obj->get_incremental_reloc_count(i);
1263 if (nrelocs > 0)
1264 {
1265 gold_assert(symtab_index != -1U
1266 && (symtab_index - first_global_index
1267 < global_sym_count));
1268 first_reloc = obj->get_incremental_reloc_base(i);
1269 chain = global_syms[symtab_index - first_global_index];
1270 global_syms[symtab_index - first_global_index] =
1271 pov - oview;
1272 }
1273 Swap32::writeval(pov, symtab_index);
cdc29364
CC
1274 Swap32::writeval(pov + 4, shndx);
1275 Swap32::writeval(pov + 8, chain);
1276 Swap32::writeval(pov + 12, nrelocs);
1277 Swap32::writeval(pov + 16, first_reloc * 3 * sizeof_addr);
1278 pov += 20;
09ec0418 1279 }
cdc29364
CC
1280
1281 delete[] index_map;
09ec0418
CC
1282 }
1283 break;
1284
1285 case INCREMENTAL_INPUT_SHARED_LIBRARY:
1286 {
56f75c03
ILT
1287 gold_assert(static_cast<unsigned int>(pov - oview)
1288 == (*p)->get_info_offset());
09ec0418
CC
1289 Incremental_object_entry* entry = (*p)->object_entry();
1290 gold_assert(entry != NULL);
1291 const Object* obj = entry->object();
1292 const Object::Symbols* syms = obj->get_global_symbols();
1293
cdc29364
CC
1294 // Skip the global symbol count for now.
1295 unsigned char* orig_pov = pov;
09ec0418
CC
1296 pov += 4;
1297
1298 // For each global symbol, write the global symbol table index.
cdc29364
CC
1299 unsigned int nsyms = syms->size();
1300 unsigned int nsyms_out = 0;
09ec0418
CC
1301 for (unsigned int i = 0; i < nsyms; i++)
1302 {
1303 const Symbol* sym = (*syms)[i];
cdc29364
CC
1304 if (sym == NULL)
1305 continue;
1306 if (sym->is_forwarder())
1307 sym = this->symtab_->resolve_forwards(sym);
1308 if (sym->symtab_index() == -1U)
1309 continue;
1310 unsigned int def_flag = 0;
1311 if (sym->source() == Symbol::FROM_OBJECT
1312 && sym->object() == obj
1313 && sym->is_defined())
1314 def_flag = 1U << 31;
1315 Swap32::writeval(pov, sym->symtab_index() | def_flag);
09ec0418 1316 pov += 4;
cdc29364 1317 ++nsyms_out;
09ec0418 1318 }
cdc29364
CC
1319
1320 // Now write the global symbol count.
1321 Swap32::writeval(orig_pov, nsyms_out);
09ec0418
CC
1322 }
1323 break;
1324
1325 case INCREMENTAL_INPUT_ARCHIVE:
1326 {
56f75c03
ILT
1327 gold_assert(static_cast<unsigned int>(pov - oview)
1328 == (*p)->get_info_offset());
09ec0418
CC
1329 Incremental_archive_entry* entry = (*p)->archive_entry();
1330 gold_assert(entry != NULL);
1331
1332 // Write the member count and unused global symbol count.
1333 unsigned int nmembers = entry->get_member_count();
1334 unsigned int nsyms = entry->get_unused_global_symbol_count();
1335 Swap32::writeval(pov, nmembers);
1336 Swap32::writeval(pov + 4, nsyms);
1337 pov += 8;
1338
1339 // For each member, write the offset to its input file entry.
1340 for (unsigned int i = 0; i < nmembers; ++i)
1341 {
1342 Incremental_object_entry* member = entry->get_member(i);
1343 Swap32::writeval(pov, member->get_offset());
1344 pov += 4;
1345 }
1346
1347 // For each global symbol, write the name offset.
1348 for (unsigned int i = 0; i < nsyms; ++i)
1349 {
1350 Stringpool::Key key = entry->get_unused_global_symbol(i);
1351 Swap32::writeval(pov, strtab->get_offset_from_key(key));
1352 pov += 4;
1353 }
1354 }
1355 break;
1356
1357 default:
1358 gold_unreachable();
1359 }
1360 }
1361 return pov;
1362}
1363
1364// Write the contents of the .gnu_incremental_symtab section.
1365
1366template<int size, bool big_endian>
1367void
1368Output_section_incremental_inputs<size, big_endian>::write_symtab(
1369 unsigned char* pov,
1370 unsigned int* global_syms,
1371 unsigned int global_sym_count)
1372{
1373 for (unsigned int i = 0; i < global_sym_count; ++i)
1374 {
1375 Swap32::writeval(pov, global_syms[i]);
1376 pov += 4;
1377 }
3ce2c28e
ILT
1378}
1379
0e70b911
CC
1380// This struct holds the view information needed to write the
1381// .gnu_incremental_got_plt section.
1382
1383struct Got_plt_view_info
1384{
1385 // Start of the GOT type array in the output view.
1386 unsigned char* got_type_p;
1387 // Start of the GOT descriptor array in the output view.
1388 unsigned char* got_desc_p;
1389 // Start of the PLT descriptor array in the output view.
1390 unsigned char* plt_desc_p;
1391 // Number of GOT entries.
1392 unsigned int got_count;
1393 // Number of PLT entries.
1394 unsigned int plt_count;
1395 // Offset of the first non-reserved PLT entry (this is a target-dependent value).
1396 unsigned int first_plt_entry_offset;
1397 // Size of a PLT entry (this is a target-dependent value).
1398 unsigned int plt_entry_size;
1399 // Value to write in the GOT descriptor array. For global symbols,
1400 // this is the global symbol table index; for local symbols, it is
1401 // the offset of the input file entry in the .gnu_incremental_inputs
1402 // section.
1403 unsigned int got_descriptor;
1404};
1405
1406// Functor class for processing a GOT offset list for local symbols.
1407// Writes the GOT type and symbol index into the GOT type and descriptor
1408// arrays in the output section.
1409
1410template<int size, bool big_endian>
cdc29364 1411class Local_got_offset_visitor : public Got_offset_list::Visitor
0e70b911
CC
1412{
1413 public:
1414 Local_got_offset_visitor(struct Got_plt_view_info& info)
1415 : info_(info)
1416 { }
1417
1418 void
cdc29364 1419 visit(unsigned int got_type, unsigned int got_offset)
0e70b911
CC
1420 {
1421 unsigned int got_index = got_offset / this->got_entry_size_;
1422 gold_assert(got_index < this->info_.got_count);
1423 // We can only handle GOT entry types in the range 0..0x7e
1424 // because we use a byte array to store them, and we use the
1425 // high bit to flag a local symbol.
1426 gold_assert(got_type < 0x7f);
1427 this->info_.got_type_p[got_index] = got_type | 0x80;
1428 unsigned char* pov = this->info_.got_desc_p + got_index * 4;
1429 elfcpp::Swap<32, big_endian>::writeval(pov, this->info_.got_descriptor);
1430 }
1431
1432 private:
1433 static const unsigned int got_entry_size_ = size / 8;
1434 struct Got_plt_view_info& info_;
1435};
1436
1437// Functor class for processing a GOT offset list. Writes the GOT type
1438// and symbol index into the GOT type and descriptor arrays in the output
1439// section.
1440
1441template<int size, bool big_endian>
cdc29364 1442class Global_got_offset_visitor : public Got_offset_list::Visitor
0e70b911
CC
1443{
1444 public:
1445 Global_got_offset_visitor(struct Got_plt_view_info& info)
1446 : info_(info)
1447 { }
1448
1449 void
cdc29364 1450 visit(unsigned int got_type, unsigned int got_offset)
0e70b911
CC
1451 {
1452 unsigned int got_index = got_offset / this->got_entry_size_;
1453 gold_assert(got_index < this->info_.got_count);
1454 // We can only handle GOT entry types in the range 0..0x7e
1455 // because we use a byte array to store them, and we use the
1456 // high bit to flag a local symbol.
1457 gold_assert(got_type < 0x7f);
1458 this->info_.got_type_p[got_index] = got_type;
1459 unsigned char* pov = this->info_.got_desc_p + got_index * 4;
1460 elfcpp::Swap<32, big_endian>::writeval(pov, this->info_.got_descriptor);
1461 }
1462
1463 private:
1464 static const unsigned int got_entry_size_ = size / 8;
1465 struct Got_plt_view_info& info_;
1466};
1467
1468// Functor class for processing the global symbol table. Processes the
1469// GOT offset list for the symbol, and writes the symbol table index
1470// into the PLT descriptor array in the output section.
1471
1472template<int size, bool big_endian>
1473class Global_symbol_visitor_got_plt
1474{
1475 public:
1476 Global_symbol_visitor_got_plt(struct Got_plt_view_info& info)
1477 : info_(info)
1478 { }
1479
1480 void
1481 operator()(const Sized_symbol<size>* sym)
1482 {
1483 typedef Global_got_offset_visitor<size, big_endian> Got_visitor;
1484 const Got_offset_list* got_offsets = sym->got_offset_list();
1485 if (got_offsets != NULL)
1486 {
cdc29364
CC
1487 this->info_.got_descriptor = sym->symtab_index();
1488 Got_visitor v(this->info_);
1489 got_offsets->for_all_got_offsets(&v);
0e70b911
CC
1490 }
1491 if (sym->has_plt_offset())
1492 {
1493 unsigned int plt_index =
1494 ((sym->plt_offset() - this->info_.first_plt_entry_offset)
1495 / this->info_.plt_entry_size);
1496 gold_assert(plt_index < this->info_.plt_count);
1497 unsigned char* pov = this->info_.plt_desc_p + plt_index * 4;
1498 elfcpp::Swap<32, big_endian>::writeval(pov, sym->symtab_index());
1499 }
1500 }
1501
1502 private:
1503 struct Got_plt_view_info& info_;
1504};
1505
1506// Write the contents of the .gnu_incremental_got_plt section.
1507
1508template<int size, bool big_endian>
1509void
1510Output_section_incremental_inputs<size, big_endian>::write_got_plt(
1511 unsigned char* pov,
1512 off_t view_size)
1513{
1514 Sized_target<size, big_endian>* target =
1515 parameters->sized_target<size, big_endian>();
1516
1517 // Set up the view information for the functors.
1518 struct Got_plt_view_info view_info;
1519 view_info.got_count = target->got_entry_count();
1520 view_info.plt_count = target->plt_entry_count();
1521 view_info.first_plt_entry_offset = target->first_plt_entry_offset();
1522 view_info.plt_entry_size = target->plt_entry_size();
1523 view_info.got_type_p = pov + 8;
1524 view_info.got_desc_p = (view_info.got_type_p
1525 + ((view_info.got_count + 3) & ~3));
1526 view_info.plt_desc_p = view_info.got_desc_p + view_info.got_count * 4;
1527
1528 gold_assert(pov + view_size ==
1529 view_info.plt_desc_p + view_info.plt_count * 4);
1530
1531 // Write the section header.
1532 Swap32::writeval(pov, view_info.got_count);
1533 Swap32::writeval(pov + 4, view_info.plt_count);
1534
1535 // Initialize the GOT type array to 0xff (reserved).
1536 memset(view_info.got_type_p, 0xff, view_info.got_count);
1537
1538 // Write the incremental GOT descriptors for local symbols.
cdc29364 1539 typedef Local_got_offset_visitor<size, big_endian> Got_visitor;
0e70b911
CC
1540 for (Incremental_inputs::Input_list::const_iterator p =
1541 this->inputs_->input_files().begin();
1542 p != this->inputs_->input_files().end();
1543 ++p)
1544 {
1545 if ((*p)->type() != INCREMENTAL_INPUT_OBJECT
1546 && (*p)->type() != INCREMENTAL_INPUT_ARCHIVE_MEMBER)
1547 continue;
1548 Incremental_object_entry* entry = (*p)->object_entry();
1549 gold_assert(entry != NULL);
cdc29364 1550 const Object* obj = entry->object();
0e70b911 1551 gold_assert(obj != NULL);
cdc29364
CC
1552 view_info.got_descriptor = (*p)->get_offset();
1553 Got_visitor v(view_info);
1554 obj->for_all_local_got_entries(&v);
0e70b911
CC
1555 }
1556
1557 // Write the incremental GOT and PLT descriptors for global symbols.
1558 typedef Global_symbol_visitor_got_plt<size, big_endian> Symbol_visitor;
1559 symtab_->for_all_symbols<size, Symbol_visitor>(Symbol_visitor(view_info));
1560}
1561
cdc29364
CC
1562// Class Sized_incr_relobj. Most of these methods are not used for
1563// Incremental objects, but are required to be implemented by the
1564// base class Object.
1565
1566template<int size, bool big_endian>
1567Sized_incr_relobj<size, big_endian>::Sized_incr_relobj(
1568 const std::string& name,
1569 Sized_incremental_binary<size, big_endian>* ibase,
1570 unsigned int input_file_index)
1571 : Sized_relobj_base<size, big_endian>(name, NULL), ibase_(ibase),
1572 input_file_index_(input_file_index),
1573 input_reader_(ibase->inputs_reader().input_file(input_file_index)),
1574 symbols_(), section_offsets_(), incr_reloc_offset_(-1U),
1575 incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL)
1576{
1577 if (this->input_reader_.is_in_system_directory())
1578 this->set_is_in_system_directory();
1579 const unsigned int shnum = this->input_reader_.get_input_section_count() + 1;
1580 this->set_shnum(shnum);
1581}
1582
1583// Read the symbols.
1584
1585template<int size, bool big_endian>
1586void
1587Sized_incr_relobj<size, big_endian>::do_read_symbols(Read_symbols_data*)
1588{
1589 gold_unreachable();
1590}
1591
1592// Lay out the input sections.
1593
1594template<int size, bool big_endian>
1595void
1596Sized_incr_relobj<size, big_endian>::do_layout(
1597 Symbol_table*,
1598 Layout* layout,
1599 Read_symbols_data*)
1600{
1601 const unsigned int shnum = this->shnum();
1602 Incremental_inputs* incremental_inputs = layout->incremental_inputs();
1603 gold_assert(incremental_inputs != NULL);
1604 Output_sections& out_sections(this->output_sections());
1605 out_sections.resize(shnum);
1606 this->section_offsets_.resize(shnum);
1607 for (unsigned int i = 1; i < shnum; i++)
1608 {
1609 typename Input_entry_reader::Input_section_info sect =
1610 this->input_reader_.get_input_section(i - 1);
1611 // Add the section to the incremental inputs layout.
1612 incremental_inputs->report_input_section(this, i, sect.name,
1613 sect.sh_size);
1614 if (sect.output_shndx == 0 || sect.sh_offset == -1)
1615 continue;
1616 Output_section* os = this->ibase_->output_section(sect.output_shndx);
1617 gold_assert(os != NULL);
1618 out_sections[i] = os;
1619 this->section_offsets_[i] = static_cast<Address>(sect.sh_offset);
1620 }
1621}
1622
1623// Layout sections whose layout was deferred while waiting for
1624// input files from a plugin.
1625template<int size, bool big_endian>
1626void
1627Sized_incr_relobj<size, big_endian>::do_layout_deferred_sections(Layout*)
1628{
1629}
1630
1631// Add the symbols to the symbol table.
1632
1633template<int size, bool big_endian>
1634void
1635Sized_incr_relobj<size, big_endian>::do_add_symbols(
1636 Symbol_table* symtab,
1637 Read_symbols_data*,
1638 Layout*)
1639{
1640 const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
1641 unsigned char symbuf[sym_size];
1642 elfcpp::Sym<size, big_endian> sym(symbuf);
1643 elfcpp::Sym_write<size, big_endian> osym(symbuf);
1644
1645 typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
1646
1647 unsigned int nsyms = this->input_reader_.get_global_symbol_count();
1648 this->symbols_.resize(nsyms);
1649
1650 Incremental_binary::View symtab_view(NULL);
1651 unsigned int symtab_count;
1652 elfcpp::Elf_strtab strtab(NULL, 0);
1653 this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
1654
1655 // Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
1656 // Incremental_relocs_reader<size, big_endian> irelocs(this->ibase_->relocs_reader());
1657 // unsigned int isym_count = isymtab.symbol_count();
1658 // unsigned int first_global = symtab_count - isym_count;
1659
1660 unsigned const char* sym_p;
1661 for (unsigned int i = 0; i < nsyms; ++i)
1662 {
1663 Incremental_global_symbol_reader<big_endian> info =
1664 this->input_reader_.get_global_symbol_reader(i);
1665 sym_p = symtab_view.data() + info.output_symndx() * sym_size;
1666 elfcpp::Sym<size, big_endian> gsym(sym_p);
1667 const char* name;
1668 if (!strtab.get_c_string(gsym.get_st_name(), &name))
1669 name = "";
1670
1671 typename elfcpp::Elf_types<size>::Elf_Addr v;
1672 unsigned int shndx = gsym.get_st_shndx();
1673 elfcpp::STB st_bind = gsym.get_st_bind();
1674 elfcpp::STT st_type = gsym.get_st_type();
1675
1676 // Local hidden symbols start out as globals, but get converted to
1677 // to local during output.
1678 if (st_bind == elfcpp::STB_LOCAL)
1679 st_bind = elfcpp::STB_GLOBAL;
1680
1681 unsigned int input_shndx = info.shndx();
1682 if (input_shndx == 0)
1683 {
1684 shndx = elfcpp::SHN_UNDEF;
1685 v = 0;
1686 }
1687 else if (shndx != elfcpp::SHN_ABS)
1688 {
1689 // Find the input section and calculate the section-relative value.
1690 gold_assert(shndx != elfcpp::SHN_UNDEF);
1691 v = gsym.get_st_value();
1692 Output_section* os = this->ibase_->output_section(shndx);
1693 gold_assert(os != NULL && os->has_fixed_layout());
1694 typename Input_entry_reader::Input_section_info sect =
1695 this->input_reader_.get_input_section(input_shndx - 1);
1696 gold_assert(sect.output_shndx == shndx);
1697 if (st_type != elfcpp::STT_TLS)
1698 v -= os->address();
1699 v -= sect.sh_offset;
1700 shndx = input_shndx;
1701 }
1702
1703 osym.put_st_name(0);
1704 osym.put_st_value(v);
1705 osym.put_st_size(gsym.get_st_size());
1706 osym.put_st_info(st_bind, st_type);
1707 osym.put_st_other(gsym.get_st_other());
1708 osym.put_st_shndx(shndx);
1709
1710 this->symbols_[i] =
1711 symtab->add_from_incrobj(this, name, NULL, &sym);
1712 }
1713}
1714
1715// Return TRUE if we should include this object from an archive library.
1716
1717template<int size, bool big_endian>
1718Archive::Should_include
1719Sized_incr_relobj<size, big_endian>::do_should_include_member(
1720 Symbol_table*,
1721 Layout*,
1722 Read_symbols_data*,
1723 std::string*)
1724{
1725 gold_unreachable();
1726}
1727
1728// Iterate over global symbols, calling a visitor class V for each.
1729
1730template<int size, bool big_endian>
1731void
1732Sized_incr_relobj<size, big_endian>::do_for_all_global_symbols(
1733 Read_symbols_data*,
1734 Library_base::Symbol_visitor_base*)
1735{
1736 // This routine is not used for incremental objects.
1737}
1738
1739// Iterate over local symbols, calling a visitor class V for each GOT offset
1740// associated with a local symbol.
1741
1742template<int size, bool big_endian>
1743void
1744Sized_incr_relobj<size, big_endian>::do_for_all_local_got_entries(
1745 Got_offset_list::Visitor*) const
1746{
1747 // FIXME: Implement Sized_incr_relobj::do_for_all_local_got_entries.
1748}
1749
1750// Get the size of a section.
1751
1752template<int size, bool big_endian>
1753uint64_t
1754Sized_incr_relobj<size, big_endian>::do_section_size(unsigned int)
1755{
1756 gold_unreachable();
1757}
1758
1759// Get the name of a section.
1760
1761template<int size, bool big_endian>
1762std::string
1763Sized_incr_relobj<size, big_endian>::do_section_name(unsigned int)
1764{
1765 gold_unreachable();
1766}
1767
1768// Return a view of the contents of a section.
1769
1770template<int size, bool big_endian>
1771Object::Location
1772Sized_incr_relobj<size, big_endian>::do_section_contents(unsigned int)
1773{
1774 gold_unreachable();
1775}
1776
1777// Return section flags.
1778
1779template<int size, bool big_endian>
1780uint64_t
1781Sized_incr_relobj<size, big_endian>::do_section_flags(unsigned int)
1782{
1783 gold_unreachable();
1784}
1785
1786// Return section entsize.
1787
1788template<int size, bool big_endian>
1789uint64_t
1790Sized_incr_relobj<size, big_endian>::do_section_entsize(unsigned int)
1791{
1792 gold_unreachable();
1793}
1794
1795// Return section address.
1796
1797template<int size, bool big_endian>
1798uint64_t
1799Sized_incr_relobj<size, big_endian>::do_section_address(unsigned int)
1800{
1801 gold_unreachable();
1802}
1803
1804// Return section type.
1805
1806template<int size, bool big_endian>
1807unsigned int
1808Sized_incr_relobj<size, big_endian>::do_section_type(unsigned int)
1809{
1810 gold_unreachable();
1811}
1812
1813// Return the section link field.
1814
1815template<int size, bool big_endian>
1816unsigned int
1817Sized_incr_relobj<size, big_endian>::do_section_link(unsigned int)
1818{
1819 gold_unreachable();
1820}
1821
1822// Return the section link field.
1823
1824template<int size, bool big_endian>
1825unsigned int
1826Sized_incr_relobj<size, big_endian>::do_section_info(unsigned int)
1827{
1828 gold_unreachable();
1829}
1830
1831// Return the section alignment.
1832
1833template<int size, bool big_endian>
1834uint64_t
1835Sized_incr_relobj<size, big_endian>::do_section_addralign(unsigned int)
1836{
1837 gold_unreachable();
1838}
1839
1840// Return the Xindex structure to use.
1841
1842template<int size, bool big_endian>
1843Xindex*
1844Sized_incr_relobj<size, big_endian>::do_initialize_xindex()
1845{
1846 gold_unreachable();
1847}
1848
1849// Get symbol counts.
1850
1851template<int size, bool big_endian>
1852void
1853Sized_incr_relobj<size, big_endian>::do_get_global_symbol_counts(
1854 const Symbol_table*, size_t*, size_t*) const
1855{
1856 gold_unreachable();
1857}
1858
1859// Read the relocs.
1860
1861template<int size, bool big_endian>
1862void
1863Sized_incr_relobj<size, big_endian>::do_read_relocs(Read_relocs_data*)
1864{
1865}
1866
1867// Process the relocs to find list of referenced sections. Used only
1868// during garbage collection.
1869
1870template<int size, bool big_endian>
1871void
1872Sized_incr_relobj<size, big_endian>::do_gc_process_relocs(Symbol_table*,
1873 Layout*,
1874 Read_relocs_data*)
1875{
1876 gold_unreachable();
1877}
1878
1879// Scan the relocs and adjust the symbol table.
1880
1881template<int size, bool big_endian>
1882void
1883Sized_incr_relobj<size, big_endian>::do_scan_relocs(Symbol_table*,
1884 Layout* layout,
1885 Read_relocs_data*)
1886{
1887 // Count the incremental relocations for this object.
1888 unsigned int nsyms = this->input_reader_.get_global_symbol_count();
1889 this->allocate_incremental_reloc_counts();
1890 for (unsigned int i = 0; i < nsyms; i++)
1891 {
1892 Incremental_global_symbol_reader<big_endian> sym =
1893 this->input_reader_.get_global_symbol_reader(i);
1894 unsigned int reloc_count = sym.reloc_count();
1895 if (reloc_count > 0 && this->incr_reloc_offset_ == -1U)
1896 this->incr_reloc_offset_ = sym.reloc_offset();
1897 this->incr_reloc_count_ += reloc_count;
1898 for (unsigned int j = 0; j < reloc_count; j++)
1899 this->count_incremental_reloc(i);
1900 }
1901 this->incr_reloc_output_index_ =
1902 layout->incremental_inputs()->get_reloc_count();
1903 this->finalize_incremental_relocs(layout, false);
1904
1905 // The incoming incremental relocations may not end up in the same
1906 // location after the incremental update, because the incremental info
1907 // is regenerated in each link. Because the new location may overlap
1908 // with other data in the updated output file, we need to copy the
1909 // relocations into a buffer so that we can still read them safely
1910 // after we start writing updates to the output file.
1911 if (this->incr_reloc_count_ > 0)
1912 {
1913 const Incremental_relocs_reader<size, big_endian>& relocs_reader =
1914 this->ibase_->relocs_reader();
1915 const unsigned int incr_reloc_size = relocs_reader.reloc_size;
1916 unsigned int len = this->incr_reloc_count_ * incr_reloc_size;
1917 this->incr_relocs_ = new unsigned char[len];
1918 memcpy(this->incr_relocs_,
1919 relocs_reader.data(this->incr_reloc_offset_),
1920 len);
1921 }
1922}
1923
1924// Count the local symbols.
1925
1926template<int size, bool big_endian>
1927void
1928Sized_incr_relobj<size, big_endian>::do_count_local_symbols(
1929 Stringpool_template<char>*,
1930 Stringpool_template<char>*)
1931{
1932 // FIXME: Count local symbols.
1933}
1934
1935// Finalize the local symbols.
1936
1937template<int size, bool big_endian>
1938unsigned int
1939Sized_incr_relobj<size, big_endian>::do_finalize_local_symbols(
1940 unsigned int index,
1941 off_t,
1942 Symbol_table*)
1943{
1944 // FIXME: Finalize local symbols.
1945 return index;
1946}
1947
1948// Set the offset where local dynamic symbol information will be stored.
1949
1950template<int size, bool big_endian>
1951unsigned int
1952Sized_incr_relobj<size, big_endian>::do_set_local_dynsym_indexes(
1953 unsigned int index)
1954{
1955 // FIXME: set local dynsym indexes.
1956 return index;
1957}
1958
1959// Set the offset where local dynamic symbol information will be stored.
1960
1961template<int size, bool big_endian>
1962unsigned int
1963Sized_incr_relobj<size, big_endian>::do_set_local_dynsym_offset(off_t)
1964{
1965 return 0;
1966}
1967
1968// Relocate the input sections and write out the local symbols.
1969// We don't actually do any relocation here. For unchanged input files,
1970// we reapply relocations only for symbols that have changed; that happens
1971// in queue_final_tasks. We do need to rewrite the incremental relocations
1972// for this object.
1973
1974template<int size, bool big_endian>
1975void
1976Sized_incr_relobj<size, big_endian>::do_relocate(const Symbol_table*,
1977 const Layout* layout,
1978 Output_file* of)
1979{
1980 if (this->incr_reloc_count_ == 0)
1981 return;
1982
1983 const unsigned int incr_reloc_size =
1984 Incremental_relocs_reader<size, big_endian>::reloc_size;
1985
1986 // Get a view for the .gnu_incremental_relocs section.
1987 Incremental_inputs* inputs = layout->incremental_inputs();
1988 gold_assert(inputs != NULL);
1989 const off_t relocs_off = inputs->relocs_section()->offset();
1990 const off_t relocs_size = inputs->relocs_section()->data_size();
1991 unsigned char* const view = of->get_output_view(relocs_off, relocs_size);
1992
1993 // Copy the relocations from the buffer.
1994 off_t off = this->incr_reloc_output_index_ * incr_reloc_size;
1995 unsigned int len = this->incr_reloc_count_ * incr_reloc_size;
1996 memcpy(view + off, this->incr_relocs_, len);
1997 of->write_output_view(off, len, view);
1998}
1999
2000// Set the offset of a section.
2001
2002template<int size, bool big_endian>
2003void
2004Sized_incr_relobj<size, big_endian>::do_set_section_offset(unsigned int,
2005 uint64_t)
2006{
2007}
2008
2009// Class Sized_incr_dynobj. Most of these methods are not used for
2010// Incremental objects, but are required to be implemented by the
2011// base class Object.
2012
2013template<int size, bool big_endian>
2014Sized_incr_dynobj<size, big_endian>::Sized_incr_dynobj(
2015 const std::string& name,
2016 Sized_incremental_binary<size, big_endian>* ibase,
2017 unsigned int input_file_index)
2018 : Dynobj(name, NULL), ibase_(ibase),
2019 input_file_index_(input_file_index),
2020 input_reader_(ibase->inputs_reader().input_file(input_file_index)),
2021 symbols_()
2022{
2023 if (this->input_reader_.is_in_system_directory())
2024 this->set_is_in_system_directory();
2025 this->set_shnum(0);
2026}
2027
2028// Read the symbols.
2029
2030template<int size, bool big_endian>
2031void
2032Sized_incr_dynobj<size, big_endian>::do_read_symbols(Read_symbols_data*)
2033{
2034 gold_unreachable();
2035}
2036
2037// Lay out the input sections.
2038
2039template<int size, bool big_endian>
2040void
2041Sized_incr_dynobj<size, big_endian>::do_layout(
2042 Symbol_table*,
2043 Layout*,
2044 Read_symbols_data*)
2045{
2046}
2047
2048// Add the symbols to the symbol table.
2049
2050template<int size, bool big_endian>
2051void
2052Sized_incr_dynobj<size, big_endian>::do_add_symbols(
2053 Symbol_table* symtab,
2054 Read_symbols_data*,
2055 Layout*)
2056{
2057 const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
2058 unsigned char symbuf[sym_size];
2059 elfcpp::Sym<size, big_endian> sym(symbuf);
2060 elfcpp::Sym_write<size, big_endian> osym(symbuf);
2061
2062 typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
2063
2064 unsigned int nsyms = this->input_reader_.get_global_symbol_count();
2065 this->symbols_.resize(nsyms);
2066
2067 Incremental_binary::View symtab_view(NULL);
2068 unsigned int symtab_count;
2069 elfcpp::Elf_strtab strtab(NULL, 0);
2070 this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
2071
2072 // Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
2073 // Incremental_relocs_reader<size, big_endian> irelocs(this->ibase_->relocs_reader());
2074 // unsigned int isym_count = isymtab.symbol_count();
2075 // unsigned int first_global = symtab_count - isym_count;
2076
2077 unsigned const char* sym_p;
2078 for (unsigned int i = 0; i < nsyms; ++i)
2079 {
2080 bool is_def;
2081 unsigned int output_symndx =
2082 this->input_reader_.get_output_symbol_index(i, &is_def);
2083 sym_p = symtab_view.data() + output_symndx * sym_size;
2084 elfcpp::Sym<size, big_endian> gsym(sym_p);
2085 const char* name;
2086 if (!strtab.get_c_string(gsym.get_st_name(), &name))
2087 name = "";
2088
2089 typename elfcpp::Elf_types<size>::Elf_Addr v;
2090 unsigned int shndx;
2091 elfcpp::STB st_bind = gsym.get_st_bind();
2092 elfcpp::STT st_type = gsym.get_st_type();
2093
2094 // Local hidden symbols start out as globals, but get converted to
2095 // to local during output.
2096 if (st_bind == elfcpp::STB_LOCAL)
2097 st_bind = elfcpp::STB_GLOBAL;
2098
2099 if (!is_def)
2100 {
2101 shndx = elfcpp::SHN_UNDEF;
2102 v = 0;
2103 }
2104 else
2105 {
2106 // For a symbol defined in a shared object, the section index
2107 // is meaningless, as long as it's not SHN_UNDEF.
2108 shndx = 1;
2109 v = gsym.get_st_value();
2110 }
2111
2112 osym.put_st_name(0);
2113 osym.put_st_value(v);
2114 osym.put_st_size(gsym.get_st_size());
2115 osym.put_st_info(st_bind, st_type);
2116 osym.put_st_other(gsym.get_st_other());
2117 osym.put_st_shndx(shndx);
2118
2119 this->symbols_[i] =
2120 symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
2121 }
2122}
2123
2124// Return TRUE if we should include this object from an archive library.
2125
2126template<int size, bool big_endian>
2127Archive::Should_include
2128Sized_incr_dynobj<size, big_endian>::do_should_include_member(
2129 Symbol_table*,
2130 Layout*,
2131 Read_symbols_data*,
2132 std::string*)
2133{
2134 gold_unreachable();
2135}
2136
2137// Iterate over global symbols, calling a visitor class V for each.
2138
2139template<int size, bool big_endian>
2140void
2141Sized_incr_dynobj<size, big_endian>::do_for_all_global_symbols(
2142 Read_symbols_data*,
2143 Library_base::Symbol_visitor_base*)
2144{
2145 // This routine is not used for dynamic libraries.
2146}
2147
2148// Iterate over local symbols, calling a visitor class V for each GOT offset
2149// associated with a local symbol.
2150
2151template<int size, bool big_endian>
2152void
2153Sized_incr_dynobj<size, big_endian>::do_for_all_local_got_entries(
2154 Got_offset_list::Visitor*) const
2155{
2156 // FIXME: Implement Sized_incr_dynobj::do_for_all_local_got_entries.
2157}
2158
2159// Get the size of a section.
2160
2161template<int size, bool big_endian>
2162uint64_t
2163Sized_incr_dynobj<size, big_endian>::do_section_size(unsigned int)
2164{
2165 gold_unreachable();
2166}
2167
2168// Get the name of a section.
2169
2170template<int size, bool big_endian>
2171std::string
2172Sized_incr_dynobj<size, big_endian>::do_section_name(unsigned int)
2173{
2174 gold_unreachable();
2175}
2176
2177// Return a view of the contents of a section.
2178
2179template<int size, bool big_endian>
2180Object::Location
2181Sized_incr_dynobj<size, big_endian>::do_section_contents(unsigned int)
2182{
2183 gold_unreachable();
2184}
2185
2186// Return section flags.
2187
2188template<int size, bool big_endian>
2189uint64_t
2190Sized_incr_dynobj<size, big_endian>::do_section_flags(unsigned int)
2191{
2192 gold_unreachable();
2193}
2194
2195// Return section entsize.
2196
2197template<int size, bool big_endian>
2198uint64_t
2199Sized_incr_dynobj<size, big_endian>::do_section_entsize(unsigned int)
2200{
2201 gold_unreachable();
2202}
2203
2204// Return section address.
2205
2206template<int size, bool big_endian>
2207uint64_t
2208Sized_incr_dynobj<size, big_endian>::do_section_address(unsigned int)
2209{
2210 gold_unreachable();
2211}
2212
2213// Return section type.
2214
2215template<int size, bool big_endian>
2216unsigned int
2217Sized_incr_dynobj<size, big_endian>::do_section_type(unsigned int)
2218{
2219 gold_unreachable();
2220}
2221
2222// Return the section link field.
2223
2224template<int size, bool big_endian>
2225unsigned int
2226Sized_incr_dynobj<size, big_endian>::do_section_link(unsigned int)
2227{
2228 gold_unreachable();
2229}
2230
2231// Return the section link field.
2232
2233template<int size, bool big_endian>
2234unsigned int
2235Sized_incr_dynobj<size, big_endian>::do_section_info(unsigned int)
2236{
2237 gold_unreachable();
2238}
2239
2240// Return the section alignment.
2241
2242template<int size, bool big_endian>
2243uint64_t
2244Sized_incr_dynobj<size, big_endian>::do_section_addralign(unsigned int)
2245{
2246 gold_unreachable();
2247}
2248
2249// Return the Xindex structure to use.
2250
2251template<int size, bool big_endian>
2252Xindex*
2253Sized_incr_dynobj<size, big_endian>::do_initialize_xindex()
2254{
2255 gold_unreachable();
2256}
2257
2258// Get symbol counts.
2259
2260template<int size, bool big_endian>
2261void
2262Sized_incr_dynobj<size, big_endian>::do_get_global_symbol_counts(
2263 const Symbol_table*, size_t*, size_t*) const
2264{
2265 gold_unreachable();
2266}
2267
2268// Allocate an incremental object of the appropriate size and endianness.
2269
2270Object*
2271make_sized_incremental_object(
2272 Incremental_binary* ibase,
2273 unsigned int input_file_index,
2274 Incremental_input_type input_type,
2275 const Incremental_binary::Input_reader* input_reader)
2276{
2277 Object* obj = NULL;
2278 std::string name(input_reader->filename());
2279
2280 switch (parameters->size_and_endianness())
2281 {
2282#ifdef HAVE_TARGET_32_LITTLE
2283 case Parameters::TARGET_32_LITTLE:
2284 {
2285 Sized_incremental_binary<32, false>* sized_ibase =
2286 static_cast<Sized_incremental_binary<32, false>*>(ibase);
2287 if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2288 obj = new Sized_incr_dynobj<32, false>(name, sized_ibase,
2289 input_file_index);
2290 else
2291 obj = new Sized_incr_relobj<32, false>(name, sized_ibase,
2292 input_file_index);
2293 }
2294 break;
2295#endif
2296#ifdef HAVE_TARGET_32_BIG
2297 case Parameters::TARGET_32_BIG:
2298 {
2299 Sized_incremental_binary<32, true>* sized_ibase =
2300 static_cast<Sized_incremental_binary<32, true>*>(ibase);
2301 if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2302 obj = new Sized_incr_dynobj<32, true>(name, sized_ibase,
2303 input_file_index);
2304 else
2305 obj = new Sized_incr_relobj<32, true>(name, sized_ibase,
2306 input_file_index);
2307 }
2308 break;
2309#endif
2310#ifdef HAVE_TARGET_64_LITTLE
2311 case Parameters::TARGET_64_LITTLE:
2312 {
2313 Sized_incremental_binary<64, false>* sized_ibase =
2314 static_cast<Sized_incremental_binary<64, false>*>(ibase);
2315 if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2316 obj = new Sized_incr_dynobj<64, false>(name, sized_ibase,
2317 input_file_index);
2318 else
2319 obj = new Sized_incr_relobj<64, false>(name, sized_ibase,
2320 input_file_index);
2321 }
2322 break;
2323#endif
2324#ifdef HAVE_TARGET_64_BIG
2325 case Parameters::TARGET_64_BIG:
2326 {
2327 Sized_incremental_binary<64, true>* sized_ibase =
2328 static_cast<Sized_incremental_binary<64, true>*>(ibase);
2329 if (input_type == INCREMENTAL_INPUT_SHARED_LIBRARY)
2330 obj = new Sized_incr_dynobj<64, true>(name, sized_ibase,
2331 input_file_index);
2332 else
2333 obj = new Sized_incr_relobj<64, true>(name, sized_ibase,
2334 input_file_index);
2335 }
2336 break;
2337#endif
2338 default:
2339 gold_unreachable();
2340 }
2341
2342 gold_assert(obj != NULL);
2343 return obj;
2344}
2345
2346// Copy the unused symbols from the incremental input info.
2347// We need to do this because we may be overwriting the incremental
2348// input info in the base file before we write the new incremental
2349// info.
2350void
2351Incremental_library::copy_unused_symbols()
2352{
2353 unsigned int symcount = this->input_reader_->get_unused_symbol_count();
2354 this->unused_symbols_.reserve(symcount);
2355 for (unsigned int i = 0; i < symcount; ++i)
2356 {
2357 std::string name(this->input_reader_->get_unused_symbol(i));
2358 this->unused_symbols_.push_back(name);
2359 }
2360}
2361
2362// Iterator for unused global symbols in the library.
2363void
2364Incremental_library::do_for_all_unused_symbols(Symbol_visitor_base* v) const
2365{
2366 for (Symbol_list::const_iterator p = this->unused_symbols_.begin();
2367 p != this->unused_symbols_.end();
2368 ++p)
2369 v->visit(p->c_str());
2370}
2371
c549a694
ILT
2372// Instantiate the templates we need.
2373
2374#ifdef HAVE_TARGET_32_LITTLE
2375template
2376class Sized_incremental_binary<32, false>;
cdc29364
CC
2377
2378template
2379class Sized_incr_relobj<32, false>;
2380
2381template
2382class Sized_incr_dynobj<32, false>;
c549a694
ILT
2383#endif
2384
2385#ifdef HAVE_TARGET_32_BIG
2386template
2387class Sized_incremental_binary<32, true>;
cdc29364
CC
2388
2389template
2390class Sized_incr_relobj<32, true>;
2391
2392template
2393class Sized_incr_dynobj<32, true>;
c549a694
ILT
2394#endif
2395
2396#ifdef HAVE_TARGET_64_LITTLE
2397template
2398class Sized_incremental_binary<64, false>;
cdc29364
CC
2399
2400template
2401class Sized_incr_relobj<64, false>;
2402
2403template
2404class Sized_incr_dynobj<64, false>;
c549a694
ILT
2405#endif
2406
2407#ifdef HAVE_TARGET_64_BIG
2408template
2409class Sized_incremental_binary<64, true>;
cdc29364
CC
2410
2411template
2412class Sized_incr_relobj<64, true>;
2413
2414template
2415class Sized_incr_dynobj<64, true>;
c549a694
ILT
2416#endif
2417
0e879927 2418} // End namespace gold.
This page took 0.290739 seconds and 4 git commands to generate.