From b3b74ddc6e208b58108b0900b4896034f84bb6be Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 28 Sep 2007 06:36:25 +0000 Subject: [PATCH] Use parameters to track whether we are doing a static link. Fix up final_value_is_known for weak undefined symbols. Pointed out by Cary Coutant. --- gold/gold.cc | 3 +++ gold/parameters.cc | 22 +++++++++++++++++++++- gold/parameters.h | 21 +++++++++++++++++++++ gold/symtab.cc | 33 +++++++++++++++++++++++++++++++++ gold/symtab.h | 7 +------ 5 files changed, 79 insertions(+), 7 deletions(-) diff --git a/gold/gold.cc b/gold/gold.cc index 7d01a81305f..5c8ce50d5c8 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -160,6 +160,9 @@ queue_middle_tasks(const General_options& options, Layout* layout, Workqueue* workqueue) { + // Now we have seen all the input files. + set_parameters_doing_static_link(!input_objects->any_dynamic()); + // Define some sections and symbols needed for a dynamic link. This // handles some cases we want to see before we read the relocs. layout->create_initial_dynamic_sections(input_objects, symtab); diff --git a/gold/parameters.cc b/gold/parameters.cc index db377f83a75..0c38ef7ed99 100644 --- a/gold/parameters.cc +++ b/gold/parameters.cc @@ -31,7 +31,8 @@ namespace gold // Initialize the parameters from the options. Parameters::Parameters(const General_options* options) - : is_size_and_endian_valid_(false), size_(0), is_big_endian_(false), + : is_doing_static_link_valid_(false), doing_static_link_(false), + is_size_and_endian_valid_(false), size_(0), is_big_endian_(false), optimization_level_(options->optimization_level()) { if (options->is_shared()) @@ -42,6 +43,15 @@ Parameters::Parameters(const General_options* options) this->output_file_type_ = OUTPUT_EXECUTABLE; } +// Set whether we are doing a static link. + +void +Parameters::set_doing_static_link(bool doing_static_link) +{ + this->doing_static_link_ = doing_static_link; + this->is_doing_static_link_valid_ = true; +} + // Set the size and endianness. void @@ -76,6 +86,16 @@ initialize_parameters(const General_options* options) parameters = static_parameters = new Parameters(options); } +// Set whether we are doing a static link. + +void +set_parameters_doing_static_link(bool doing_static_link) +{ + static_parameters->set_doing_static_link(doing_static_link); +} + +// Set the size and endianness. + void set_parameters_size_and_endianness(int size, bool is_big_endian) { diff --git a/gold/parameters.h b/gold/parameters.h index fafd3450e50..2a21607bb2b 100644 --- a/gold/parameters.h +++ b/gold/parameters.h @@ -56,6 +56,16 @@ class Parameters output_is_object() const { return this->output_file_type_ == OUTPUT_OBJECT; } + // Whether we are doing a static link--a link in which none of the + // input files are shared libraries. This is only known after we + // have seen all the input files. + bool + doing_static_link() const + { + gold_assert(this->is_doing_static_link_valid_); + return this->doing_static_link_; + } + // The size of the output file we are generating. This should // return 32 or 64. int @@ -78,6 +88,10 @@ class Parameters optimization_level() const { return this->optimization_level_; } + // Set whether we are doing a static link. + void + set_doing_static_link(bool doing_static_link); + // Set the size and endianness. void set_size_and_endianness(int size, bool is_big_endian); @@ -96,6 +110,10 @@ class Parameters // The type of the output file. Output_file_type output_file_type_; + // Whether the doing_static_link_ field is valid. + bool is_doing_static_link_valid_; + // Whether we are doing a static link. + bool doing_static_link_; // Whether the size_ and is_big_endian_ fields are valid. bool is_size_and_endian_valid_; // The size of the output file--32 or 64. @@ -115,6 +133,9 @@ extern void initialize_parameters(const General_options*); // Set the size and endianness of the global parameters variable. extern void set_parameters_size_and_endianness(int size, bool is_big_endian); +// Set whether we are doing a static link. +extern void set_parameters_doing_static_link(bool doing_static_link); + } // End namespace gold. #endif // !defined(GOLD_PARAMATERS_H) diff --git a/gold/symtab.cc b/gold/symtab.cc index 332c59f2f94..c9ac1c9a825 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -187,6 +187,39 @@ Sized_symbol::init(const char* name, Value_type value, Size_type symsize, this->symsize_ = symsize; } +// Return true if the final value of this symbol is known at link +// time. + +bool +Symbol::final_value_is_known() const +{ + // If we are not generating an executable, then no final values are + // known, since they will change at runtime. + if (!parameters->output_is_executable()) + return false; + + // If the symbol is not from an object file, then it is defined, and + // known. + if (this->source_ != FROM_OBJECT) + return true; + + // If the symbol is from a dynamic object, then the final value is + // not known. + if (this->object()->is_dynamic()) + return false; + + // If the symbol is not undefined (it is defined or common), then + // the final value is known. + if (!this->is_undefined()) + return true; + + // If the symbol is undefined, then whether the final value is known + // depends on whether we are doing a static link. If we are doing a + // dynamic link, then the final value could be filled in at runtime. + // This could reasonably be the case for a weak undefined symbol. + return parameters->doing_static_link(); +} + // Class Symbol_table. Symbol_table::Symbol_table() diff --git a/gold/symtab.h b/gold/symtab.h index 918c9741d85..258c99f9a72 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -341,12 +341,7 @@ class Symbol // Return true if the final value of this symbol is known at link // time. bool - final_value_is_known() const - { - if (parameters->output_is_shared()) - return false; - return this->source_ != FROM_OBJECT || !this->object()->is_dynamic(); - } + final_value_is_known() const; // Return whether this is a defined symbol (not undefined or // common). -- 2.30.2