aboutsummaryrefslogtreecommitdiff
path: root/gold/common.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2011-06-08 04:05:25 +0000
committerCary Coutant <ccoutant@google.com>2011-06-08 04:05:25 +0000
commit5146f4485680b0029143c2e17bf5393dd4b89792 (patch)
tree8f95099e332a5f4d6183d8673536c96e1b8d0897 /gold/common.cc
parent26d3c67de1d0e6434dabb908e5a6fa002f5b1db8 (diff)
downloadfsf-binutils-gdb-5146f4485680b0029143c2e17bf5393dd4b89792.zip
fsf-binutils-gdb-5146f4485680b0029143c2e17bf5393dd4b89792.tar.gz
fsf-binutils-gdb-5146f4485680b0029143c2e17bf5393dd4b89792.tar.bz2
* common.cc (Symbol_table::do_allocate_commons_list): For incremental
update, allocate common from bss section's free list. * incremental-dump.cc (dump_incremental_inputs): Print flag for linker-defined symbols. * incremental.cc (Sized_incremental_binary::do_process_got_plt): Skip GOT and PLT entries that are no longer referenced. (Output_section_incremental_inputs::write_info_blocks): Mark linker-defined symbols. (Sized_incr_relobj::do_add_symbols): Process linker-defined symbols. * output.cc (Output_section::allocate): New function. * output.h (Output_section::allocate): New function. * resolve.cc (Symbol_table::report_resolve_problem): Add case for linker-defined symbols. (Symbol::override_base_with_special): Copy is_predefined_ flag. * symtab.cc (Symbol::init_fields): Initialize is_predefined_ flag. (Symbol::init_base_output_data): Likewise. (Symbol::init_base_output_segment): Likewise. (Symbol::init_base_constant): Likewise. (Sized_symbol::init_output_data): Likewise. (Sized_symbol::init_output_segment): Likewise. (Sized_symbol::init_constant): Likewise. (Symbol_table::do_define_in_output_data): Likewise. (Symbol_table::do_define_in_output_segment): Likewise. (Symbol_table::do_define_as_constant): Likewise. * symtab.h (Symbol::is_predefined): New function. (Symbol::init_base_output_data): Add is_predefined parameter. (Symbol::init_base_output_segment): Likewise. (Symbol::init_base_constant): Likewise. (Symbol::is_predefined_): New data member. (Sized_symbol::init_output_data): Add is_predefined parameter. (Sized_symbol::init_output_segment): Likewise. (Sized_symbol::init_constant): Likewise. (enum Symbol_table::Defined): Add INCREMENTAL_BASE.
Diffstat (limited to 'gold/common.cc')
-rw-r--r--gold/common.cc45
1 files changed, 35 insertions, 10 deletions
diff --git a/gold/common.cc b/gold/common.cc
index 6acd2b5..bffa829 100644
--- a/gold/common.cc
+++ b/gold/common.cc
@@ -286,12 +286,23 @@ Symbol_table::do_allocate_commons_list(
gold_unreachable();
}
- Output_data_space* poc = new Output_data_space(addralign, ds_name);
- Output_section* os = layout->add_output_section_data(name,
- elfcpp::SHT_NOBITS,
- flags, poc,
- ORDER_INVALID,
- false);
+ Output_data_space* poc;
+ Output_section* os;
+
+ if (!parameters->incremental_update())
+ {
+ poc = new Output_data_space(addralign, ds_name);
+ os = layout->add_output_section_data(name, elfcpp::SHT_NOBITS, flags,
+ poc, ORDER_INVALID, false);
+ }
+ else
+ {
+ // When doing an incremental update, we need to allocate each common
+ // directly from the output section's free list.
+ poc = NULL;
+ os = layout->find_output_section(name);
+ }
+
if (os != NULL)
{
if (commons_section_type == COMMONS_SMALL)
@@ -329,12 +340,26 @@ Symbol_table::do_allocate_commons_list(
if (mapfile != NULL)
mapfile->report_allocate_common(sym, ssym->symsize());
- off = align_address(off, ssym->value());
- ssym->allocate_common(poc, off);
- off += ssym->symsize();
+ if (poc != NULL)
+ {
+ off = align_address(off, ssym->value());
+ ssym->allocate_common(poc, off);
+ off += ssym->symsize();
+ }
+ else
+ {
+ // For an incremental update, allocate from the free list.
+ off = os->allocate(ssym->symsize(), ssym->value());
+ if (off == -1)
+ gold_fatal(_("out of patch space in section %s; "
+ "relink with --incremental-full"),
+ os->name());
+ ssym->allocate_common(os, off);
+ }
}
- poc->set_current_data_size(off);
+ if (poc != NULL)
+ poc->set_current_data_size(off);
commons->clear();
}