diff options
author | Sriraman Tallam <tmsriram@google.com> | 2009-01-28 02:25:33 +0000 |
---|---|---|
committer | Sriraman Tallam <tmsriram@google.com> | 2009-01-28 02:25:33 +0000 |
commit | 6d03d481a0827abf92804f8ffaf9ab00593943be (patch) | |
tree | 617f1054036bd3cca35f897b225b37b4ce1a3b0c /gold/reloc.cc | |
parent | 7df3ce47694f5c804a9468d4c098825b5901216e (diff) | |
download | gdb-6d03d481a0827abf92804f8ffaf9ab00593943be.zip gdb-6d03d481a0827abf92804f8ffaf9ab00593943be.tar.gz gdb-6d03d481a0827abf92804f8ffaf9ab00593943be.tar.bz2 |
2009-01-20 Sriraman Tallam <tmsriram@google.com>
* 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.
Diffstat (limited to 'gold/reloc.cc')
-rw-r--r-- | gold/reloc.cc | 147 |
1 files changed, 143 insertions, 4 deletions
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 <iant@google.com>. // 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<size, big_endian>::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<int size, bool big_endian> +void +Sized_relobj<size, big_endian>::do_gc_process_relocs(const General_options& options, + Symbol_table* symtab, + Layout* layout, + Read_relocs_data* rd) +{ + Sized_target<size, big_endian>* 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<size, big_endian>::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, |