Line 159... |
Line 159... |
// flag that will cause errors to be treated seriously.
|
// flag that will cause errors to be treated seriously.
|
vexplain_no_incremental(format, args);
|
vexplain_no_incremental(format, args);
|
va_end(args);
|
va_end(args);
|
}
|
}
|
|
|
|
// Return TRUE if a section of type SH_TYPE can be updated in place
|
|
// during an incremental update. We can update sections of type PROGBITS,
|
|
// NOBITS, INIT_ARRAY, FINI_ARRAY, PREINIT_ARRAY, and NOTE. All others
|
|
// will be regenerated.
|
|
|
|
bool
|
|
can_incremental_update(unsigned int sh_type)
|
|
{
|
|
return (sh_type == elfcpp::SHT_PROGBITS
|
|
|| sh_type == elfcpp::SHT_NOBITS
|
|
|| sh_type == elfcpp::SHT_INIT_ARRAY
|
|
|| sh_type == elfcpp::SHT_FINI_ARRAY
|
|
|| sh_type == elfcpp::SHT_PREINIT_ARRAY
|
|
|| sh_type == elfcpp::SHT_NOTE);
|
|
}
|
|
|
// Find the .gnu_incremental_inputs section and related sections.
|
// Find the .gnu_incremental_inputs section and related sections.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
bool
|
bool
|
Sized_incremental_binary<size, big_endian>::find_incremental_inputs_sections(
|
Sized_incremental_binary<size, big_endian>::find_incremental_inputs_sections(
|
Line 667... |
Line 683... |
unsigned int plt_desc = got_plt_reader.get_plt_desc(i);
|
unsigned int plt_desc = got_plt_reader.get_plt_desc(i);
|
// FIXME: This should really be a fatal error (corrupt input).
|
// FIXME: This should really be a fatal error (corrupt input).
|
gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
|
gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
|
Symbol* sym = this->global_symbol(plt_desc - first_global);
|
Symbol* sym = this->global_symbol(plt_desc - first_global);
|
// Add the PLT entry only if the symbol is still referenced.
|
// Add the PLT entry only if the symbol is still referenced.
|
if (sym->in_reg())
|
if (sym != NULL && 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(symtab, layout, i, sym);
|
target->register_global_plt_entry(symtab, layout, i, sym);
|
Line 1948... |
Line 1964... |
: Sized_relobj<size, big_endian>(name, NULL), ibase_(ibase),
|
: Sized_relobj<size, big_endian>(name, NULL), ibase_(ibase),
|
input_file_index_(input_file_index),
|
input_file_index_(input_file_index),
|
input_reader_(ibase->inputs_reader().input_file(input_file_index)),
|
input_reader_(ibase->inputs_reader().input_file(input_file_index)),
|
local_symbol_count_(0), output_local_dynsym_count_(0),
|
local_symbol_count_(0), output_local_dynsym_count_(0),
|
local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0),
|
local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0),
|
symbols_(), incr_reloc_offset_(-1U), incr_reloc_count_(0),
|
symbols_(), defined_count_(0), incr_reloc_offset_(-1U),
|
incr_reloc_output_index_(0), incr_relocs_(NULL), local_symbols_()
|
incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL),
|
|
local_symbols_()
|
{
|
{
|
if (this->input_reader_.is_in_system_directory())
|
if (this->input_reader_.is_in_system_directory())
|
this->set_is_in_system_directory();
|
this->set_is_in_system_directory();
|
const unsigned int shnum = this->input_reader_.get_input_section_count() + 1;
|
const unsigned int shnum = this->input_reader_.get_input_section_count() + 1;
|
this->set_shnum(shnum);
|
this->set_shnum(shnum);
|
Line 2006... |
Line 2023... |
const char* signature = this->input_reader_.get_comdat_group_signature(i);
|
const char* signature = this->input_reader_.get_comdat_group_signature(i);
|
if (signature == NULL || signature[0] == '\0')
|
if (signature == NULL || signature[0] == '\0')
|
this->error(_("COMDAT group has no signature"));
|
this->error(_("COMDAT group has no signature"));
|
bool keep = layout->find_or_add_kept_section(signature, this, i, true,
|
bool keep = layout->find_or_add_kept_section(signature, this, i, true,
|
true, NULL);
|
true, NULL);
|
if (!keep)
|
if (keep)
|
|
incremental_inputs->report_comdat_group(this, signature);
|
|
else
|
this->error(_("COMDAT group %s included twice in incremental link"),
|
this->error(_("COMDAT group %s included twice in incremental link"),
|
signature);
|
signature);
|
}
|
}
|
}
|
}
|
|
|
Line 2100... |
Line 2119... |
osym.put_st_other(gsym.get_st_other());
|
osym.put_st_other(gsym.get_st_other());
|
osym.put_st_shndx(shndx);
|
osym.put_st_shndx(shndx);
|
|
|
Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym);
|
Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym);
|
|
|
|
if (shndx != elfcpp::SHN_UNDEF)
|
|
++this->defined_count_;
|
|
|
// If this is a linker-defined symbol that hasn't yet been defined,
|
// If this is a linker-defined symbol that hasn't yet been defined,
|
// define it now.
|
// define it now.
|
if (input_shndx == -1U && !res->is_defined())
|
if (input_shndx == -1U && !res->is_defined())
|
{
|
{
|
shndx = gsym.get_st_shndx();
|
shndx = gsym.get_st_shndx();
|
Line 2263... |
Line 2285... |
// Get symbol counts.
|
// Get symbol counts.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Sized_relobj_incr<size, big_endian>::do_get_global_symbol_counts(
|
Sized_relobj_incr<size, big_endian>::do_get_global_symbol_counts(
|
const Symbol_table*, size_t*, size_t*) const
|
const Symbol_table*,
|
{
|
size_t* defined,
|
gold_unreachable();
|
size_t* used) const
|
|
{
|
|
*defined = this->defined_count_;
|
|
size_t count = 0;
|
|
for (typename Symbols::const_iterator p = this->symbols_.begin();
|
|
p != this->symbols_.end();
|
|
++p)
|
|
if (*p != NULL
|
|
&& (*p)->source() == Symbol::FROM_OBJECT
|
|
&& (*p)->object() == this
|
|
&& (*p)->is_defined())
|
|
++count;
|
|
*used = count;
|
}
|
}
|
|
|
// Read the relocs.
|
// Read the relocs.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
Line 2559... |
Line 2593... |
Sized_incremental_binary<size, big_endian>* ibase,
|
Sized_incremental_binary<size, big_endian>* ibase,
|
unsigned int input_file_index)
|
unsigned int input_file_index)
|
: Dynobj(name, NULL), ibase_(ibase),
|
: Dynobj(name, NULL), ibase_(ibase),
|
input_file_index_(input_file_index),
|
input_file_index_(input_file_index),
|
input_reader_(ibase->inputs_reader().input_file(input_file_index)),
|
input_reader_(ibase->inputs_reader().input_file(input_file_index)),
|
symbols_()
|
symbols_(), defined_count_(0)
|
{
|
{
|
if (this->input_reader_.is_in_system_directory())
|
if (this->input_reader_.is_in_system_directory())
|
this->set_is_in_system_directory();
|
this->set_is_in_system_directory();
|
if (this->input_reader_.as_needed())
|
if (this->input_reader_.as_needed())
|
this->set_as_needed();
|
this->set_as_needed();
|
Line 2657... |
Line 2691... |
{
|
{
|
// For a symbol defined in a shared object, the section index
|
// For a symbol defined in a shared object, the section index
|
// is meaningless, as long as it's not SHN_UNDEF.
|
// is meaningless, as long as it's not SHN_UNDEF.
|
shndx = 1;
|
shndx = 1;
|
v = gsym.get_st_value();
|
v = gsym.get_st_value();
|
|
++this->defined_count_;
|
}
|
}
|
|
|
osym.put_st_name(0);
|
osym.put_st_name(0);
|
osym.put_st_value(v);
|
osym.put_st_value(v);
|
osym.put_st_size(gsym.get_st_size());
|
osym.put_st_size(gsym.get_st_size());
|
Line 2825... |
Line 2860... |
// Get symbol counts.
|
// Get symbol counts.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Sized_incr_dynobj<size, big_endian>::do_get_global_symbol_counts(
|
Sized_incr_dynobj<size, big_endian>::do_get_global_symbol_counts(
|
const Symbol_table*, size_t*, size_t*) const
|
const Symbol_table*,
|
{
|
size_t* defined,
|
gold_unreachable();
|
size_t* used) const
|
|
{
|
|
*defined = this->defined_count_;
|
|
size_t count = 0;
|
|
for (typename Symbols::const_iterator p = this->symbols_.begin();
|
|
p != this->symbols_.end();
|
|
++p)
|
|
if (*p != NULL
|
|
&& (*p)->source() == Symbol::FROM_OBJECT
|
|
&& (*p)->object() == this
|
|
&& (*p)->is_defined()
|
|
&& (*p)->dynsym_index() != -1U)
|
|
++count;
|
|
*used = count;
|
}
|
}
|
|
|
// Allocate an incremental object of the appropriate size and endianness.
|
// Allocate an incremental object of the appropriate size and endianness.
|
|
|
Object*
|
Object*
|