From 6d03d481a0827abf92804f8ffaf9ab00593943be Mon Sep 17 00:00:00 2001 From: Sriraman Tallam Date: Wed, 28 Jan 2009 02:25:33 +0000 Subject: 2009-01-20 Sriraman Tallam * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function. --- gold/reloc.cc | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 4 deletions(-) (limited to 'gold/reloc.cc') diff --git a/gold/reloc.cc b/gold/reloc.cc index f6bef1d..669d87b 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -1,6 +1,6 @@ // reloc.cc -- relocate input files for gold. -// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -62,11 +62,28 @@ Read_relocs::run(Workqueue* workqueue) { Read_relocs_data *rd = new Read_relocs_data; this->object_->read_relocs(rd); + this->object_->set_relocs_data(rd); this->object_->release(); - workqueue->queue_next(new Scan_relocs(this->options_, this->symtab_, - this->layout_, this->object_, rd, - this->symtab_lock_, this->blocker_)); + // If garbage collection is desired, we must process the relocs + // instead of scanning the relocs as reloc processing is necessary + // to determine unused sections. + if (parameters->options().gc_sections()) + { + workqueue->queue_next(new Gc_process_relocs(this->options_, + this->symtab_, + this->layout_, + this->object_, rd, + this->symtab_lock_, + this->blocker_)); + } + else + { + workqueue->queue_next(new Scan_relocs(this->options_, this->symtab_, + this->layout_, this->object_, rd, + this->symtab_lock_, + this->blocker_)); + } } // Return a debugging name for the task. @@ -77,6 +94,43 @@ Read_relocs::get_name() const return "Read_relocs " + this->object_->name(); } +// Gc_process_relocs methods. + +// These tasks process the relocations read by Read_relocs and +// determine which sections are referenced and which are garbage. +// This task is done only when --gc-sections is used. + +Task_token* +Gc_process_relocs::is_runnable() +{ + if (this->object_->is_locked()) + return this->object_->token(); + return NULL; +} + +void +Gc_process_relocs::locks(Task_locker* tl) +{ + tl->add(this, this->object_->token()); + tl->add(this, this->blocker_); +} + +void +Gc_process_relocs::run(Workqueue*) +{ + this->object_->gc_process_relocs(this->options_, this->symtab_, this->layout_, + this->rd_); + this->object_->release(); +} + +// Return a debugging name for the task. + +std::string +Gc_process_relocs::get_name() const +{ + return "Gc_process_relocs " + this->object_->name(); +} + // Scan_relocs methods. // These tasks scan the relocations read by Read_relocs and mark up @@ -296,6 +350,47 @@ Sized_relobj::do_read_relocs(Read_relocs_data* rd) } } +// Process the relocs to generate mappings from source sections to referenced +// sections. This is used during garbage colletion to determine garbage +// sections. + +template +void +Sized_relobj::do_gc_process_relocs(const General_options& options, + Symbol_table* symtab, + Layout* layout, + Read_relocs_data* rd) +{ + Sized_target* target = this->sized_target(); + + const unsigned char* local_symbols; + if (rd->local_symbols == NULL) + local_symbols = NULL; + else + local_symbols = rd->local_symbols->data(); + + for (Read_relocs_data::Relocs_list::iterator p = rd->relocs.begin(); + p != rd->relocs.end(); + ++p) + { + if (!parameters->options().relocatable()) + { + // As noted above, when not generating an object file, we + // only scan allocated sections. We may see a non-allocated + // section here if we are emitting relocs. + if (p->is_data_section_allocated) + target->gc_process_relocs(options, symtab, layout, this, + p->data_shndx, p->sh_type, + p->contents->data(), p->reloc_count, + p->output_section, + p->needs_special_offset_handling, + this->local_symbol_count_, + local_symbols); + } + } +} + + // Scan the relocs and adjust the symbol table. This looks for // relocations which require GOT/PLT/COPY relocations. @@ -318,6 +413,14 @@ Sized_relobj::do_scan_relocs(const General_options& options, p != rd->relocs.end(); ++p) { + // When garbage collection is on, unreferenced sections are not included + // in the link that would have been included normally. This is known only + // after Read_relocs hence this check has to be done again. + if (parameters->options().gc_sections()) + { + if (p->output_section == NULL) + continue; + } if (!parameters->options().relocatable()) { // As noted above, when not generating an object file, we @@ -1080,6 +1183,42 @@ Sized_relobj<64, true>::do_read_relocs(Read_relocs_data* rd); #ifdef HAVE_TARGET_32_LITTLE template void +Sized_relobj<32, false>::do_gc_process_relocs(const General_options& options, + Symbol_table* symtab, + Layout* layout, + Read_relocs_data* rd); +#endif + +#ifdef HAVE_TARGET_32_BIG +template +void +Sized_relobj<32, true>::do_gc_process_relocs(const General_options& options, + Symbol_table* symtab, + Layout* layout, + Read_relocs_data* rd); +#endif + +#ifdef HAVE_TARGET_64_LITTLE +template +void +Sized_relobj<64, false>::do_gc_process_relocs(const General_options& options, + Symbol_table* symtab, + Layout* layout, + Read_relocs_data* rd); +#endif + +#ifdef HAVE_TARGET_64_BIG +template +void +Sized_relobj<64, true>::do_gc_process_relocs(const General_options& options, + Symbol_table* symtab, + Layout* layout, + Read_relocs_data* rd); +#endif + +#ifdef HAVE_TARGET_32_LITTLE +template +void Sized_relobj<32, false>::do_scan_relocs(const General_options& options, Symbol_table* symtab, Layout* layout, -- cgit v1.1