diff options
-rw-r--r-- | gold/ChangeLog | 8 | ||||
-rw-r--r-- | gold/layout.cc | 32 | ||||
-rw-r--r-- | gold/layout.h | 6 |
3 files changed, 42 insertions, 4 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 5bf395e..a4d6e8e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,6 +1,14 @@ 2009-12-29 Ian Lance Taylor <iant@google.com> PR 10450 + * layout.cc (Layout::Layout): Initialize dynamic_symbol_ field. + (Layout::create_initial_dynamic_sections): Set dynamic_symbol_. + (Layout::finalize): Call set_dynamic_symbol_size. + (Layout::set_dynamic_symbol_size): New function. + * layout.h (class Layout): Add dynamic_symbol_ field. Declare + set_dynamic_symbol_size. + + PR 10450 * output.h (class Output_section): Add is_entsize_zero_ field. * output.cc (Output_section::Output_section): Initialize is_entsize_zero_. diff --git a/gold/layout.cc b/gold/layout.cc index 17477bb..d0726ae 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -180,6 +180,7 @@ Layout::Layout(int number_of_input_files, Script_options* script_options) dynsym_section_(NULL), dynsym_xindex_(NULL), dynamic_section_(NULL), + dynamic_symbol_(NULL), dynamic_data_(NULL), eh_frame_section_(NULL), eh_frame_data_(NULL), @@ -1161,10 +1162,11 @@ Layout::create_initial_dynamic_sections(Symbol_table* symtab) false, false, true); this->dynamic_section_->set_is_relro(); - symtab->define_in_output_data("_DYNAMIC", NULL, Symbol_table::PREDEFINED, - this->dynamic_section_, 0, 0, - elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, - elfcpp::STV_HIDDEN, 0, false, false); + this->dynamic_symbol_ = + symtab->define_in_output_data("_DYNAMIC", NULL, Symbol_table::PREDEFINED, + this->dynamic_section_, 0, 0, + elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, + elfcpp::STV_HIDDEN, 0, false, false); this->dynamic_data_ = new Output_data_dynamic(&this->dynpool_); @@ -1580,6 +1582,10 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, // dynamic string table is complete. this->create_version_sections(&versions, symtab, local_dynamic_count, dynamic_symbols, dynstr); + + // Set the size of the _DYNAMIC symbol. We can't do this until + // after we call create_version_sections. + this->set_dynamic_symbol_size(symtab); } if (this->incremental_inputs_) @@ -3303,6 +3309,24 @@ Layout::finish_dynamic_section(const Input_objects* input_objects, odyn->add_constant(elfcpp::DT_FLAGS_1, flags); } +// Set the size of the _DYNAMIC symbol table to be the size of the +// dynamic data. + +void +Layout::set_dynamic_symbol_size(const Symbol_table* symtab) +{ + Output_data_dynamic* const odyn = this->dynamic_data_; + odyn->finalize_data_size(); + off_t data_size = odyn->data_size(); + const int size = parameters->target().get_size(); + if (size == 32) + symtab->get_sized_symbol<32>(this->dynamic_symbol_)->set_symsize(data_size); + else if (size == 64) + symtab->get_sized_symbol<64>(this->dynamic_symbol_)->set_symsize(data_size); + else + gold_unreachable(); +} + // The mapping of input section name prefixes to output section names. // In some cases one prefix is itself a prefix of another prefix; in // such a case the longer prefix must come first. These prefixes are diff --git a/gold/layout.h b/gold/layout.h index 71afa96..0437cf1 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -708,6 +708,10 @@ class Layout void finish_dynamic_section(const Input_objects*, const Symbol_table*); + // Set the size of the _DYNAMIC symbol. + void + set_dynamic_symbol_size(const Symbol_table*); + // Create the .interp section and PT_INTERP segment. void create_interp(const Target* target); @@ -947,6 +951,8 @@ class Layout Output_symtab_xindex* dynsym_xindex_; // The SHT_DYNAMIC output section if there is one. Output_section* dynamic_section_; + // The _DYNAMIC symbol if there is one. + Symbol* dynamic_symbol_; // The dynamic data which goes into dynamic_section_. Output_data_dynamic* dynamic_data_; // The exception frame output section if there is one. |