summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/common.cc4
-rw-r--r--gold/compressed_output.cc2
-rw-r--r--gold/dwarf_reader.cc41
-rw-r--r--gold/dynobj.cc20
-rw-r--r--gold/ehframe.cc90
-rw-r--r--gold/expression.cc22
-rw-r--r--gold/fileread.cc10
-rw-r--r--gold/gold-threads.cc5
-rw-r--r--gold/gold.cc15
-rw-r--r--gold/i386.cc49
-rw-r--r--gold/layout.cc143
-rw-r--r--gold/layout.h6
-rw-r--r--gold/main.cc6
-rw-r--r--gold/object.cc24
-rw-r--r--gold/options.cc29
-rw-r--r--gold/options.h10
-rw-r--r--gold/output.cc241
-rw-r--r--gold/parameters.cc185
-rw-r--r--gold/parameters.h352
-rw-r--r--gold/reloc.cc17
-rw-r--r--gold/resolve.cc2
-rw-r--r--gold/script-sections.cc14
-rw-r--r--gold/script.cc10
-rw-r--r--gold/stringpool.cc2
-rw-r--r--gold/symtab.cc164
-rw-r--r--gold/symtab.h14
-rw-r--r--gold/target-reloc.h2
-rw-r--r--gold/target.h13
-rw-r--r--gold/testsuite/binary_unittest.cc4
-rw-r--r--gold/x86_64.cc26
30 files changed, 596 insertions, 926 deletions
diff --git a/gold/common.cc b/gold/common.cc
index d94f2c3c9f..e6f391017d 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 0bbcb559f3..1eca021e71 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 19c1a035ac..136e4a6469 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 a33707b8c8..bfcc78ae8d 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 8306f51b6e..df9448897f 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 1cc646f853..25a19f9ae4 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 2defbf8814..901c52802d 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 = &parameters->target();
else
- target = options.default_target();
+ target = &parameters->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 4ebbdd8496..e54d96c6ec 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 e34baeb8ab..c79e87a0ee 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(&parameters->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*>(&parameters->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 6b805bdac6..4303a2a8d9 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 e8c6c66ca6..df104986da 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 e4e97e43bd..658eb1e02d 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 678bd032ef..2fc9439f47 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 c8867170cd..e444ec1ead 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 != &parameters->target())
{
obj->error(_("incompatible target"));
return false;
diff --git a/gold/options.cc b/gold/options.cc
index c65862ed9f..716b133d6f 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 c08b391f9f..c4e9859aae 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 107ed09c4b..31a2531e48 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 56de281114..db775ed0bf 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 9d3ebb6ccb..3b10228706 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 63ebb84d1d..405d1da9ff 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 63ed5e7207..185327b4e7 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 68cba6bdd9..ff40ef542b 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, &sections);
// 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 b5f2abb787..ee54e9df56 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 5d13dcf548..b2738b3e4f 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 86b69b4ded..25f1cab348 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 cdc1ec87a1..9a54187821 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 2bc0a1b3b6..09f5076d85 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 fa18fc7a35..8d0dd17f20 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 6a3956a2ec..229be7e073 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 3ceb798614..257be6529b 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)
{