diff options
author | Ian Lance Taylor <iant@google.com> | 2008-02-28 00:18:24 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2008-02-28 00:18:24 +0000 |
commit | 8851eccaec28f25f56fab5ba5d8ae44f71729975 (patch) | |
tree | 8580999a45a15a7e86dbabb0675a05f647aedd1a | |
parent | f960754aeea602f787d1828efb0f9a8baeca646e (diff) | |
download | fsf-binutils-gdb-8851eccaec28f25f56fab5ba5d8ae44f71729975.zip fsf-binutils-gdb-8851eccaec28f25f56fab5ba5d8ae44f71729975.tar.gz fsf-binutils-gdb-8851eccaec28f25f56fab5ba5d8ae44f71729975.tar.bz2 |
From Craig Silverstein: Have Parameters point to General_options.
-rw-r--r-- | gold/common.cc | 4 | ||||
-rw-r--r-- | gold/compressed_output.cc | 2 | ||||
-rw-r--r-- | gold/dwarf_reader.cc | 41 | ||||
-rw-r--r-- | gold/dynobj.cc | 20 | ||||
-rw-r--r-- | gold/ehframe.cc | 90 | ||||
-rw-r--r-- | gold/expression.cc | 22 | ||||
-rw-r--r-- | gold/fileread.cc | 10 | ||||
-rw-r--r-- | gold/gold-threads.cc | 5 | ||||
-rw-r--r-- | gold/gold.cc | 15 | ||||
-rw-r--r-- | gold/i386.cc | 49 | ||||
-rw-r--r-- | gold/layout.cc | 143 | ||||
-rw-r--r-- | gold/layout.h | 6 | ||||
-rw-r--r-- | gold/main.cc | 6 | ||||
-rw-r--r-- | gold/object.cc | 24 | ||||
-rw-r--r-- | gold/options.cc | 29 | ||||
-rw-r--r-- | gold/options.h | 10 | ||||
-rw-r--r-- | gold/output.cc | 241 | ||||
-rw-r--r-- | gold/parameters.cc | 185 | ||||
-rw-r--r-- | gold/parameters.h | 352 | ||||
-rw-r--r-- | gold/reloc.cc | 17 | ||||
-rw-r--r-- | gold/resolve.cc | 2 | ||||
-rw-r--r-- | gold/script-sections.cc | 14 | ||||
-rw-r--r-- | gold/script.cc | 10 | ||||
-rw-r--r-- | gold/stringpool.cc | 2 | ||||
-rw-r--r-- | gold/symtab.cc | 164 | ||||
-rw-r--r-- | gold/symtab.h | 14 | ||||
-rw-r--r-- | gold/target-reloc.h | 2 | ||||
-rw-r--r-- | gold/target.h | 13 | ||||
-rw-r--r-- | gold/testsuite/binary_unittest.cc | 4 | ||||
-rw-r--r-- | gold/x86_64.cc | 26 |
30 files changed, 596 insertions, 926 deletions
diff --git a/gold/common.cc b/gold/common.cc index d94f2c3..e6f3910 100644 --- a/gold/common.cc +++ b/gold/common.cc @@ -121,7 +121,7 @@ Sort_commons<size>::operator()(const Symbol* pa, const Symbol* pb) const void Symbol_table::allocate_commons(const General_options& options, Layout* layout) { - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) this->do_allocate_commons<32>(options, layout); @@ -129,7 +129,7 @@ Symbol_table::allocate_commons(const General_options& options, Layout* layout) gold_unreachable(); #endif } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) this->do_allocate_commons<64>(options, layout); diff --git a/gold/compressed_output.cc b/gold/compressed_output.cc index 0bbcb55..1eca021 100644 --- a/gold/compressed_output.cc +++ b/gold/compressed_output.cc @@ -49,7 +49,7 @@ zlib_compress(const char* uncompressed_data, unsigned long uncompressed_size, *compressed_data = new char[*compressed_size]; int compress_level; - if (parameters->optimize() >= 1) + if (parameters->options().optimize() >= 1) compress_level = 9; else compress_level = 1; diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc index 19c1a03..136e4a6 100644 --- a/gold/dwarf_reader.cc +++ b/gold/dwarf_reader.cc @@ -790,36 +790,31 @@ std::string Dwarf_line_info::one_addr2line(Object* object, unsigned int shndx, off_t offset) { - if (parameters->get_size() == 32 && !parameters->is_big_endian()) + switch (parameters->size_and_endianness()) + { #ifdef HAVE_TARGET_32_LITTLE - return Sized_dwarf_line_info<32, false>(object, shndx).addr2line(shndx, - offset); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + return Sized_dwarf_line_info<32, false>(object, shndx).addr2line(shndx, + offset); #endif - else if (parameters->get_size() == 32 && parameters->is_big_endian()) #ifdef HAVE_TARGET_32_BIG - return Sized_dwarf_line_info<32, true>(object, shndx).addr2line(shndx, - offset); -#else - gold_unreachable(); + case Parameters::TARGET_32_BIG: + return Sized_dwarf_line_info<32, true>(object, shndx).addr2line(shndx, + offset); #endif - else if (parameters->get_size() == 64 && !parameters->is_big_endian()) #ifdef HAVE_TARGET_64_LITTLE - return Sized_dwarf_line_info<64, false>(object, shndx).addr2line(shndx, - offset); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + return Sized_dwarf_line_info<64, false>(object, shndx).addr2line(shndx, + offset); #endif - else if (parameters->get_size() == 64 && parameters->is_big_endian()) -#ifdef HAVE_TARGET_64_BIT - return Sized_dwarf_line_info<64, true>(object, shndx).addr2line(shndx, - offset); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + return Sized_dwarf_line_info<64, true>(object, shndx).addr2line(shndx, + offset); #endif - else - gold_unreachable(); + default: + gold_unreachable(); + } } #ifdef HAVE_TARGET_32_LITTLE diff --git a/gold/dynobj.cc b/gold/dynobj.cc index a33707b..bfcc78a 100644 --- a/gold/dynobj.cc +++ b/gold/dynobj.cc @@ -775,7 +775,7 @@ Dynobj::create_elf_hash_table(const std::vector<Symbol*>& dynsyms, * 4); unsigned char* phash = new unsigned char[hashlen]; - if (parameters->is_big_endian()) + if (parameters->target().is_big_endian()) { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) Dynobj::sized_create_elf_hash_table<true>(bucket, chain, phash, @@ -904,8 +904,8 @@ Dynobj::create_gnu_hash_table(const std::vector<Symbol*>& dynsyms, // For the actual data generation we call out to a templatized // function. - int size = parameters->get_size(); - bool big_endian = parameters->is_big_endian(); + int size = parameters->target().get_size(); + bool big_endian = parameters->target().is_big_endian(); if (size == 32) { if (big_endian) @@ -1235,13 +1235,13 @@ Versions::Versions(const Version_script_info& version_script, { // We always need a base version, so define that first. Nothing // explicitly declares itself as part of base, so it doesn't need to - // be in version_table_. + // be in version_table_. // FIXME: Should use soname here when creating a shared object. Is // this fixme still valid? It looks like it's doing the right thing // to me. - if (parameters->output_is_shared()) + if (parameters->options().shared()) { - const char* name = dynpool->add(parameters->output_file_name(), + const char* name = dynpool->add(parameters->options().output_file_name(), false, NULL); Verdef* vdbase = new Verdef(name, std::vector<std::string>(), true, false, true); @@ -1307,13 +1307,13 @@ Versions::record_version(const Symbol_table* symtab, { gold_assert(!this->is_finalized_); gold_assert(sym->version() != NULL); - + Stringpool::Key version_key; const char* version = dynpool->add(sym->version(), false, &version_key); if (!sym->is_from_dynobj() && !sym->is_copied_from_dynobj()) { - if (parameters->output_is_shared()) + if (parameters->options().shared()) this->add_def(sym, version, version_key); } else @@ -1350,7 +1350,7 @@ Versions::add_def(const Symbol* sym, const char* version, // If we are creating a shared object, it is an error to // find a definition of a symbol with a version which is not // in the version script. - if (parameters->output_is_shared()) + if (parameters->options().shared()) { gold_error(_("symbol %s has undefined version %s"), sym->demangled_name().c_str(), version); @@ -1481,7 +1481,7 @@ Versions::version_index(const Symbol_table* symtab, const Stringpool* dynpool, Key k; if (!sym->is_from_dynobj() && !sym->is_copied_from_dynobj()) { - if (!parameters->output_is_shared()) + if (!parameters->options().shared()) return elfcpp::VER_NDX_GLOBAL; k = Key(version_key, 0); } diff --git a/gold/ehframe.cc b/gold/ehframe.cc index 8306f51..df94488 100644 --- a/gold/ehframe.cc +++ b/gold/ehframe.cc @@ -109,46 +109,31 @@ Eh_frame_hdr::set_final_data_size() void Eh_frame_hdr::do_write(Output_file* of) { - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (!parameters->is_big_endian()) - { #ifdef HAVE_TARGET_32_LITTLE - this->do_sized_write<32, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->do_sized_write<32, false>(of); + break; #endif - } - else - { #ifdef HAVE_TARGET_32_BIG - this->do_sized_write<32, true>(of); -#else - gold_unreachable(); + case Parameters::TARGET_32_BIG: + this->do_sized_write<32, true>(of); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (!parameters->is_big_endian()) - { #ifdef HAVE_TARGET_64_LITTLE - this->do_sized_write<64, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->do_sized_write<64, false>(of); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_BIG - this->do_sized_write<64, true>(of); -#else - gold_unreachable(); + case Parameters::TARGET_64_BIG: + this->do_sized_write<64, true>(of); + break; #endif - } + default: + gold_unreachable(); } - else - gold_unreachable(); } // Write the data to the file with the right endianness. @@ -1075,46 +1060,31 @@ Eh_frame::do_write(Output_file* of) const off_t oview_size = this->data_size(); unsigned char* const oview = of->get_output_view(offset, oview_size); - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (!parameters->is_big_endian()) - { #ifdef HAVE_TARGET_32_LITTLE - this->do_sized_write<32, false>(oview); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->do_sized_write<32, false>(oview); + break; #endif - } - else - { #ifdef HAVE_TARGET_32_BIG - this->do_sized_write<32, true>(oview); -#else - gold_unreachable(); + case Parameters::TARGET_32_BIG: + this->do_sized_write<32, true>(oview); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (!parameters->is_big_endian()) - { #ifdef HAVE_TARGET_64_LITTLE - this->do_sized_write<64, false>(oview); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->do_sized_write<64, false>(oview); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_BIG - this->do_sized_write<64, true>(oview); -#else - gold_unreachable(); + case Parameters::TARGET_64_BIG: + this->do_sized_write<64, true>(oview); + break; #endif - } + default: + gold_unreachable(); } - else - gold_unreachable(); of->write_output_view(offset, oview_size, oview); } diff --git a/gold/expression.cc b/gold/expression.cc index 1cc646f..25a19f9 100644 --- a/gold/expression.cc +++ b/gold/expression.cc @@ -170,9 +170,9 @@ Symbol_expression::value(const Expression_eval_info* eei) *eei->result_section_pointer = sym->output_section(); - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) return eei->symtab->get_sized_symbol<32>(sym)->value(); - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) return eei->symtab->get_sized_symbol<64>(sym)->value(); else gold_unreachable(); @@ -267,7 +267,7 @@ class Unary_expression : public Expression { \ Output_section* arg_section; \ uint64_t ret = OPERATOR this->arg_value(eei, &arg_section); \ - if (arg_section != NULL && parameters->output_is_object()) \ + if (arg_section != NULL && parameters->options().relocatable()) \ gold_warning(_("unary " #NAME " applied to section " \ "relative value")); \ return ret; \ @@ -387,7 +387,7 @@ class Binary_expression : public Expression *eei->result_section_pointer = left_section; \ else if ((WARN || left_section != right_section) \ && (left_section != NULL || right_section != NULL) \ - && parameters->output_is_object()) \ + && parameters->options().relocatable()) \ gold_warning(_("binary " #NAME " applied to section " \ "relative value")); \ if (IS_DIV && right == 0) \ @@ -559,7 +559,7 @@ class Max_expression : public Binary_expression if (left_section == right_section) *eei->result_section_pointer = left_section; else if ((left_section != NULL || right_section != NULL) - && parameters->output_is_object()) + && parameters->options().relocatable()) gold_warning(_("max applied to section relative value")); return std::max(left, right); } @@ -594,7 +594,7 @@ class Min_expression : public Binary_expression if (left_section == right_section) *eei->result_section_pointer = left_section; else if ((left_section != NULL || right_section != NULL) - && parameters->output_is_object()) + && parameters->options().relocatable()) gold_warning(_("min applied to section relative value")); return std::min(left, right); } @@ -705,7 +705,7 @@ class Align_expression : public Binary_expression Output_section* align_section; uint64_t align = this->right_value(eei, &align_section); if (align_section != NULL - && parameters->output_is_object()) + && parameters->options().relocatable()) gold_warning(_("aligning to section relative value")); uint64_t value = this->left_value(eei, eei->result_section_pointer); @@ -862,9 +862,9 @@ Constant_expression::value(const Expression_eval_info*) switch (this->function_) { case CONSTANT_MAXPAGESIZE: - return parameters->target()->abi_pagesize(); + return parameters->target().abi_pagesize(); case CONSTANT_COMMONPAGESIZE: - return parameters->target()->common_pagesize(); + return parameters->target().common_pagesize(); default: gold_unreachable(); } @@ -1040,12 +1040,12 @@ Sizeof_headers_expression::value(const Expression_eval_info* eei) { unsigned int ehdr_size; unsigned int phdr_size; - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size; phdr_size = elfcpp::Elf_sizes<32>::phdr_size; } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { ehdr_size = elfcpp::Elf_sizes<64>::ehdr_size; phdr_size = elfcpp::Elf_sizes<64>::phdr_size; diff --git a/gold/fileread.cc b/gold/fileread.cc index 2defbf8..901c528 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -714,17 +714,17 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath, // Open a file for --format binary. bool -Input_file::open_binary(const General_options& options, +Input_file::open_binary(const General_options&, const Task* task, const std::string& name) { // In order to open a binary file, we need machine code, size, and // endianness. We may not have a valid target at this point, in // which case we use the default target. - Target* target; - if (parameters->is_target_valid()) - target = parameters->target(); + const Target* target; + if (parameters->target_valid()) + target = ¶meters->target(); else - target = options.default_target(); + target = ¶meters->default_target(); Binary_to_elf binary_to_elf(target->machine_code(), target->get_size(), diff --git a/gold/gold-threads.cc b/gold/gold-threads.cc index 4ebbdd8..e54d96c 100644 --- a/gold/gold-threads.cc +++ b/gold/gold-threads.cc @@ -28,6 +28,7 @@ #include <pthread.h> #endif +#include "options.h" #include "parameters.h" #include "gold-threads.h" @@ -144,7 +145,7 @@ Lock_impl_threads::release() Lock::Lock() { - if (!parameters->threads()) + if (!parameters->options().threads()) this->lock_ = new Lock_impl_nothreads; else { @@ -258,7 +259,7 @@ Condvar_impl_threads::broadcast() Condvar::Condvar(Lock& lock) : lock_(lock) { - if (!parameters->threads()) + if (!parameters->options().threads()) this->condvar_ = new Condvar_impl_nothreads; else { diff --git a/gold/gold.cc b/gold/gold.cc index e34baeb..c79e87a 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -50,7 +50,7 @@ void gold_exit(bool status) { if (!status && parameters != NULL && parameters->options_valid()) - unlink_if_ordinary(parameters->output_file_name()); + unlink_if_ordinary(parameters->options().output_file_name()); exit(status ? EXIT_SUCCESS : EXIT_FAILURE); } @@ -166,7 +166,7 @@ queue_middle_tasks(const General_options& options, // pass an empty archive to the linker and get an empty object file // out. In order to do this we need to use a default target. if (input_objects->number_of_input_objects() == 0) - set_parameters_target(options.default_target()); + set_parameters_target(¶meters->default_target()); int thread_count = options.thread_count_middle(); if (thread_count == 0) @@ -175,7 +175,7 @@ queue_middle_tasks(const General_options& options, // Now we have seen all the input files. const bool doing_static_link = (!input_objects->any_dynamic() - && !parameters->output_is_shared()); + && !parameters->options().shared()); set_parameters_doing_static_link(doing_static_link); if (!doing_static_link && options.is_static()) { @@ -183,7 +183,7 @@ queue_middle_tasks(const General_options& options, gold_error(_("cannot mix -static with dynamic object %s"), (*input_objects->dynobj_begin())->name().c_str()); } - if (!doing_static_link && parameters->output_is_object()) + if (!doing_static_link && parameters->options().relocatable()) gold_error(_("cannot mix -r with dynamic object %s"), (*input_objects->dynobj_begin())->name().c_str()); if (!doing_static_link @@ -209,7 +209,7 @@ queue_middle_tasks(const General_options& options, // Define symbols from any linker scripts. layout->define_script_symbols(symtab); - if (!parameters->output_is_object()) + if (!parameters->options().relocatable()) { // Predefine standard symbols. define_standard_symbols(symtab, layout); @@ -253,7 +253,7 @@ queue_middle_tasks(const General_options& options, // symbol table, but is independent of the relocation processing. // FIXME: We should have an option to do this even for a relocatable // link. - if (!parameters->output_is_object()) + if (!parameters->options().relocatable()) { blocker->add_blocker(); workqueue->queue(new Allocate_commons_task(options, symtab, layout, @@ -262,9 +262,12 @@ queue_middle_tasks(const General_options& options, // When all those tasks are complete, we can start laying out the // output file. + // TODO(csilvers): figure out a more principled way to get the target + Target* target = const_cast<Target*>(¶meters->target()); workqueue->queue(new Task_function(new Layout_task_runner(options, input_objects, symtab, + target, layout), blocker, "Task_function Layout_task_runner")); diff --git a/gold/i386.cc b/gold/i386.cc index 6b805bd..4303a2a 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -129,7 +129,7 @@ class Target_i386 : public Sized_target<32, false> // Return a string used to fill a code section with nops. std::string - do_code_fill(section_size_type length); + do_code_fill(section_size_type length) const; // Return whether SYM is defined by the ABI. bool @@ -324,7 +324,7 @@ class Target_i386 : public Sized_target<32, false> bool may_need_copy_reloc(Symbol* gsym) { - return (!parameters->output_is_shared() + return (!parameters->options().shared() && gsym->is_from_dynobj() && gsym->type() != elfcpp::STT_FUNC); } @@ -597,7 +597,7 @@ Output_data_plt_i386::do_write(Output_file* of) elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address(); elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address(); - if (parameters->output_is_shared()) + if (parameters->options().shared()) memcpy(pov, dyn_first_plt_entry, plt_entry_size); else { @@ -629,7 +629,7 @@ Output_data_plt_i386::do_write(Output_file* of) { // Set and adjust the PLT entry itself. - if (parameters->output_is_shared()) + if (parameters->options().shared()) { memcpy(pov, dyn_plt_entry, plt_entry_size); elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset); @@ -792,7 +792,7 @@ Target_i386::optimize_tls_reloc(bool is_final, int r_type) { // If we are generating a shared library, then we can't do anything // in the linker. - if (parameters->output_is_shared()) + if (parameters->options().shared()) return tls::TLSOPT_NONE; switch (r_type) @@ -878,7 +878,7 @@ Target_i386::Scan::local(const General_options&, // apply the link-time value, so we flag the location with // an R_386_RELATIVE relocation so the dynamic loader can // relocate it easily. - if (parameters->output_is_position_independent()) + if (parameters->options().output_is_position_independent()) { Reloc_section* rel_dyn = target->rel_dyn_section(layout); unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); @@ -895,7 +895,7 @@ Target_i386::Scan::local(const General_options&, // this location. Because the addend needs to remain in the // data section, we need to be careful not to apply this // relocation statically. - if (parameters->output_is_position_independent()) + if (parameters->options().output_is_position_independent()) { Reloc_section* rel_dyn = target->rel_dyn_section(layout); if (lsym.get_st_type() != elfcpp::STT_SECTION) @@ -939,7 +939,7 @@ Target_i386::Scan::local(const General_options&, { // If we are generating a shared object, we need to add a // dynamic RELATIVE relocation for this symbol's GOT entry. - if (parameters->output_is_position_independent()) + if (parameters->options().output_is_position_independent()) { Reloc_section* rel_dyn = target->rel_dyn_section(layout); unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); @@ -980,7 +980,7 @@ Target_i386::Scan::local(const General_options&, case elfcpp::R_386_TLS_LE: // Local-exec case elfcpp::R_386_TLS_LE_32: { - bool output_is_shared = parameters->output_is_shared(); + bool output_is_shared = parameters->options().shared(); const tls::Tls_optimization optimized_type = Target_i386::optimize_tls_reloc(!output_is_shared, r_type); switch (r_type) @@ -1032,7 +1032,7 @@ Target_i386::Scan::local(const General_options&, // For the R_386_TLS_IE relocation, we need to create a // dynamic relocation when building a shared library. if (r_type == elfcpp::R_386_TLS_IE - && parameters->output_is_shared()) + && parameters->options().shared()) { Reloc_section* rel_dyn = target->rel_dyn_section(layout); unsigned int r_sym @@ -1140,7 +1140,7 @@ Target_i386::Scan::global(const General_options& options, // taking the address of a function. In that case we need to // set the entry in the dynamic symbol table to the address of // the PLT entry. - if (gsym->is_from_dynobj() && !parameters->output_is_shared()) + if (gsym->is_from_dynobj() && !parameters->options().shared()) gsym->set_needs_dynsym_value(); } // Make a dynamic relocation if necessary. @@ -1182,7 +1182,7 @@ Target_i386::Scan::global(const General_options& options, // PLT entry and let the dynamic linker bind the call directly // to the target. For smaller relocations, we should use a // PLT entry to ensure that the call can reach. - if (!parameters->output_is_shared() + if (!parameters->options().shared() || r_type != elfcpp::R_386_PC32) target->make_plt_entry(symtab, layout, gsym); } @@ -1341,7 +1341,7 @@ Target_i386::Scan::global(const General_options& options, // For the R_386_TLS_IE relocation, we need to create a // dynamic relocation when building a shared library. if (r_type == elfcpp::R_386_TLS_IE - && parameters->output_is_shared()) + && parameters->options().shared()) { Reloc_section* rel_dyn = target->rel_dyn_section(layout); rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE, @@ -1366,7 +1366,7 @@ Target_i386::Scan::global(const General_options& options, case elfcpp::R_386_TLS_LE: // Local-exec case elfcpp::R_386_TLS_LE_32: layout->set_has_static_tls(); - if (parameters->output_is_shared()) + if (parameters->options().shared()) { // We need to create a dynamic relocation. unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_LE_32 @@ -1468,7 +1468,7 @@ Target_i386::do_finalize_sections(Layout* layout) elfcpp::Elf_sizes<32>::rel_size); } - if (!parameters->output_is_shared()) + if (!parameters->options().shared()) { // The value of the DT_DEBUG tag is filled in by the dynamic // linker at run time, and used by the debugger. @@ -1505,7 +1505,7 @@ Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym, // (b) the relocation is absolute (not pc- or segment-relative), and // (c) the relocation is not 32 bits wide. if (gsym == NULL) - return !(parameters->output_is_position_independent() + return !(parameters->options().output_is_position_independent() && (ref_flags & Symbol::ABSOLUTE_REF) && !is_32bit); @@ -1555,10 +1555,10 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, || r_type == elfcpp::R_386_PC32); if (gsym != NULL && (gsym->is_from_dynobj() - || (parameters->output_is_shared() + || (parameters->options().shared() && (gsym->is_undefined() || gsym->is_preemptible()))) && gsym->has_plt_offset() - && (!is_nonpic || !parameters->output_is_shared())) + && (!is_nonpic || !parameters->options().shared())) { symval.set_output_value(target->plt_section()->address() + gsym->plt_offset()); @@ -1750,9 +1750,10 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, elfcpp::Elf_types<32>::Elf_Addr value = psymval->value(object, 0); - const bool is_final = (gsym == NULL - ? !parameters->output_is_position_independent() - : gsym->final_value_is_known()); + const bool is_final = + (gsym == NULL + ? !parameters->options().output_is_position_independent() + : gsym->final_value_is_known()); const tls::Tls_optimization optimized_type = Target_i386::optimize_tls_reloc(is_final, r_type); switch (r_type) @@ -1895,7 +1896,7 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_LE: // Local-exec // If we're creating a shared library, a dynamic relocation will // have been created for this location, so do not apply it now. - if (!parameters->output_is_shared()) + if (!parameters->options().shared()) { gold_assert(tls_segment != NULL); value -= tls_segment->memsz(); @@ -1906,7 +1907,7 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_LE_32: // If we're creating a shared library, a dynamic relocation will // have been created for this location, so do not apply it now. - if (!parameters->output_is_shared()) + if (!parameters->options().shared()) { gold_assert(tls_segment != NULL); value = tls_segment->memsz() - value; @@ -2362,7 +2363,7 @@ Target_i386::do_dynsym_value(const Symbol* gsym) const // the specified length. std::string -Target_i386::do_code_fill(section_size_type length) +Target_i386::do_code_fill(section_size_type length) const { if (length >= 16) { diff --git a/gold/layout.cc b/gold/layout.cc index e8c6c66..df10498 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -52,11 +52,12 @@ Layout_task_runner::run(Workqueue* workqueue, const Task* task) { off_t file_size = this->layout_->finalize(this->input_objects_, this->symtab_, + this->target_, task); // Now we know the final size of the output file and we know where // each piece of information goes. - Output_file* of = new Output_file(parameters->output_file_name()); + Output_file* of = new Output_file(parameters->options().output_file_name()); if (this->options_.oformat() != General_options::OBJECT_FORMAT_ELF) of->set_is_temporary(); of->open(file_size); @@ -157,12 +158,12 @@ Layout::include_section(Sized_relobj<size, big_endian>*, const char* name, case elfcpp::SHT_GROUP: // If we are emitting relocations these should be handled // elsewhere. - gold_assert(!parameters->output_is_object() - && !parameters->emit_relocs()); + gold_assert(!parameters->options().relocatable() + && !parameters->options().emit_relocs()); return false; case elfcpp::SHT_PROGBITS: - if (parameters->strip_debug() + if (parameters->options().strip_debug() && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0) { // Debugging sections can only be recognized by name. @@ -172,7 +173,7 @@ Layout::include_section(Sized_relobj<size, big_endian>*, const char* name, || is_prefix_of(".stab", name)) return false; } - if (parameters->strip_debug_gdb() + if (parameters->options().strip_debug_gdb() && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0) { // Debugging sections can only be recognized by name. @@ -305,7 +306,7 @@ Layout::choose_output_section(const Relobj* relobj, const char* name, // output section. size_t len = strlen(name); - if (adjust_name && !parameters->output_is_object()) + if (adjust_name && !parameters->options().relocatable()) name = Layout::output_section_name(name, &len); Stringpool::Key name_key; @@ -339,7 +340,7 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx, // In a relocatable link a grouped section must not be combined with // any other sections. - if (parameters->output_is_object() + if (parameters->options().relocatable() && (shdr.get_sh_flags() & elfcpp::SHF_GROUP) != 0) { name = this->namepool_.add(name, true, NULL); @@ -372,7 +373,8 @@ Layout::layout_reloc(Sized_relobj<size, big_endian>* object, Output_section* data_section, Relocatable_relocs* rr) { - gold_assert(parameters->output_is_object() || parameters->emit_relocs()); + gold_assert(parameters->options().relocatable() + || parameters->options().emit_relocs()); int sh_type = shdr.get_sh_type(); @@ -429,7 +431,7 @@ Layout::layout_group(Symbol_table* symtab, const elfcpp::Shdr<size, big_endian>& shdr, const elfcpp::Elf_Word* contents) { - gold_assert(parameters->output_is_object()); + gold_assert(parameters->options().relocatable()); gold_assert(shdr.get_sh_type() == elfcpp::SHT_GROUP); group_section_name = this->namepool_.add(group_section_name, true, NULL); Output_section* os = this->make_output_section(group_section_name, @@ -609,7 +611,7 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type, this->unattached_section_list_.push_back(os); else { - if (parameters->output_is_object()) + if (parameters->options().relocatable()) return os; // If we have a SECTIONS clause, we can't handle the attachment @@ -901,10 +903,8 @@ Layout::find_first_load_seg() off_t Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, - const Task* task) + Target* target, const Task* task) { - Target* const target = parameters->target(); - target->finalize_sections(this); this->count_local_symbols(task, input_objects); @@ -913,7 +913,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, this->create_executable_stack_info(target); Output_segment* phdr_seg = NULL; - if (!parameters->output_is_object() && !parameters->doing_static_link()) + if (!parameters->options().relocatable() && !parameters->doing_static_link()) { // There was a dynamic object in the link. We need to create // some information for the dynamic linker. @@ -935,7 +935,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, // Create the .interp section to hold the name of the // interpreter, and put it in a PT_INTERP segment. - if (!parameters->output_is_shared()) + if (!parameters->options().shared()) this->create_interp(target); // Finish the .dynamic section to hold the dynamic data, and put @@ -957,7 +957,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, Output_segment* load_seg; if (this->script_options_->saw_sections_clause()) load_seg = this->set_section_addresses_from_script(symtab); - else if (parameters->output_is_object()) + else if (parameters->options().relocatable()) load_seg = NULL; else load_seg = this->find_first_load_seg(); @@ -969,7 +969,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, // Lay out the segment headers. Output_segment_headers* segment_headers; - if (parameters->output_is_object()) + if (parameters->options().relocatable()) segment_headers = NULL; else { @@ -992,7 +992,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, this->special_output_list_.push_back(segment_headers); if (this->script_options_->saw_phdrs_clause() - && !parameters->output_is_object()) + && !parameters->options().relocatable()) { // Support use of FILEHDRS and PHDRS attachments in a PHDRS // clause in a linker script. @@ -1007,7 +1007,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, // Set the file offsets of all the segments, and all the sections // they contain. off_t off; - if (!parameters->output_is_object()) + if (!parameters->options().relocatable()) off = this->set_segment_offsets(target, load_seg, &shndx); else off = this->set_relocatable_section_offsets(file_header, &shndx); @@ -1063,7 +1063,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, void Layout::create_gold_note() { - if (parameters->output_is_object()) + if (parameters->options().relocatable()) return; // Authorities all agree that the values in a .note field should @@ -1078,7 +1078,7 @@ Layout::create_gold_note() // .note.ABI-tag (as of version 1.6), so that's the one we go with // here. #ifdef GABI_FORMAT_FOR_DOTNOTE_SECTION // This is not defined by default. - const int size = parameters->get_size(); + const int size = parameters->target().get_size(); #else const int size = 32; #endif @@ -1098,7 +1098,7 @@ Layout::create_gold_note() gold_assert(sizeof buffer >= notesz); memset(buffer, 0, notesz); - bool is_big_endian = parameters->is_big_endian(); + bool is_big_endian = parameters->target().is_big_endian(); if (size == 32) { @@ -1175,7 +1175,7 @@ Layout::create_executable_stack_info(const Target* target) is_stack_executable = false; } - if (parameters->output_is_object()) + if (parameters->options().relocatable()) { const char* name = this->namepool_.add(".note.GNU-stack", false, NULL); elfcpp::Elf_Xword flags = 0; @@ -1314,7 +1314,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg, uint64_t addr; if (this->options_.user_set_Ttext()) addr = this->options_.Ttext(); - else if (parameters->output_is_shared()) + else if (parameters->options().shared()) addr = 0; else addr = target->default_text_segment_address(); @@ -1560,7 +1560,7 @@ Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass) unsigned int Layout::set_section_indexes(unsigned int shndx) { - const bool output_is_object = parameters->output_is_object(); + const bool output_is_object = parameters->options().relocatable(); for (Section_list::iterator p = this->unattached_section_list_.begin(); p != this->unattached_section_list_.end(); ++p) @@ -1646,12 +1646,12 @@ Layout::create_symtab_sections(const Input_objects* input_objects, { int symsize; unsigned int align; - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { symsize = elfcpp::Elf_sizes<32>::sym_size; align = 4; } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { symsize = elfcpp::Elf_sizes<64>::sym_size; align = 8; @@ -1718,7 +1718,7 @@ Layout::create_symtab_sections(const Input_objects* input_objects, off = symtab->finalize(off, dynoff, dyn_global_index, dyncount, &this->sympool_, &local_symcount); - if (!parameters->strip_all()) + if (!parameters->options().strip_all()) { this->sympool_.set_string_offsets(); @@ -1844,7 +1844,7 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, int symsize; unsigned int align; - const int size = parameters->get_size(); + const int size = parameters->target().get_size(); if (size == 32) { symsize = elfcpp::Elf_sizes<32>::sym_size; @@ -1956,58 +1956,43 @@ Layout::create_version_sections(const Versions* versions, if (!versions->any_defs() && !versions->any_needs()) return; - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_32_BIG - this->sized_create_version_sections - SELECT_SIZE_ENDIAN_NAME(32, true)( - versions, symtab, local_symcount, dynamic_symbols, dynstr - SELECT_SIZE_ENDIAN(32, true)); -#else - gold_unreachable(); -#endif - } - else - { #ifdef HAVE_TARGET_32_LITTLE - this->sized_create_version_sections - SELECT_SIZE_ENDIAN_NAME(32, false)( - versions, symtab, local_symcount, dynamic_symbols, dynstr - SELECT_SIZE_ENDIAN(32, false)); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->sized_create_version_sections + SELECT_SIZE_ENDIAN_NAME(32, false)( + versions, symtab, local_symcount, dynamic_symbols, dynstr + SELECT_SIZE_ENDIAN(32, false)); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_64_BIG - this->sized_create_version_sections - SELECT_SIZE_ENDIAN_NAME(64, true)( - versions, symtab, local_symcount, dynamic_symbols, dynstr - SELECT_SIZE_ENDIAN(64, true)); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_32_BIG + case Parameters::TARGET_32_BIG: + this->sized_create_version_sections + SELECT_SIZE_ENDIAN_NAME(32, true)( + versions, symtab, local_symcount, dynamic_symbols, dynstr + SELECT_SIZE_ENDIAN(32, true)); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_LITTLE - this->sized_create_version_sections - SELECT_SIZE_ENDIAN_NAME(64, false)( - versions, symtab, local_symcount, dynamic_symbols, dynstr - SELECT_SIZE_ENDIAN(64, false)); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->sized_create_version_sections + SELECT_SIZE_ENDIAN_NAME(64, false)( + versions, symtab, local_symcount, dynamic_symbols, dynstr + SELECT_SIZE_ENDIAN(64, false)); + break; #endif - } +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + this->sized_create_version_sections + SELECT_SIZE_ENDIAN_NAME(64, true)( + versions, symtab, local_symcount, dynamic_symbols, dynstr + SELECT_SIZE_ENDIAN(64, true)); + break; +#endif + default: + gold_unreachable(); } - else - gold_unreachable(); } // Create the version sections, sized version. @@ -2152,7 +2137,7 @@ Layout::finish_dynamic_section(const Input_objects* input_objects, odyn->add_string(elfcpp::DT_NEEDED, (*p)->soname()); } - if (parameters->output_is_shared()) + if (parameters->options().shared()) { const char* soname = this->options_.soname(); if (soname != NULL) @@ -2244,7 +2229,7 @@ Layout::finish_dynamic_section(const Input_objects* input_objects, odyn->add_constant(elfcpp::DT_TEXTREL, 0); flags |= elfcpp::DF_TEXTREL; } - if (parameters->output_is_shared() && this->has_static_tls()) + if (parameters->options().shared() && this->has_static_tls()) flags |= elfcpp::DF_STATIC_TLS; odyn->add_constant(elfcpp::DT_FLAGS, flags); } @@ -2439,7 +2424,7 @@ Layout::get_allocated_sections(Section_list* section_list) const Output_segment* Layout::make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags) { - gold_assert(!parameters->output_is_object()); + gold_assert(!parameters->options().relocatable()); Output_segment* oseg = new Output_segment(type, flags); this->segment_list_.push_back(oseg); return oseg; @@ -2466,7 +2451,7 @@ Layout::write_output_sections(Output_file* of) const void Layout::write_data(const Symbol_table* symtab, Output_file* of) const { - if (!parameters->strip_all()) + if (!parameters->options().strip_all()) { const Output_section* symtab_section = this->symtab_section_; for (Section_list::const_iterator p = this->section_list_.begin(); @@ -2573,7 +2558,7 @@ Layout::write_binary(Output_file* in) const } } - Output_file out(parameters->output_file_name()); + Output_file out(parameters->options().output_file_name()); out.open(max_load_address); for (Segment_list::const_iterator p = this->segment_list_.begin(); diff --git a/gold/layout.h b/gold/layout.h index e4e97e4..658eb1e 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -61,9 +61,10 @@ class Layout_task_runner : public Task_function_runner Layout_task_runner(const General_options& options, const Input_objects* input_objects, Symbol_table* symtab, + Target* target, Layout* layout) : options_(options), input_objects_(input_objects), symtab_(symtab), - layout_(layout) + target_(target), layout_(layout) { } // Run the operation. @@ -77,6 +78,7 @@ class Layout_task_runner : public Task_function_runner const General_options& options_; const Input_objects* input_objects_; Symbol_table* symtab_; + Target* target_; Layout* layout_; }; @@ -201,7 +203,7 @@ class Layout // Finalize the layout after all the input sections have been added. off_t - finalize(const Input_objects*, Symbol_table*, const Task*); + finalize(const Input_objects*, Symbol_table*, Target*, const Task*); // Return whether any sections require postprocessing. bool diff --git a/gold/main.cc b/gold/main.cc index 678bd03..2fc9439 100644 --- a/gold/main.cc +++ b/gold/main.cc @@ -145,7 +145,7 @@ main(int argc, char** argv) // Initialize the global parameters, to let random code get to the // errors object. - initialize_parameters(&errors); + set_parameters_errors(&errors); // Handle the command line options. Command_line command_line; @@ -156,7 +156,7 @@ main(int argc, char** argv) start_time = get_run_time(); // Store some options in the globally accessible parameters. - set_parameters_from_options(&command_line.options()); + set_parameters_options(&command_line.options()); // Do this as early as possible (since it prints a welcome message). write_debug_script(command_line.options().output_file_name(), @@ -169,7 +169,7 @@ main(int argc, char** argv) // permit symbols to be forced local with -r, though, as it would // permit some linker optimizations. Perhaps we need yet another // option to control this. FIXME. - if (parameters->output_is_object()) + if (parameters->options().relocatable()) command_line.script_options().version_script_info()->clear(); // The work queue. diff --git a/gold/object.cc b/gold/object.cc index c886717..e444ec1 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -451,7 +451,7 @@ Sized_relobj<size, big_endian>::include_section_group( if ((flags & elfcpp::GRP_COMDAT) == 0 || layout->add_comdat(signature, true)) { - if (parameters->output_is_object()) + if (parameters->options().relocatable()) layout->layout_group(symtab, this, index, name, signature, shdr, pword); return true; @@ -594,8 +594,9 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, std::vector<bool> omit(shnum, false); // Keep track of reloc sections when emitting relocations. - const bool output_is_object = parameters->output_is_object(); - const bool emit_relocs = output_is_object || parameters->emit_relocs(); + const bool relocatable = parameters->options().relocatable(); + const bool emit_relocs = (relocatable + || parameters->options().emit_relocs()); std::vector<unsigned int> reloc_sections; // Keep track of .eh_frame sections. @@ -618,7 +619,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, if (this->handle_gnu_warning_section(name, i, symtab)) { - if (!output_is_object) + if (!relocatable) omit[i] = true; } @@ -669,7 +670,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, continue; } - if (output_is_object && shdr.get_sh_type() == elfcpp::SHT_GROUP) + if (relocatable && shdr.get_sh_type() == elfcpp::SHT_GROUP) continue; // The .eh_frame section is special. It holds exception frame @@ -678,7 +679,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, // sections so that the exception frame reader can reliably // determine which sections are being discarded, and discard the // corresponding information. - if (!output_is_object + if (!relocatable && strcmp(name, ".eh_frame") == 0 && this->check_eh_frame_flags(&shdr)) { @@ -1068,7 +1069,8 @@ Sized_relobj<size, big_endian>::write_local_symbols( const Stringpool* sympool, const Stringpool* dynpool) { - if (parameters->strip_all() && this->output_local_dynsym_count_ == 0) + if (parameters->options().strip_all() + && this->output_local_dynsym_count_ == 0) return; gold_assert(this->symtab_shndx_ != -1U); @@ -1134,7 +1136,7 @@ Sized_relobj<size, big_endian>::write_local_symbols( } // Write the symbol to the output symbol table. - if (!parameters->strip_all() + if (!parameters->options().strip_all() && this->local_values_[i].needs_output_symtab_entry()) { elfcpp::Sym_write<size, big_endian> osym(ov); @@ -1235,7 +1237,7 @@ Sized_relobj<size, big_endian>::get_symbol_location_info( else { info->enclosing_symbol_name = symbol_names + sym.get_st_name(); - if (parameters->demangle()) + if (parameters->options().demangle()) { char* demangled_name = cplus_demangle( info->enclosing_symbol_name.c_str(), @@ -1264,9 +1266,9 @@ Input_objects::add_object(Object* obj) { // Set the global target from the first object file we recognize. Target* target = obj->target(); - if (!parameters->is_target_valid()) + if (!parameters->target_valid()) set_parameters_target(target); - else if (target != parameters->target()) + else if (target != ¶meters->target()) { obj->error(_("incompatible target")); return false; diff --git a/gold/options.cc b/gold/options.cc index c65862e..716b133 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -30,7 +30,6 @@ #include "debug.h" #include "script.h" -#include "target-select.h" #include "options.h" namespace gold @@ -717,34 +716,6 @@ General_options::set_oformat(const char* arg) this->oformat_ = string_to_object_format(arg); } -// The x86_64 kernel build converts a binary file to an object file -// using -r --format binary --oformat elf32-i386 foo.o. In order to -// support that for gold we support determining the default target -// choice from the output format. We recognize names that the GNU -// linker uses. - -Target* -General_options::default_target() const -{ - if (this->oformat_string_ != NULL) - { - Target* target = select_target_by_name(this->oformat_string_); - if (target != NULL) - return target; - - gold_error(_("unrecognized output format %s"), - this->oformat_string_); - } - - // The GOLD_DEFAULT_xx macros are defined by the configure script. - Target* target = select_target(elfcpp::GOLD_DEFAULT_MACHINE, - GOLD_DEFAULT_SIZE, - GOLD_DEFAULT_BIG_ENDIAN, - 0, 0); - gold_assert(target != NULL); - return target; -} - // Handle the -z option. void diff --git a/gold/options.h b/gold/options.h index c08b391..c4e9859 100644 --- a/gold/options.h +++ b/gold/options.h @@ -163,6 +163,10 @@ class General_options oformat() const { return this->oformat_; } + const char* + oformat_string() const + { return this->oformat_string_; } + // Return the default target. Target* default_target() const; @@ -245,6 +249,12 @@ class General_options shared() const { return this->is_shared_; } + // This is not defined via a flag, but combines flags to say whether + // the output is position-independent or not. + bool + output_is_position_independent() const + { return this->shared(); } + // --static: Whether doing a static link. bool is_static() const diff --git a/gold/output.cc b/gold/output.cc index 107ed09..31a2531 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -61,7 +61,8 @@ Output_data::~Output_data() uint64_t Output_data::default_alignment() { - return Output_data::default_alignment_for_size(parameters->get_size()); + return Output_data::default_alignment_for_size( + parameters->target().get_size()); } // Return the default alignment for a size--32 or 64. @@ -94,7 +95,7 @@ Output_section_headers::Output_section_headers( { // Count all the sections. Start with 1 for the null section. off_t count = 1; - if (!parameters->output_is_object()) + if (!parameters->options().relocatable()) { for (Layout::Segment_list::const_iterator p = segment_list->begin(); p != segment_list->end(); @@ -112,7 +113,7 @@ Output_section_headers::Output_section_headers( } count += unattached_section_list->size(); - const int size = parameters->get_size(); + const int size = parameters->target().get_size(); int shdr_size; if (size == 32) shdr_size = elfcpp::Elf_sizes<32>::shdr_size; @@ -129,46 +130,31 @@ Output_section_headers::Output_section_headers( void Output_section_headers::do_write(Output_file* of) { - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_32_BIG - this->do_sized_write<32, true>(of); -#else - gold_unreachable(); -#endif - } - else - { #ifdef HAVE_TARGET_32_LITTLE - this->do_sized_write<32, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->do_sized_write<32, false>(of); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_64_BIG - this->do_sized_write<64, true>(of); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_32_BIG + case Parameters::TARGET_32_BIG: + this->do_sized_write<32, true>(of); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_LITTLE - this->do_sized_write<64, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->do_sized_write<64, false>(of); + break; #endif - } +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + this->do_sized_write<64, true>(of); + break; +#endif + default: + gold_unreachable(); } - else - gold_unreachable(); } template<int size, bool big_endian> @@ -198,7 +184,7 @@ Output_section_headers::do_sized_write(Output_file* of) v += shdr_size; unsigned int shndx = 1; - if (!parameters->output_is_object()) + if (!parameters->options().relocatable()) { for (Layout::Segment_list::const_iterator p = this->segment_list_->begin(); @@ -237,7 +223,7 @@ Output_section_headers::do_sized_write(Output_file* of) // For a relocatable link, we did unallocated group sections // above, since they have to come first. if ((*p)->type() == elfcpp::SHT_GROUP - && parameters->output_is_object()) + && parameters->options().relocatable()) continue; gold_assert(shndx == (*p)->out_shndx()); elfcpp::Shdr_write<size, big_endian> oshdr(v); @@ -255,7 +241,7 @@ Output_segment_headers::Output_segment_headers( const Layout::Segment_list& segment_list) : segment_list_(segment_list) { - const int size = parameters->get_size(); + const int size = parameters->target().get_size(); int phdr_size; if (size == 32) phdr_size = elfcpp::Elf_sizes<32>::phdr_size; @@ -270,46 +256,31 @@ Output_segment_headers::Output_segment_headers( void Output_segment_headers::do_write(Output_file* of) { - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_32_BIG - this->do_sized_write<32, true>(of); -#else - gold_unreachable(); -#endif - } - else - { #ifdef HAVE_TARGET_32_LITTLE - this->do_sized_write<32, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->do_sized_write<32, false>(of); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_64_BIG - this->do_sized_write<64, true>(of); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_32_BIG + case Parameters::TARGET_32_BIG: + this->do_sized_write<32, true>(of); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_LITTLE - this->do_sized_write<64, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->do_sized_write<64, false>(of); + break; #endif - } +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + this->do_sized_write<64, true>(of); + break; +#endif + default: + gold_unreachable(); } - else - gold_unreachable(); } template<int size, bool big_endian> @@ -349,7 +320,7 @@ Output_file_header::Output_file_header(const Target* target, shstrtab_(NULL), entry_(entry) { - const int size = parameters->get_size(); + const int size = parameters->target().get_size(); int ehdr_size; if (size == 32) ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size; @@ -378,46 +349,31 @@ Output_file_header::do_write(Output_file* of) { gold_assert(this->offset() == 0); - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_32_BIG - this->do_sized_write<32, true>(of); -#else - gold_unreachable(); -#endif - } - else - { #ifdef HAVE_TARGET_32_LITTLE - this->do_sized_write<32, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->do_sized_write<32, false>(of); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_64_BIG - this->do_sized_write<64, true>(of); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_32_BIG + case Parameters::TARGET_32_BIG: + this->do_sized_write<32, true>(of); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_LITTLE - this->do_sized_write<64, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->do_sized_write<64, false>(of); + break; #endif - } +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + this->do_sized_write<64, true>(of); + break; +#endif + default: + gold_unreachable(); } - else - gold_unreachable(); } // Write out the file header with appropriate size and endianess. @@ -452,9 +408,9 @@ Output_file_header::do_sized_write(Output_file* of) oehdr.put_e_ident(e_ident); elfcpp::ET e_type; - if (parameters->output_is_object()) + if (parameters->options().relocatable()) e_type = elfcpp::ET_REL; - else if (parameters->output_is_shared()) + else if (parameters->options().shared()) e_type = elfcpp::ET_DYN; else e_type = elfcpp::ET_EXEC; @@ -505,7 +461,8 @@ typename elfcpp::Elf_types<size>::Elf_Addr Output_file_header::entry() { const bool should_issue_warning = (this->entry_ != NULL - && parameters->output_is_executable()); + && !parameters->options().relocatable() + && !parameters->options().shared()); // FIXME: Need to support target specific entry symbol. const char* entry = this->entry_; @@ -1470,9 +1427,9 @@ Output_data_dynamic::Dynamic_entry::write( void Output_data_dynamic::do_adjust_output_section(Output_section* os) { - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) os->set_entsize(elfcpp::Elf_sizes<32>::dyn_size); - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) os->set_entsize(elfcpp::Elf_sizes<64>::dyn_size); else gold_unreachable(); @@ -1487,9 +1444,9 @@ Output_data_dynamic::set_final_data_size() this->add_constant(elfcpp::DT_NULL, 0); int dyn_size; - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) dyn_size = elfcpp::Elf_sizes<32>::dyn_size; - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) dyn_size = elfcpp::Elf_sizes<64>::dyn_size; else gold_unreachable(); @@ -1501,46 +1458,31 @@ Output_data_dynamic::set_final_data_size() void Output_data_dynamic::do_write(Output_file* of) { - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_32_BIG - this->sized_write<32, true>(of); -#else - gold_unreachable(); -#endif - } - else - { #ifdef HAVE_TARGET_32_LITTLE - this->sized_write<32, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->sized_write<32, false>(of); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_64_BIG - this->sized_write<64, true>(of); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_32_BIG + case Parameters::TARGET_32_BIG: + this->sized_write<32, true>(of); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_LITTLE - this->sized_write<64, false>(of); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->sized_write<64, false>(of); + break; #endif - } +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + this->sized_write<64, true>(of); + break; +#endif + default: + gold_unreachable(); } - else - gold_unreachable(); } template<int size, bool big_endian> @@ -2149,7 +2091,7 @@ Output_section::do_write(Output_file* of) p != this->fills_.end(); ++p) { - std::string fill_data(parameters->target()->code_fill(p->length())); + std::string fill_data(parameters->target().code_fill(p->length())); of->write(output_section_file_offset + p->section_offset(), fill_data.data(), fill_data.size()); } @@ -2198,13 +2140,12 @@ Output_section::write_to_postprocessing_buffer() { gold_assert(this->requires_postprocessing()); - Target* target = parameters->target(); unsigned char* buffer = this->postprocessing_buffer(); for (Fill_list::iterator p = this->fills_.begin(); p != this->fills_.end(); ++p) { - std::string fill_data(target->code_fill(p->length())); + std::string fill_data(parameters->target().code_fill(p->length())); memcpy(buffer + p->section_offset(), fill_data.data(), fill_data.size()); } @@ -2886,7 +2827,7 @@ Output_file::open(off_t file_size) if (::stat(this->name_, &s) == 0 && s.st_size != 0) unlink_if_ordinary(this->name_); - int mode = parameters->output_is_object() ? 0666 : 0777; + int mode = parameters->options().relocatable() ? 0666 : 0777; int o = ::open(this->name_, O_RDWR | O_CREAT | O_TRUNC, mode); if (o < 0) gold_fatal(_("%s: open: %s"), this->name_, strerror(errno)); diff --git a/gold/parameters.cc b/gold/parameters.cc index 56de281..db775ed 100644 --- a/gold/parameters.cc +++ b/gold/parameters.cc @@ -24,127 +24,142 @@ #include "options.h" #include "target.h" -#include "parameters.h" +#include "target-select.h" namespace gold { -// Initialize the parameters from the options. - -Parameters::Parameters(Errors* errors) - : errors_(errors), threads_(false), output_file_name_(NULL), - output_file_type_(OUTPUT_INVALID), emit_relocs_(false), sysroot_(), - strip_(STRIP_INVALID), allow_shlib_undefined_(false), - symbolic_(false), demangle_(false), detect_odr_violations_(false), - optimization_level_(0), export_dynamic_(false), debug_(0), - is_doing_static_link_valid_(false), doing_static_link_(false), - is_target_valid_(false), target_(NULL), size_(0), is_big_endian_(false), - max_page_size_(0), common_page_size_(0) +void +Parameters::set_errors(Errors* errors) { + gold_assert(this->errors_ == NULL); + this->errors_ = errors; } -// Set fields from the command line options. - void -Parameters::set_from_options(const General_options* options) +Parameters::set_options(const General_options* options) { - this->threads_ = options->threads(); - this->output_file_name_ = options->output_file_name(); - this->emit_relocs_ = options->emit_relocs(); - this->sysroot_ = options->sysroot(); - this->allow_shlib_undefined_ = options->allow_shlib_undefined(); - this->symbolic_ = options->Bsymbolic(); - this->demangle_ = options->demangle(); - this->detect_odr_violations_ = options->detect_odr_violations(); - this->optimization_level_ = options->optimize(); - this->export_dynamic_ = options->export_dynamic(); - this->debug_ = options->debug(); - - if (options->shared()) - this->output_file_type_ = OUTPUT_SHARED; - else if (options->relocatable()) - this->output_file_type_ = OUTPUT_OBJECT; - else - this->output_file_type_ = OUTPUT_EXECUTABLE; - - if (options->strip_all()) - this->strip_ = STRIP_ALL; - else if (options->strip_debug()) - this->strip_ = STRIP_DEBUG; - else if (options->strip_debug_gdb()) - this->strip_ = STRIP_DEBUG_UNUSED_BY_GDB; - else - this->strip_ = STRIP_NONE; - - this->max_page_size_ = options->max_page_size(); - this->common_page_size_ = options->common_page_size(); - - this->options_valid_ = true; + gold_assert(!this->options_valid()); + this->options_ = options; + // For speed, we make our own copy of the debug variable. + this->debug_ = this->options().debug(); } -// Set whether we are doing a static link. - void Parameters::set_doing_static_link(bool doing_static_link) { + gold_assert(!this->doing_static_link_valid_); this->doing_static_link_ = doing_static_link; - this->is_doing_static_link_valid_ = true; + this->doing_static_link_valid_ = true; } -// Set the target. - void -Parameters::set_target(Target* target) +Parameters::set_target(const Target* target) { - if (!this->is_target_valid_) - { - this->target_ = target; - this->size_ = target->get_size(); - this->is_big_endian_ = target->is_big_endian(); - this->is_target_valid_ = true; - } + if (!this->target_valid()) + this->target_ = target; else gold_assert(target == this->target_); } -// Our local version of the variable, which is not const. - -static Parameters* static_parameters; +// The x86_64 kernel build converts a binary file to an object file +// using -r --format binary --oformat elf32-i386 foo.o. In order to +// support that for gold we support determining the default target +// choice from the output format. We recognize names that the GNU +// linker uses. -// The global variable. +const Target& +Parameters::default_target() const +{ + gold_assert(this->options_valid()); + if (this->options().oformat_string() != NULL) + { + const Target* target + = select_target_by_name(this->options().oformat_string()); + if (target != NULL) + return *target; -const Parameters* parameters; + gold_error(_("unrecognized output format %s"), + this->options().oformat_string()); + } -// Initialize the global variable. + // The GOLD_DEFAULT_xx macros are defined by the configure script. + const Target* target = select_target(elfcpp::GOLD_DEFAULT_MACHINE, + GOLD_DEFAULT_SIZE, + GOLD_DEFAULT_BIG_ENDIAN, + 0, 0); + gold_assert(target != NULL); + return *target; +} -void -initialize_parameters(Errors* errors) +Parameters::Target_size_endianness +Parameters::size_and_endianness() const { - parameters = static_parameters = new Parameters(errors); + if (this->target().get_size() == 32) + { + if (!this->target().is_big_endian()) + { +#ifdef HAVE_TARGET_32_LITTLE + return TARGET_32_LITTLE; +#else + gold_unreachable(); +#endif + } + else + { +#ifdef HAVE_TARGET_32_BIG + return TARGET_32_BIG; +#else + gold_unreachable(); +#endif + } + } + else if (parameters->target().get_size() == 64) + { + if (!parameters->target().is_big_endian()) + { +#ifdef HAVE_TARGET_64_LITTLE + return TARGET_64_LITTLE; +#else + gold_unreachable(); +#endif + } + else + { +#ifdef HAVE_TARGET_64_BIG + return TARGET_64_BIG; +#else + gold_unreachable(); +#endif + } + } + else + gold_unreachable(); } -// Set values from the options. -void -set_parameters_from_options(const General_options* options) -{ - static_parameters->set_from_options(options); -} +// Our local version of the variable, which is not const. + +static Parameters static_parameters; + +// The global variable. -// Set whether we are doing a static link. +const Parameters* parameters = &static_parameters; void -set_parameters_doing_static_link(bool doing_static_link) -{ - static_parameters->set_doing_static_link(doing_static_link); -} +set_parameters_errors(Errors* errors) +{ static_parameters.set_errors(errors); } -// Set the target. +void +set_parameters_options(const General_options* options) +{ static_parameters.set_options(options); } void -set_parameters_target(Target* target) -{ - static_parameters->set_target(target); -} +set_parameters_target(const Target* target) +{ static_parameters.set_target(target); } + +void +set_parameters_doing_static_link(bool doing_static_link) +{ static_parameters.set_doing_static_link(doing_static_link); } } // End namespace gold. diff --git a/gold/parameters.h b/gold/parameters.h index 9d3ebb6..3b10228 100644 --- a/gold/parameters.h +++ b/gold/parameters.h @@ -32,16 +32,39 @@ class Target; // Here we define the Parameters class which simply holds simple // general parameters which apply to the entire link. We use a global -// variable for this. This is in contrast to the General_options -// class, which holds the complete state of position independent -// command line options. The hope is that Parameters will stay fairly -// simple, so that if this turns into a library it will be clear how -// these parameters should be set. +// variable for this. The parameters class holds three types of data: +// 1) An Errors struct. Any part of the code that wants to log an +// error can use parameters->errors(). +// 2) A const General_options. These are the options as read on +// the commandline. +// 3) Target information, such as size and endian-ness. This is +// available as soon as we've decided on the Target (after +// parsing the first .o file). +// 4) Whether we're doing a static link or not. This is set +// after all inputs have been read and we know if any is a +// dynamic library. class Parameters { public: - Parameters(Errors*); + Parameters() + : errors_(NULL), options_(NULL), target_(NULL), + doing_static_link_valid_(false), doing_static_link_(false), + debug_(0) + { } + + // These should be called as soon as they are known. + void + set_errors(Errors* errors); + + void + set_options(const General_options* options); + + void + set_target(const Target* target); + + void + set_doing_static_link(bool doing_static_link); // Return the error object. Errors* @@ -52,310 +75,89 @@ class Parameters // called, but it is needed by gold_exit. bool options_valid() const - { return this->options_valid_; } - - // Whether to use threads. - bool - threads() const - { - gold_assert(this->options_valid_); - return this->threads_; - } - - // Return the output file name. - const char* - output_file_name() const - { - gold_assert(this->options_valid_); - return this->output_file_name_; - } - - // Whether we are generating a regular executable. - bool - output_is_executable() const - { - gold_assert(this->output_file_type_ != OUTPUT_INVALID); - return this->output_file_type_ == OUTPUT_EXECUTABLE; - } - - // Whether we are generating a shared library. - bool - output_is_shared() const - { - gold_assert(this->output_file_type_ != OUTPUT_INVALID); - return this->output_file_type_ == OUTPUT_SHARED; - } - - // Whether we are generating an object file. - bool - output_is_object() const - { - gold_assert(this->output_file_type_ != OUTPUT_INVALID); - return this->output_file_type_ == OUTPUT_OBJECT; - } - - // Whether we are generating position-independent output. - // This is the case when generating either a shared library - // or a regular executable with the --pic-executable option. - // FIXME: support --pic-executable - bool - output_is_position_independent() const - { return output_is_shared(); } - - // Whether to emit relocations in the output. - bool - emit_relocs() const - { return this->emit_relocs_; } - - // The target system root directory. This is NULL if there isn't - // one. - const std::string& - sysroot() const - { - gold_assert(this->options_valid_); - return this->sysroot_; - } - - // Whether to strip all symbols. - bool - strip_all() const - { - gold_assert(this->strip_ != STRIP_INVALID); - return this->strip_ == STRIP_ALL; - } - - // Whether to strip debugging information. - bool - strip_debug() const - { - gold_assert(this->strip_ != STRIP_INVALID); - return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; - } - - // Whether to strip debugging information that's not used by gdb. - bool - strip_debug_gdb() const - { - gold_assert(this->strip_ != STRIP_INVALID); - return this->strip_debug() || this->strip_ == STRIP_DEBUG_UNUSED_BY_GDB; - } - - // Whether to permit unresolved references from shared libraries. - bool - allow_shlib_undefined() const - { - gold_assert(this->options_valid_); - return this->allow_shlib_undefined_; - } - - // Whether we are doing a symbolic link, in which all defined - // symbols are bound locally. - bool - Bsymbolic() const - { - gold_assert(this->options_valid_); - return this->symbolic_; - } - - // Whether we should demangle C++ symbols in our log messages. - bool - demangle() const - { return this->demangle_; } - - // Whether we should try to detect violations of the One Definition Rule. - bool - detect_odr_violations() const - { - gold_assert(this->options_valid_); - return this->detect_odr_violations_; - } - - // The general linker optimization level (-O). - int - optimize() const - { - gold_assert(this->options_valid_); - return this->optimization_level_; - } - - // Whether the -E/--export-dynamic flag is set. - bool - export_dynamic() const - { - gold_assert(this->options_valid_); - return this->export_dynamic_; - } + { return this->options_ != NULL; } - // Return the debug flags. These are the flags for which we should - // report internal debugging information. - unsigned int - debug() const - { - gold_assert(this->options_valid_); - return this->debug_; - } - - // 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 + // Return the options object. + const General_options& + options() const { - gold_assert(this->is_doing_static_link_valid_); - return this->doing_static_link_; + gold_assert(this->options_valid()); + return *this->options_; } // Return whether the target field has been set. bool - is_target_valid() const - { return this->is_target_valid_; } + target_valid() const + { return this->target_ != NULL; } // The target of the output file we are generating. - Target* + const Target& target() const { - gold_assert(this->is_target_valid_); - return this->target_; + gold_assert(this->target_valid()); + return *this->target_; } - // The size of the output file we are generating. This should - // return 32 or 64. - int - get_size() const - { - gold_assert(this->is_target_valid_); - return this->size_; - } + // When we don't have an output file to associate a target, make a + // default one, with guesses about size and endianness. + const Target& + default_target() const; - // Whether the output is big endian. bool - is_big_endian() const - { - gold_assert(this->is_target_valid_); - return this->is_big_endian_; - } - - // The maximum page size - uint64_t - max_page_size() const + doing_static_link() const { - gold_assert(this->is_target_valid_); - return this->max_page_size_; + gold_assert(this->doing_static_link_valid_); + return this->doing_static_link_; } - // The common page size - uint64_t - common_page_size() const + // This is just a copy of options().debug(). We make a copy so we + // don't have to #include options.h in order to inline + // is_debugging_enabled, below. + int + debug() const { - gold_assert(this->is_target_valid_); - return this->common_page_size_; + gold_assert(this->options_valid()); + return debug_; } - // Set values recorded from options. - void - set_from_options(const General_options*); + // A convenience routine for combining size and endianness. It also + // checks the HAVE_TARGET_FOO configure options and dies if the + // current target's size/endianness is not supported according to + // HAVE_TARGET_FOO. Otherwise it returns this enum + enum Target_size_endianness + { TARGET_32_LITTLE, TARGET_32_BIG, TARGET_64_LITTLE, TARGET_64_BIG }; - // Set whether we are doing a static link. - void - set_doing_static_link(bool doing_static_link); + Target_size_endianness + size_and_endianness() const; - // Set the target. - void - set_target(Target* target); private: - // The types of output files. - enum Output_file_type - { - // Uninitialized. - OUTPUT_INVALID, - // Generating executable. - OUTPUT_EXECUTABLE, - // Generating shared library. - OUTPUT_SHARED, - // Generating object file. - OUTPUT_OBJECT - }; - - // Which symbols to strip. - enum Strip - { - // Uninitialize. - STRIP_INVALID, - // Don't strip any symbols. - STRIP_NONE, - // Strip all symbols. - STRIP_ALL, - // Strip debugging information. - STRIP_DEBUG, - // Strip debugging information that's not used by gdb (at least <= 6.7) - STRIP_DEBUG_UNUSED_BY_GDB - }; - - // A pointer to the error handling object. Errors* errors_; - - // Whether the fields set from the options are valid. - bool options_valid_; - // Whether to use threads. - bool threads_; - // The output file name. - const char* output_file_name_; - // The type of the output file. - Output_file_type output_file_type_; - // Whether to emit relocations (-q/--emit-relocs). - bool emit_relocs_; - // The target system root directory. - std::string sysroot_; - // Which symbols to strip. - Strip strip_; - // Whether to allow undefined references from shared libraries. - bool allow_shlib_undefined_; - // Whether we are doing a symbolic link. - bool symbolic_; - // Whether we should demangle C++ symbols in our log messages. - bool demangle_; - // Whether we try to detect One Definition Rule violations. - bool detect_odr_violations_; - // The optimization level. - int optimization_level_; - // Whether the -E/--export-dynamic flag is set. - bool export_dynamic_; - // The debug flags. - unsigned int debug_; - - // Whether the doing_static_link_ field is valid. - bool is_doing_static_link_valid_; - // Whether we are doing a static link. + const General_options* options_; + const Target* target_; + bool doing_static_link_valid_; bool doing_static_link_; - // Whether the target_ field is valid. - bool is_target_valid_; - // The target. - Target* target_; - // The size of the output file--32 or 64. - int size_; - // Whether the output file is big endian. - bool is_big_endian_; - // The maximum page size and common page size - int max_page_size_; - int common_page_size_; + int debug_; }; // This is a global variable. extern const Parameters* parameters; -// Initialize the global variable. -extern void initialize_parameters(Errors*); +// We use free functions for these since they affect a global variable +// that is internal to parameters.cc. -// Set the options. -extern void set_parameters_from_options(const General_options*); +extern void +set_parameters_errors(Errors* errors); -// Set the target recorded in the global parameters variable. -extern void set_parameters_target(Target* target); +extern void +set_parameters_options(const General_options* options); -// Set whether we are doing a static link. -extern void set_parameters_doing_static_link(bool doing_static_link); +extern void +set_parameters_target(const Target* target); +extern void +set_parameters_doing_static_link(bool doing_static_link); + // Return whether we are doing a particular debugging type. The // argument is one of the flags from debug.h. diff --git a/gold/reloc.cc b/gold/reloc.cc index 63ebb84..405d1da 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -229,8 +229,8 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd) bool is_section_allocated = ((secshdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0); if (!is_section_allocated - && !parameters->output_is_object() - && !parameters->emit_relocs()) + && !parameters->options().relocatable() + && !parameters->options().emit_relocs()) continue; if (shdr.get_sh_link() != this->symtab_shndx_) @@ -317,7 +317,7 @@ Sized_relobj<size, big_endian>::do_scan_relocs(const General_options& options, p != rd->relocs.end(); ++p) { - if (!parameters->output_is_object()) + if (!parameters->options().relocatable()) { // As noted above, when not generating an object file, we // only scan allocated sections. We may see a non-allocated @@ -329,7 +329,7 @@ Sized_relobj<size, big_endian>::do_scan_relocs(const General_options& options, p->needs_special_offset_handling, this->local_symbol_count_, local_symbols); - if (parameters->emit_relocs()) + if (parameters->options().emit_relocs()) this->emit_relocs_scan(options, symtab, layout, local_symbols, p); } else @@ -555,7 +555,8 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, if (shdr.get_sh_type() == elfcpp::SHT_NOBITS) continue; - if ((parameters->output_is_object() || parameters->emit_relocs()) + if ((parameters->options().relocatable() + || parameters->options().emit_relocs()) && (shdr.get_sh_type() == elfcpp::SHT_REL || shdr.get_sh_type() == elfcpp::SHT_RELA) && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0) @@ -731,7 +732,7 @@ Sized_relobj<size, big_endian>::relocate_sections( off_t output_offset = map_sections[index].offset; gold_assert((*pviews)[index].view != NULL); - if (parameters->output_is_object()) + if (parameters->options().relocatable()) gold_assert((*pviews)[i].view != NULL); if (shdr.get_sh_link() != this->symtab_shndx_) @@ -773,7 +774,7 @@ Sized_relobj<size, big_endian>::relocate_sections( relinfo.reloc_shndx = i; relinfo.data_shndx = index; - if (!parameters->output_is_object()) + if (!parameters->options().relocatable()) { target->relocate_section(&relinfo, sh_type, @@ -784,7 +785,7 @@ Sized_relobj<size, big_endian>::relocate_sections( (*pviews)[index].view, (*pviews)[index].address, (*pviews)[index].view_size); - if (parameters->emit_relocs()) + if (parameters->options().emit_relocs()) this->emit_relocs(&relinfo, i, sh_type, prelocs, reloc_count, os, output_offset, (*pviews)[index].view, diff --git a/gold/resolve.cc b/gold/resolve.cc index 63ed5e7..185327b 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -243,7 +243,7 @@ Symbol_table::resolve(Sized_symbol<size>* to, // is an ODR violation. But it's helpful to warn about.) // We use orig_sym here because we want the symbol exactly as it // appears in the object file, not munged via our future processing. - if (parameters->detect_odr_violations() + if (parameters->options().detect_odr_violations() && orig_sym.get_st_bind() == elfcpp::STB_WEAK && to->binding() == elfcpp::STB_WEAK && orig_sym.get_st_shndx() != elfcpp::SHN_UNDEF diff --git a/gold/script-sections.cc b/gold/script-sections.cc index 68cba6b..ff40ef5 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -489,7 +489,7 @@ Output_data_expression::do_write_to_buffer(unsigned char* buf) this->dot_value_, this->dot_section_, &dummy); - if (parameters->is_big_endian()) + if (parameters->target().is_big_endian()) this->endian_write_to_buffer<true>(val, buf); else this->endian_write_to_buffer<false>(val, buf); @@ -512,7 +512,7 @@ Output_data_expression::endian_write_to_buffer(uint64_t val, elfcpp::Swap_unaligned<32, big_endian>::writeval(buf, val); break; case 8: - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { val &= 0xffffffff; if (this->is_signed_ && (val & 0x80000000) != 0) @@ -2430,12 +2430,12 @@ Script_sections::total_header_size(Layout* layout) const size_t segment_count = layout->segment_count(); size_t file_header_size; size_t segment_headers_size; - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { file_header_size = elfcpp::Elf_sizes<32>::ehdr_size; segment_headers_size = segment_count * elfcpp::Elf_sizes<32>::phdr_size; } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { file_header_size = elfcpp::Elf_sizes<64>::ehdr_size; segment_headers_size = segment_count * elfcpp::Elf_sizes<64>::phdr_size; @@ -2455,7 +2455,7 @@ uint64_t Script_sections::header_size_adjustment(uint64_t lma, size_t sizeof_headers) const { - const uint64_t abi_pagesize = parameters->target()->abi_pagesize(); + const uint64_t abi_pagesize = parameters->target().abi_pagesize(); uint64_t hdr_lma = lma - sizeof_headers; hdr_lma &= ~(abi_pagesize - 1); return lma - hdr_lma; @@ -2470,7 +2470,7 @@ Script_sections::create_segments(Layout* layout) { gold_assert(this->saw_sections_clause_); - if (parameters->output_is_object()) + if (parameters->options().relocatable()) return NULL; if (this->saw_phdrs_clause()) @@ -2485,7 +2485,7 @@ Script_sections::create_segments(Layout* layout) this->create_note_and_tls_segments(layout, §ions); // Walk through the sections adding them to PT_LOAD segments. - const uint64_t abi_pagesize = parameters->target()->abi_pagesize(); + const uint64_t abi_pagesize = parameters->target().abi_pagesize(); Output_segment* first_seg = NULL; Output_segment* current_seg = NULL; bool is_current_seg_readonly = true; diff --git a/gold/script.cc b/gold/script.cc index b5f2abb..ee54e9d 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -951,7 +951,7 @@ Symbol_assignment::finalize_maybe_dot(Symbol_table* symtab, return; } - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) this->sized_finalize<32>(symtab, layout, is_dot_available, dot_value, @@ -960,7 +960,7 @@ Symbol_assignment::finalize_maybe_dot(Symbol_table* symtab, gold_unreachable(); #endif } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) this->sized_finalize<64>(symtab, layout, is_dot_available, dot_value, @@ -1005,7 +1005,7 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, if (val_section != NULL) return; - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) Sized_symbol<32>* ssym = symtab->get_sized_symbol<32>(this->sym_); @@ -1014,7 +1014,7 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, gold_unreachable(); #endif } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) Sized_symbol<64>* ssym = symtab->get_sized_symbol<64>(this->sym_); @@ -2036,7 +2036,7 @@ script_add_file(void* closurev, const char* name, size_t length) { if (closure->is_in_sysroot()) { - const std::string& sysroot(parameters->sysroot()); + const std::string& sysroot(parameters->options().sysroot()); gold_assert(!sysroot.empty()); name_string = sysroot + name_string; } diff --git a/gold/stringpool.cc b/gold/stringpool.cc index 5d13dcf..b2738b3 100644 --- a/gold/stringpool.cc +++ b/gold/stringpool.cc @@ -394,7 +394,7 @@ Stringpool_template<Stringpool_char>::set_string_offsets() // the strtab size, and gives a relatively small benefit (it's // typically rare for a symbol to be a suffix of another), we only // take the time to sort when the user asks for heavy optimization. - if (parameters->optimize() < 2) + if (parameters->options().optimize() < 2) { for (typename String_set_type::iterator curr = this->string_set_.begin(); curr != this->string_set_.end(); diff --git a/gold/symtab.cc b/gold/symtab.cc index 86b69b4..25f1cab 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -79,7 +79,7 @@ Symbol::init_fields(const char* name, const char* version, static std::string demangle(const char* name) { - if (!parameters->demangle()) + if (!parameters->options().demangle()) return name; // cplus_demangle allocates memory for the result it returns, @@ -257,7 +257,7 @@ Symbol::should_add_dynsym_entry() const // If exporting all symbols or building a shared library, // and the symbol is defined in a regular object and is // externally visible, we need to add it. - if ((parameters->export_dynamic() || parameters->output_is_shared()) + if ((parameters->options().export_dynamic() || parameters->options().shared()) && !this->is_from_dynobj() && this->is_externally_visible()) return true; @@ -273,7 +273,7 @@ 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()) + if (parameters->options().shared() || parameters->options().relocatable()) return false; // If the symbol is not from an object file, then it is defined, and @@ -667,7 +667,7 @@ Symbol_table::add_from_relobj( typename Sized_relobj<size, big_endian>::Symbols* sympointers) { gold_assert(size == relobj->target()->get_size()); - gold_assert(size == parameters->get_size()); + gold_assert(size == parameters->target().get_size()); const int sym_size = elfcpp::Elf_sizes<size>::sym_size; @@ -802,7 +802,7 @@ Symbol_table::add_from_dynobj( const std::vector<const char*>* version_map) { gold_assert(size == dynobj->target()->get_size()); - gold_assert(size == parameters->get_size()); + gold_assert(size == parameters->target().get_size()); if (dynobj->just_symbols()) { @@ -1087,16 +1087,16 @@ Symbol_table::define_special_symbol(const char** pname, const char** pversion, } } - const Target* target = parameters->target(); - if (!target->has_make_symbol()) + const Target& target = parameters->target(); + if (!target.has_make_symbol()) sym = new Sized_symbol<size>(); else { - gold_assert(target->get_size() == size); - gold_assert(target->is_big_endian() ? big_endian : !big_endian); + gold_assert(target.get_size() == size); + gold_assert(target.is_big_endian() ? big_endian : !big_endian); typedef Sized_target<size, big_endian> My_target; const My_target* sized_target = - static_cast<const My_target*>(target); + static_cast<const My_target*>(&target); sym = sized_target->make_symbol(); if (sym == NULL) return NULL; @@ -1128,7 +1128,7 @@ Symbol_table::define_in_output_data(const char* name, bool offset_is_from_end, bool only_if_ref) { - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) return this->do_define_in_output_data<32>(name, version, od, @@ -1140,7 +1140,7 @@ Symbol_table::define_in_output_data(const char* name, gold_unreachable(); #endif } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) return this->do_define_in_output_data<64>(name, version, od, @@ -1176,7 +1176,7 @@ Symbol_table::do_define_in_output_data( Sized_symbol<size>* sym; Sized_symbol<size>* oldsym; - if (parameters->is_big_endian()) + if (parameters->target().is_big_endian()) { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) ( @@ -1232,7 +1232,7 @@ Symbol_table::define_in_output_segment(const char* name, Symbol::Segment_offset_base offset_base, bool only_if_ref) { - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) return this->do_define_in_output_segment<32>(name, version, os, @@ -1243,7 +1243,7 @@ Symbol_table::define_in_output_segment(const char* name, gold_unreachable(); #endif } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) return this->do_define_in_output_segment<64>(name, version, os, @@ -1278,7 +1278,7 @@ Symbol_table::do_define_in_output_segment( Sized_symbol<size>* sym; Sized_symbol<size>* oldsym; - if (parameters->is_big_endian()) + if (parameters->target().is_big_endian()) { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) ( @@ -1335,7 +1335,7 @@ Symbol_table::define_as_constant(const char* name, bool only_if_ref, bool force_override) { - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) return this->do_define_as_constant<32>(name, version, value, @@ -1346,7 +1346,7 @@ Symbol_table::define_as_constant(const char* name, gold_unreachable(); #endif } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) return this->do_define_as_constant<64>(name, version, value, @@ -1380,7 +1380,7 @@ Symbol_table::do_define_as_constant( Sized_symbol<size>* sym; Sized_symbol<size>* oldsym; - if (parameters->is_big_endian()) + if (parameters->target().is_big_endian()) { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) ( @@ -1598,7 +1598,7 @@ Symbol_table::finalize(off_t off, off_t dynoff, size_t dyn_global_index, this->first_dynamic_global_index_ = dyn_global_index; this->dynamic_count_ = dyncount; - if (parameters->get_size() == 32) + if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_32_LITTLE) ret = this->sized_finalize<32>(off, pool, plocal_symcount); @@ -1606,7 +1606,7 @@ Symbol_table::finalize(off_t off, off_t dynoff, size_t dyn_global_index, gold_unreachable(); #endif } - else if (parameters->get_size() == 64) + else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_BIG) || defined(HAVE_TARGET_64_LITTLE) ret = this->sized_finalize<64>(off, pool, plocal_symcount); @@ -1792,7 +1792,7 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym) sym->set_value(value); - if (parameters->strip_all()) + if (parameters->options().strip_all()) { sym->set_symtab_index(-1U); return false; @@ -1808,50 +1808,35 @@ Symbol_table::write_globals(const Input_objects* input_objects, const Stringpool* sympool, const Stringpool* dynpool, Output_file* of) const { - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_32_BIG - this->sized_write_globals<32, true>(input_objects, sympool, - dynpool, of); -#else - gold_unreachable(); -#endif - } - else - { #ifdef HAVE_TARGET_32_LITTLE - this->sized_write_globals<32, false>(input_objects, sympool, - dynpool, of); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->sized_write_globals<32, false>(input_objects, sympool, + dynpool, of); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_64_BIG - this->sized_write_globals<64, true>(input_objects, sympool, - dynpool, of); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_32_BIG + case Parameters::TARGET_32_BIG: + this->sized_write_globals<32, true>(input_objects, sympool, + dynpool, of); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_LITTLE - this->sized_write_globals<64, false>(input_objects, sympool, - dynpool, of); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->sized_write_globals<64, false>(input_objects, sympool, + dynpool, of); + break; #endif - } +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + this->sized_write_globals<64, true>(input_objects, sympool, + dynpool, of); + break; +#endif + default: + gold_unreachable(); } - else - gold_unreachable(); } // Write out the global symbols. @@ -1863,7 +1848,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, const Stringpool* dynpool, Output_file* of) const { - const Target* const target = parameters->target(); + const Target& target = parameters->target(); const int sym_size = elfcpp::Elf_sizes<size>::sym_size; @@ -1931,7 +1916,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, if (symobj->is_dynamic()) { if (sym->needs_dynsym_value()) - dynsym_value = target->dynsym_value(sym); + dynsym_value = target.dynsym_value(sym); shndx = elfcpp::SHN_UNDEF; } else if (in_shndx == elfcpp::SHN_UNDEF @@ -1948,7 +1933,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, // In object files symbol values are section // relative. - if (parameters->output_is_object()) + if (parameters->options().relocatable()) sym_value -= os->address(); } } @@ -2047,8 +2032,8 @@ Symbol_table::warn_about_undefined_dynobj_symbol( && sym->object()->is_dynamic() && sym->shndx() == elfcpp::SHN_UNDEF && sym->binding() != elfcpp::STB_WEAK - && !parameters->allow_shlib_undefined() - && !parameters->target()->is_defined_by_abi(sym) + && !parameters->options().allow_shlib_undefined() + && !parameters->target().is_defined_by_abi(sym) && !input_objects->found_in_system_library_directory(sym->object())) { // A very ugly cast. @@ -2067,46 +2052,31 @@ Symbol_table::write_section_symbol(const Output_section *os, Output_file* of, off_t offset) const { - if (parameters->get_size() == 32) + switch (parameters->size_and_endianness()) { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_32_BIG - this->sized_write_section_symbol<32, true>(os, of, offset); -#else - gold_unreachable(); -#endif - } - else - { #ifdef HAVE_TARGET_32_LITTLE - this->sized_write_section_symbol<32, false>(os, of, offset); -#else - gold_unreachable(); + case Parameters::TARGET_32_LITTLE: + this->sized_write_section_symbol<32, false>(os, of, offset); + break; #endif - } - } - else if (parameters->get_size() == 64) - { - if (parameters->is_big_endian()) - { -#ifdef HAVE_TARGET_64_BIG - this->sized_write_section_symbol<64, true>(os, of, offset); -#else - gold_unreachable(); +#ifdef HAVE_TARGET_32_BIG + case Parameters::TARGET_32_BIG: + this->sized_write_section_symbol<32, true>(os, of, offset); + break; #endif - } - else - { #ifdef HAVE_TARGET_64_LITTLE - this->sized_write_section_symbol<64, false>(os, of, offset); -#else - gold_unreachable(); + case Parameters::TARGET_64_LITTLE: + this->sized_write_section_symbol<64, false>(os, of, offset); + break; #endif - } +#ifdef HAVE_TARGET_64_BIG + case Parameters::TARGET_64_BIG: + this->sized_write_section_symbol<64, true>(os, of, offset); + break; +#endif + default: + gold_unreachable(); } - else - gold_unreachable(); } // Write out a section symbol, specialized for size and endianness. diff --git a/gold/symtab.h b/gold/symtab.h index cdc1ec8..9a54187 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -470,8 +470,8 @@ class Symbol && this->visibility_ != elfcpp::STV_HIDDEN && this->visibility_ != elfcpp::STV_PROTECTED && !this->is_forced_local_ - && parameters->output_is_shared() - && !parameters->Bsymbolic()); + && parameters->options().shared() + && !parameters->options().Bsymbolic()); } // Return true if this symbol is a function that needs a PLT entry. @@ -515,7 +515,7 @@ class Symbol // An absolute reference within a position-independent output file // will need a dynamic relocation. if ((flags & ABSOLUTE_REF) - && parameters->output_is_position_independent()) + && parameters->options().output_is_position_independent()) return true; // A function call that can branch to a local PLT entry does not need @@ -523,12 +523,12 @@ class Symbol // shared library cannot use a PLT entry. if ((flags & FUNCTION_CALL) && this->has_plt_offset() - && !((flags & NON_PIC_REF) && parameters->output_is_shared())) + && !((flags & NON_PIC_REF) && parameters->options().shared())) return false; // A reference to any PLT entry in a non-position-independent executable // does not need a dynamic relocation. - if (!parameters->output_is_position_independent() + if (!parameters->options().output_is_position_independent() && this->has_plt_offset()) return false; @@ -1460,7 +1460,7 @@ template<int size> Sized_symbol<size>* Symbol_table::get_sized_symbol(Symbol* sym ACCEPT_SIZE) const { - gold_assert(size == parameters->get_size()); + gold_assert(size == parameters->target().get_size()); return static_cast<Sized_symbol<size>*>(sym); } @@ -1468,7 +1468,7 @@ template<int size> const Sized_symbol<size>* Symbol_table::get_sized_symbol(const Symbol* sym ACCEPT_SIZE) const { - gold_assert(size == parameters->get_size()); + gold_assert(size == parameters->target().get_size()); return static_cast<const Sized_symbol<size>*>(sym); } diff --git a/gold/target-reloc.h b/gold/target-reloc.h index 2bc0a1b..09f5076 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -217,7 +217,7 @@ relocate_section( if (sym != NULL && sym->is_undefined() && sym->binding() != elfcpp::STB_WEAK - && !parameters->output_is_shared()) + && !parameters->options().shared()) gold_undefined_symbol(sym, relinfo, i, offset); if (sym != NULL && sym->has_warning()) diff --git a/gold/target.h b/gold/target.h index fa18fc7..8d0dd17 100644 --- a/gold/target.h +++ b/gold/target.h @@ -34,6 +34,7 @@ #define GOLD_TARGET_H #include "elfcpp.h" +#include "options.h" #include "parameters.h" namespace gold @@ -105,8 +106,8 @@ class Target uint64_t abi_pagesize() const { - if (parameters->max_page_size() > 0) - return parameters->max_page_size(); + if (parameters->options().max_page_size() > 0) + return parameters->options().max_page_size(); else return this->pti_->abi_pagesize; } @@ -115,8 +116,8 @@ class Target uint64_t common_pagesize() const { - if (parameters->common_page_size() > 0) - return std::min(parameters->common_page_size(), + if (parameters->options().common_page_size() > 0) + return std::min(parameters->options().common_page_size(), this->abi_pagesize()); else return std::min(this->pti_->common_pagesize, @@ -148,7 +149,7 @@ class Target // basically one or more NOPS which must fill out the specified // length in bytes. std::string - code_fill(section_size_type length) + code_fill(section_size_type length) const { return this->do_code_fill(length); } // Return whether SYM is known to be defined by the ABI. This is @@ -205,7 +206,7 @@ class Target // Virtual function which must be implemented by the child class if // needed. virtual std::string - do_code_fill(section_size_type) + do_code_fill(section_size_type) const { gold_unreachable(); } // Virtual function which may be implemented by the child class. diff --git a/gold/testsuite/binary_unittest.cc b/gold/testsuite/binary_unittest.cc index 6a3956a..229be7e 100644 --- a/gold/testsuite/binary_unittest.cc +++ b/gold/testsuite/binary_unittest.cc @@ -111,10 +111,10 @@ bool Binary_test(Test_report*) { Errors errors(gold::program_name); - initialize_parameters(&errors); + set_parameters_errors(&errors); General_options options; - set_parameters_from_options(&options); + set_parameters_options(&options); int fail = 0; diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 3ceb798..257be65 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -142,7 +142,7 @@ class Target_x86_64 : public Sized_target<64, false> // Return a string used to fill a code section with nops. std::string - do_code_fill(section_size_type length); + do_code_fill(section_size_type length) const; // Return whether SYM is defined by the ABI. bool @@ -318,7 +318,7 @@ class Target_x86_64 : public Sized_target<64, false> bool may_need_copy_reloc(Symbol* gsym) { - return (!parameters->output_is_shared() + return (!parameters->options().shared() && gsym->is_from_dynobj() && gsym->type() != elfcpp::STT_FUNC); } @@ -749,7 +749,7 @@ Target_x86_64::optimize_tls_reloc(bool is_final, int r_type) { // If we are generating a shared library, then we can't do anything // in the linker. - if (parameters->output_is_shared()) + if (parameters->options().shared()) return tls::TLSOPT_NONE; switch (r_type) @@ -833,7 +833,7 @@ Target_x86_64::Scan::local(const General_options&, // link-time value, so we flag the location with an // R_X86_64_RELATIVE relocation so the dynamic loader can // relocate it easily. - if (parameters->output_is_position_independent()) + if (parameters->options().output_is_position_independent()) { unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info()); Reloc_section* rela_dyn = target->rela_dyn_section(layout); @@ -853,7 +853,7 @@ Target_x86_64::Scan::local(const General_options&, // executable), we need to create a dynamic relocation for this // location. We can't use an R_X86_64_RELATIVE relocation // because that is always a 64-bit relocation. - if (parameters->output_is_position_independent()) + if (parameters->options().output_is_position_independent()) { Reloc_section* rela_dyn = target->rela_dyn_section(layout); if (lsym.get_st_type() != elfcpp::STT_SECTION) @@ -908,7 +908,7 @@ Target_x86_64::Scan::local(const General_options&, { // If we are generating a shared object, we need to add a // dynamic relocation for this symbol's GOT entry. - if (parameters->output_is_position_independent()) + if (parameters->options().output_is_position_independent()) { Reloc_section* rela_dyn = target->rela_dyn_section(layout); // R_X86_64_RELATIVE assumes a 64-bit relocation. @@ -953,7 +953,7 @@ Target_x86_64::Scan::local(const General_options&, case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec case elfcpp::R_X86_64_TPOFF32: // Local-exec { - bool output_is_shared = parameters->output_is_shared(); + bool output_is_shared = parameters->options().shared(); const tls::Tls_optimization optimized_type = Target_x86_64::optimize_tls_reloc(!output_is_shared, r_type); switch (r_type) @@ -1081,7 +1081,7 @@ Target_x86_64::Scan::global(const General_options& options, // taking the address of a function. In that case we need to // set the entry in the dynamic symbol table to the address of // the PLT entry. - if (gsym->is_from_dynobj() && !parameters->output_is_shared()) + if (gsym->is_from_dynobj() && !parameters->options().shared()) gsym->set_needs_dynsym_value(); } // Make a dynamic relocation if necessary. @@ -1297,7 +1297,7 @@ Target_x86_64::Scan::global(const General_options& options, case elfcpp::R_X86_64_TPOFF32: // Local-exec layout->set_has_static_tls(); - if (parameters->output_is_shared()) + if (parameters->options().shared()) unsupported_reloc_local(object, r_type); break; @@ -1385,7 +1385,7 @@ Target_x86_64::do_finalize_sections(Layout* layout) elfcpp::Elf_sizes<64>::rela_size); } - if (!parameters->output_is_shared()) + if (!parameters->options().shared()) { // The value of the DT_DEBUG tag is filled in by the dynamic // linker at run time, and used by the debugger. @@ -1440,7 +1440,7 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo, Symbol_value<64> symval; if (gsym != NULL && (gsym->is_from_dynobj() - || (parameters->output_is_shared() + || (parameters->options().shared() && (gsym->is_undefined() || gsym->is_preemptible()))) && gsym->has_plt_offset()) { @@ -1680,7 +1680,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, elfcpp::Elf_types<64>::Elf_Addr value = psymval->value(relinfo->object, 0); const bool is_final = (gsym == NULL - ? !parameters->output_is_position_independent() + ? !parameters->options().output_is_position_independent() : gsym->final_value_is_known()); const tls::Tls_optimization optimized_type = Target_x86_64::optimize_tls_reloc(is_final, r_type); @@ -2152,7 +2152,7 @@ Target_x86_64::do_dynsym_value(const Symbol* gsym) const // the specified length. std::string -Target_x86_64::do_code_fill(section_size_type length) +Target_x86_64::do_code_fill(section_size_type length) const { if (length >= 16) { |