Line 1... |
Line 1... |
// inremental.cc -- incremental linking support for gold
|
// inremental.cc -- incremental linking support for gold
|
|
|
// Copyright 2009, 2010 Free Software Foundation, Inc.
|
// Copyright 2009, 2010, 2011 Free Software Foundation, Inc.
|
// Written by Mikolaj Zalewski <mikolajz@google.com>.
|
// Written by Mikolaj Zalewski <mikolajz@google.com>.
|
|
|
// This file is part of gold.
|
// This file is part of gold.
|
|
|
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
Line 307... |
Line 307... |
}
|
}
|
}
|
}
|
break;
|
break;
|
case INCREMENTAL_INPUT_SCRIPT:
|
case INCREMENTAL_INPUT_SCRIPT:
|
{
|
{
|
Script_info* script = new Script_info(input_file.filename());
|
Script_info* script = new Script_info(input_file.filename(), i);
|
this->script_map_[i] = script;
|
this->script_map_[i] = script;
|
unsigned int object_count = input_file.get_object_count();
|
unsigned int object_count = input_file.get_object_count();
|
for (unsigned int j = 0; j < object_count; j++)
|
for (unsigned int j = 0; j < object_count; j++)
|
{
|
{
|
int object_offset = input_file.get_object_offset(j);
|
int object_offset = input_file.get_object_offset(j);
|
Line 391... |
Line 391... |
return false;
|
return false;
|
}
|
}
|
|
|
if (incremental_inputs->command_line() != inputs.command_line())
|
if (incremental_inputs->command_line() != inputs.command_line())
|
{
|
{
|
|
gold_debug(DEBUG_INCREMENTAL,
|
|
"old command line: %s",
|
|
inputs.command_line());
|
|
gold_debug(DEBUG_INCREMENTAL,
|
|
"new command line: %s",
|
|
incremental_inputs->command_line().c_str());
|
explain_no_incremental(_("command line changed"));
|
explain_no_incremental(_("command line changed"));
|
return false;
|
return false;
|
}
|
}
|
|
|
// Walk the list of input files given on the command line, and build
|
// Walk the list of input files given on the command line, and build
|
Line 440... |
Line 446... |
Sized_incremental_binary<size, big_endian>::do_file_has_changed(
|
Sized_incremental_binary<size, big_endian>::do_file_has_changed(
|
unsigned int n) const
|
unsigned int n) const
|
{
|
{
|
Input_entry_reader input_file = this->inputs_reader_.input_file(n);
|
Input_entry_reader input_file = this->inputs_reader_.input_file(n);
|
Incremental_disposition disp = INCREMENTAL_CHECK;
|
Incremental_disposition disp = INCREMENTAL_CHECK;
|
|
|
|
// For files named in scripts, find the file that was actually named
|
|
// on the command line, so that we can get the incremental disposition
|
|
// flag.
|
|
Script_info* script = this->get_script_info(n);
|
|
if (script != NULL)
|
|
n = script->input_file_index();
|
|
|
const Input_argument* input_argument = this->get_input_argument(n);
|
const Input_argument* input_argument = this->get_input_argument(n);
|
if (input_argument != NULL)
|
if (input_argument != NULL)
|
disp = input_argument->file().options().incremental_disposition();
|
disp = input_argument->file().options().incremental_disposition();
|
|
|
|
// For files at the beginning of the command line (i.e., those added
|
|
// implicitly by gcc), check whether the --incremental-startup-unchanged
|
|
// option was used.
|
|
if (disp == INCREMENTAL_STARTUP)
|
|
disp = parameters->options().incremental_startup_disposition();
|
|
|
if (disp != INCREMENTAL_CHECK)
|
if (disp != INCREMENTAL_CHECK)
|
return disp == INCREMENTAL_CHANGED;
|
return disp == INCREMENTAL_CHANGED;
|
|
|
const char* filename = input_file.filename();
|
const char* filename = input_file.filename();
|
Timespec old_mtime = input_file.get_mtime();
|
Timespec old_mtime = input_file.get_mtime();
|
Line 652... |
Line 672... |
if (sym->in_reg())
|
if (sym->in_reg())
|
{
|
{
|
gold_debug(DEBUG_INCREMENTAL,
|
gold_debug(DEBUG_INCREMENTAL,
|
"PLT entry %d: %s",
|
"PLT entry %d: %s",
|
i, sym->name());
|
i, sym->name());
|
target->register_global_plt_entry(i, sym);
|
target->register_global_plt_entry(symtab, layout, i, sym);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// Emit COPY relocations from the existing output file.
|
// Emit COPY relocations from the existing output file.
|
Line 922... |
Line 942... |
|| strcmp(argv[i], "--incremental-full") == 0
|
|| strcmp(argv[i], "--incremental-full") == 0
|
|| strcmp(argv[i], "--incremental-update") == 0
|
|| strcmp(argv[i], "--incremental-update") == 0
|
|| strcmp(argv[i], "--incremental-changed") == 0
|
|| strcmp(argv[i], "--incremental-changed") == 0
|
|| strcmp(argv[i], "--incremental-unchanged") == 0
|
|| strcmp(argv[i], "--incremental-unchanged") == 0
|
|| strcmp(argv[i], "--incremental-unknown") == 0
|
|| strcmp(argv[i], "--incremental-unknown") == 0
|
|
|| strcmp(argv[i], "--incremental-startup-unchanged") == 0
|
|| is_prefix_of("--incremental-base=", argv[i])
|
|| is_prefix_of("--incremental-base=", argv[i])
|
|
|| is_prefix_of("--incremental-patch=", argv[i])
|
|| is_prefix_of("--debug=", argv[i]))
|
|| is_prefix_of("--debug=", argv[i]))
|
continue;
|
continue;
|
if (strcmp(argv[i], "--incremental-base") == 0
|
if (strcmp(argv[i], "--incremental-base") == 0
|
|
|| strcmp(argv[i], "--incremental-patch") == 0
|
|| strcmp(argv[i], "--debug") == 0)
|
|| strcmp(argv[i], "--debug") == 0)
|
{
|
{
|
// When these options are used without the '=', skip the
|
// When these options are used without the '=', skip the
|
// following parameter as well.
|
// following parameter as well.
|
++i;
|
++i;
|
Line 1644... |
Line 1667... |
if (sym->is_forwarder())
|
if (sym->is_forwarder())
|
sym = this->symtab_->resolve_forwards(sym);
|
sym = this->symtab_->resolve_forwards(sym);
|
if (sym->symtab_index() == -1U)
|
if (sym->symtab_index() == -1U)
|
continue;
|
continue;
|
unsigned int flags = 0;
|
unsigned int flags = 0;
|
if (sym->source() == Symbol::FROM_OBJECT
|
// If the symbol has hidden or internal visibility, we
|
|
// mark it as defined in the shared object so we don't
|
|
// try to resolve it during an incremental update.
|
|
if (sym->visibility() == elfcpp::STV_HIDDEN
|
|
|| sym->visibility() == elfcpp::STV_INTERNAL)
|
|
flags = INCREMENTAL_SHLIB_SYM_DEF;
|
|
else if (sym->source() == Symbol::FROM_OBJECT
|
&& sym->object() == obj
|
&& sym->object() == obj
|
&& sym->is_defined())
|
&& sym->is_defined())
|
flags = INCREMENTAL_SHLIB_SYM_DEF;
|
flags = INCREMENTAL_SHLIB_SYM_DEF;
|
else if (sym->is_copied_from_dynobj()
|
else if (sym->is_copied_from_dynobj()
|
&& this->symtab_->get_copy_source(sym) == dynobj)
|
&& this->symtab_->get_copy_source(sym) == dynobj)
|