void
Symbol_table::allocate_commons(const General_options& options, Layout* layout)
{
- if (this->get_size() == 32)
+ if (parameters->get_size() == 32)
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
this->do_allocate_commons<32>(options, layout);
gold_unreachable();
#endif
}
- else if (this->get_size() == 64)
+ else if (parameters->get_size() == 64)
{
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
this->do_allocate_commons<64>(options, layout);
// symbol table.
void
-Dynobj::create_elf_hash_table(const Target* target,
- const std::vector<Symbol*>& dynsyms,
+Dynobj::create_elf_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash,
unsigned int* phashlen)
* 4);
unsigned char* phash = new unsigned char[hashlen];
- if (target->is_big_endian())
- Dynobj::sized_create_elf_hash_table<true>(bucket, chain, phash, hashlen);
+ if (parameters->is_big_endian())
+ {
+#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
+ Dynobj::sized_create_elf_hash_table<true>(bucket, chain, phash,
+ hashlen);
+#else
+ gold_unreachable();
+#endif
+ }
else
- Dynobj::sized_create_elf_hash_table<false>(bucket, chain, phash, hashlen);
+ {
+#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
+ Dynobj::sized_create_elf_hash_table<false>(bucket, chain, phash,
+ hashlen);
+#else
+ gold_unreachable();
+#endif
+ }
*pphash = phash;
*phashlen = hashlen;
// symbol table.
void
-Dynobj::create_gnu_hash_table(const Target* target,
- const std::vector<Symbol*>& dynsyms,
+Dynobj::create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash,
unsigned int* phashlen)
// For the actual data generation we call out to a templatized
// function.
- int size = target->get_size();
- bool big_endian = target->is_big_endian();
+ int size = parameters->get_size();
+ bool big_endian = parameters->is_big_endian();
if (size == 32)
{
if (big_endian)
- Dynobj::sized_create_gnu_hash_table<32, true>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_32_BIG
+ Dynobj::sized_create_gnu_hash_table<32, true>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
else
- Dynobj::sized_create_gnu_hash_table<32, false>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_32_LITTLE
+ Dynobj::sized_create_gnu_hash_table<32, false>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
}
else if (size == 64)
{
if (big_endian)
- Dynobj::sized_create_gnu_hash_table<64, true>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_64_BIG
+ Dynobj::sized_create_gnu_hash_table<64, true>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
else
- Dynobj::sized_create_gnu_hash_table<64, false>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ Dynobj::sized_create_gnu_hash_table<64, false>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
// number of local dynamic symbols, which is the index of the first
// dynamic gobal symbol.
static void
- create_elf_hash_table(const Target*, const std::vector<Symbol*>& dynsyms,
+ create_elf_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash,
unsigned int* phashlen);
// of local dynamic symbols, which is the index of the first dynamic
// gobal symbol.
static void
- create_gnu_hash_table(const Target*, const std::vector<Symbol*>& dynsyms,
+ create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash, unsigned int* phashlen);
// Construct the exception frame header.
-Eh_frame_hdr::Eh_frame_hdr(const Target* target,
- Output_section* eh_frame_section)
+Eh_frame_hdr::Eh_frame_hdr(Output_section* eh_frame_section)
: Output_section_data(4),
- target_(target), eh_frame_section_(eh_frame_section)
+ eh_frame_section_(eh_frame_section)
{
}
uint64_t eh_frame_hdr_address = this->address();
uint64_t eh_frame_offset = (eh_frame_address -
(eh_frame_hdr_address + 4));
- if (this->target_->is_big_endian())
+ if (parameters->is_big_endian())
elfcpp::Swap<32, true>::writeval(oview + 4, eh_frame_offset);
else
elfcpp::Swap<32, false>::writeval(oview + 4, eh_frame_offset);
class Eh_frame_hdr : public Output_section_data
{
public:
- Eh_frame_hdr(const Target*, Output_section* eh_frame_section);
+ Eh_frame_hdr(Output_section* eh_frame_section);
// Set the final data size.
void
do_write(Output_file*);
private:
- // The output target.
- const Target* target_;
// The .eh_frame section.
Output_section* eh_frame_section_;
};
// Queue a task to write out everything else.
final_blocker->add_blocker();
- workqueue->queue(new Write_data_task(layout, symtab,
- input_objects->target(),
- of, final_blocker));
+ workqueue->queue(new Write_data_task(layout, symtab, of, final_blocker));
// Queue a task to close the output file. This will be blocked by
// FINAL_BLOCKER.
elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC);
- Eh_frame_hdr* hdr_posd = new Eh_frame_hdr(object->target(), os);
+ Eh_frame_hdr* hdr_posd = new Eh_frame_hdr(os);
hdr_os->add_output_section_data(hdr_posd);
Output_segment* hdr_oseg =
elfcpp::STT_OBJECT, elfcpp::STB_LOCAL,
elfcpp::STV_HIDDEN, 0, false, false);
- this->dynamic_data_ = new Output_data_dynamic(input_objects->target(),
- &this->dynpool_);
+ this->dynamic_data_ = new Output_data_dynamic(&this->dynpool_);
this->dynamic_section_->add_output_section_data(this->dynamic_data_);
}
Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
{
Target* const target = input_objects->target();
- const int size = target->get_size();
target->finalize_sections(this);
// Create the version sections. We can't do this until the
// dynamic string table is complete.
- this->create_version_sections(target, &versions, local_dynamic_count,
+ this->create_version_sections(&versions, local_dynamic_count,
dynamic_symbols, dynstr);
}
Output_segment* load_seg = this->find_first_load_seg();
// Lay out the segment headers.
- bool big_endian = target->is_big_endian();
Output_segment_headers* segment_headers;
- segment_headers = new Output_segment_headers(size, big_endian,
- this->segment_list_);
+ segment_headers = new Output_segment_headers(this->segment_list_);
load_seg->add_initial_output_data(segment_headers);
this->special_output_list_.push_back(segment_headers);
if (phdr_seg != NULL)
// Lay out the file header.
Output_file_header* file_header;
- file_header = new Output_file_header(size,
- big_endian,
- target,
- symtab,
- segment_headers);
+ file_header = new Output_file_header(target, symtab, segment_headers);
load_seg->add_initial_output_data(file_header);
this->special_output_list_.push_back(file_header);
off_t off = this->set_segment_offsets(target, load_seg, &shndx);
// Create the symbol table sections.
- this->create_symtab_sections(size, input_objects, symtab, &off);
+ this->create_symtab_sections(input_objects, symtab, &off);
// Create the .shstrtab section.
Output_section* shstrtab_section = this->create_shstrtab();
off = this->set_section_offsets(off, &shndx);
// Create the section table header.
- Output_section_headers* oshdrs = this->create_shdrs(size, big_endian, &off);
+ Output_section_headers* oshdrs = this->create_shdrs(&off);
file_header->set_section_info(oshdrs, shstrtab_section);
// fully laid out.
void
-Layout::create_symtab_sections(int size, const Input_objects* input_objects,
+Layout::create_symtab_sections(const Input_objects* input_objects,
Symbol_table* symtab,
off_t* poff)
{
int symsize;
unsigned int align;
- if (size == 32)
+ if (parameters->get_size() == 32)
{
symsize = elfcpp::Elf_sizes<32>::sym_size;
align = 4;
}
- else if (size == 64)
+ else if (parameters->get_size() == 64)
{
symsize = elfcpp::Elf_sizes<64>::sym_size;
align = 8;
// offset.
Output_section_headers*
-Layout::create_shdrs(int size, bool big_endian, off_t* poff)
+Layout::create_shdrs(off_t* poff)
{
Output_section_headers* oshdrs;
- oshdrs = new Output_section_headers(size, big_endian, this,
+ oshdrs = new Output_section_headers(this,
&this->segment_list_,
&this->unattached_section_list_,
&this->namepool_);
int symsize;
unsigned int align;
- const int size = target->get_size();
+ const int size = parameters->get_size();
if (size == 32)
{
symsize = elfcpp::Elf_sizes<32>::sym_size;
unsigned char* phash;
unsigned int hashlen;
- Dynobj::create_elf_hash_table(target, *pdynamic_symbols, local_symcount,
+ Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
&phash, &hashlen);
const char* hash_name = this->namepool_.add(".hash", NULL);
// Create the version sections.
void
-Layout::create_version_sections(const Target* target, const Versions* versions,
+Layout::create_version_sections(const Versions* versions,
unsigned int local_symcount,
const std::vector<Symbol*>& dynamic_symbols,
const Output_section* dynstr)
if (!versions->any_defs() && !versions->any_needs())
return;
- if (target->get_size() == 32)
+ if (parameters->get_size() == 32)
{
- if (target->is_big_endian())
+ if (parameters->is_big_endian())
{
#ifdef HAVE_TARGET_32_BIG
this->sized_create_version_sections
#endif
}
}
- else if (target->get_size() == 64)
+ else if (parameters->get_size() == 64)
{
- if (target->is_big_endian())
+ if (parameters->is_big_endian())
{
#ifdef HAVE_TARGET_64_BIG
this->sized_create_version_sections
// Write out data not associated with a section or the symbol table.
void
-Layout::write_data(const Symbol_table* symtab, const Target* target,
- Output_file* of) const
+Layout::write_data(const Symbol_table* symtab, Output_file* of) const
{
const Output_section* symtab_section = this->symtab_section_;
for (Section_list::const_iterator p = this->section_list_.begin();
gold_assert(index > 0 && index != -1U);
off_t off = (symtab_section->offset()
+ index * symtab_section->entsize());
- symtab->write_section_symbol(target, *p, of, off);
+ symtab->write_section_symbol(*p, of, off);
}
}
gold_assert(index > 0 && index != -1U);
off_t off = (dynsym_section->offset()
+ index * dynsym_section->entsize());
- symtab->write_section_symbol(target, *p, of, off);
+ symtab->write_section_symbol(*p, of, off);
}
}
void
Write_data_task::run(Workqueue*)
{
- this->layout_->write_data(this->symtab_, this->target_, this->of_);
+ this->layout_->write_data(this->symtab_, this->of_);
}
// Write_symbols_task methods.
// Write out data not associated with an input file or the symbol
// table.
void
- write_data(const Symbol_table*, const Target*, Output_file*) const;
+ write_data(const Symbol_table*, Output_file*) const;
// Return an output section named NAME, or NULL if there is none.
Output_section*
// Create the output sections for the symbol table.
void
- create_symtab_sections(int size, const Input_objects*, Symbol_table*,
- off_t*);
+ create_symtab_sections(const Input_objects*, Symbol_table*, off_t*);
// Create the .shstrtab section.
Output_section*
// Create the section header table.
Output_section_headers*
- create_shdrs(int size, bool big_endian, off_t*);
+ create_shdrs(off_t*);
// Create the dynamic symbol table.
void
// Create the version sections.
void
- create_version_sections(const Target*, const Versions*,
+ create_version_sections(const Versions*,
unsigned int local_symcount,
const std::vector<Symbol*>& dynamic_symbols,
const Output_section* dynstr);
{
public:
Write_data_task(const Layout* layout, const Symbol_table* symtab,
- const Target* target, Output_file* of,
- Task_token* final_blocker)
- : layout_(layout), symtab_(symtab), target_(target), of_(of),
- final_blocker_(final_blocker)
+ Output_file* of, Task_token* final_blocker)
+ : layout_(layout), symtab_(symtab), of_(of), final_blocker_(final_blocker)
{ }
// The standard Task methods.
private:
const Layout* layout_;
const Symbol_table* symtab_;
- const Target* target_;
Output_file* of_;
Task_token* final_blocker_;
};
gold_exit(false);
}
+ set_parameters_size_and_endianness(target->get_size(),
+ target->is_big_endian());
+
return true;
}
// segment and section lists are complete at construction time.
Output_section_headers::Output_section_headers(
- int size,
- bool big_endian,
const Layout* layout,
const Layout::Segment_list* segment_list,
const Layout::Section_list* unattached_section_list,
const Stringpool* secnamepool)
- : size_(size),
- big_endian_(big_endian),
- layout_(layout),
+ : layout_(layout),
segment_list_(segment_list),
unattached_section_list_(unattached_section_list),
secnamepool_(secnamepool)
count += (*p)->output_section_count();
count += unattached_section_list->size();
+ const int size = parameters->get_size();
int shdr_size;
if (size == 32)
shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
void
Output_section_headers::do_write(Output_file* of)
{
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
- if (this->big_endian_)
- this->do_sized_write<32, true>(of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_32_BIG
+ this->do_sized_write<32, true>(of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->do_sized_write<32, false>(of);
+ {
+#ifdef HAVE_TARGET_32_LITTLE
+ this->do_sized_write<32, false>(of);
+#else
+ gold_unreachable();
+#endif
+ }
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
- if (this->big_endian_)
- this->do_sized_write<64, true>(of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_64_BIG
+ this->do_sized_write<64, true>(of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->do_sized_write<64, false>(of);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ this->do_sized_write<64, false>(of);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
// Output_segment_header methods.
Output_segment_headers::Output_segment_headers(
- int size,
- bool big_endian,
const Layout::Segment_list& segment_list)
- : size_(size), big_endian_(big_endian), segment_list_(segment_list)
+ : segment_list_(segment_list)
{
+ const int size = parameters->get_size();
int phdr_size;
if (size == 32)
phdr_size = elfcpp::Elf_sizes<32>::phdr_size;
void
Output_segment_headers::do_write(Output_file* of)
{
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
- if (this->big_endian_)
- this->do_sized_write<32, true>(of);
+ 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();
+#endif
+ }
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
- if (this->big_endian_)
- this->do_sized_write<64, true>(of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_64_BIG
+ this->do_sized_write<64, true>(of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->do_sized_write<64, false>(of);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ this->do_sized_write<64, false>(of);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
// Output_file_header methods.
-Output_file_header::Output_file_header(int size,
- bool big_endian,
- const Target* target,
+Output_file_header::Output_file_header(const Target* target,
const Symbol_table* symtab,
const Output_segment_headers* osh)
- : size_(size),
- big_endian_(big_endian),
- target_(target),
+ : target_(target),
symtab_(symtab),
segment_header_(osh),
section_header_(NULL),
shstrtab_(NULL)
{
+ const int size = parameters->get_size();
int ehdr_size;
if (size == 32)
ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size;
void
Output_file_header::do_write(Output_file* of)
{
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
- if (this->big_endian_)
- this->do_sized_write<32, true>(of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_32_BIG
+ this->do_sized_write<32, true>(of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->do_sized_write<32, false>(of);
+ {
+#ifdef HAVE_TARGET_32_LITTLE
+ this->do_sized_write<32, false>(of);
+#else
+ gold_unreachable();
+#endif
+ }
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
- if (this->big_endian_)
- this->do_sized_write<64, true>(of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_64_BIG
+ this->do_sized_write<64, true>(of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->do_sized_write<64, false>(of);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ this->do_sized_write<64, false>(of);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
void
Output_data_dynamic::do_adjust_output_section(Output_section* os)
{
- if (this->target_->get_size() == 32)
+ if (parameters->get_size() == 32)
os->set_entsize(elfcpp::Elf_sizes<32>::dyn_size);
- else if (this->target_->get_size() == 64)
+ else if (parameters->get_size() == 64)
os->set_entsize(elfcpp::Elf_sizes<64>::dyn_size);
else
gold_unreachable();
this->add_constant(elfcpp::DT_NULL, 0);
int dyn_size;
- if (this->target_->get_size() == 32)
+ if (parameters->get_size() == 32)
dyn_size = elfcpp::Elf_sizes<32>::dyn_size;
- else if (this->target_->get_size() == 64)
+ else if (parameters->get_size() == 64)
dyn_size = elfcpp::Elf_sizes<64>::dyn_size;
else
gold_unreachable();
void
Output_data_dynamic::do_write(Output_file* of)
{
- if (this->target_->get_size() == 32)
+ if (parameters->get_size() == 32)
{
- if (this->target_->is_big_endian())
- this->sized_write<32, true>(of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_32_BIG
+ this->sized_write<32, true>(of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->sized_write<32, false>(of);
+ {
+#ifdef HAVE_TARGET_32_LITTLE
+ this->sized_write<32, false>(of);
+#else
+ gold_unreachable();
+#endif
+ }
}
- else if (this->target_->get_size() == 64)
+ else if (parameters->get_size() == 64)
{
- if (this->target_->is_big_endian())
- this->sized_write<64, true>(of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_64_BIG
+ this->sized_write<64, true>(of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->sized_write<64, false>(of);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ this->sized_write<64, false>(of);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
#include "elfcpp.h"
#include "layout.h"
#include "reloc-types.h"
+#include "parameters.h"
namespace gold
{
class Output_section_headers : public Output_data
{
public:
- Output_section_headers(int size,
- bool big_endian,
- const Layout*,
+ Output_section_headers(const Layout*,
const Layout::Segment_list*,
const Layout::Section_list*,
const Stringpool*);
// Return the required alignment.
uint64_t
do_addralign() const
- { return Output_data::default_alignment(this->size_); }
+ { return Output_data::default_alignment(parameters->get_size()); }
private:
// Write the data to the file with the right size and endianness.
void
do_sized_write(Output_file*);
- int size_;
- bool big_endian_;
const Layout* layout_;
const Layout::Segment_list* segment_list_;
const Layout::Section_list* unattached_section_list_;
class Output_segment_headers : public Output_data
{
public:
- Output_segment_headers(int size, bool big_endian,
- const Layout::Segment_list& segment_list);
+ Output_segment_headers(const Layout::Segment_list& segment_list);
// Write the data to the file.
void
// Return the required alignment.
uint64_t
do_addralign() const
- { return Output_data::default_alignment(this->size_); }
+ { return Output_data::default_alignment(parameters->get_size()); }
private:
// Write the data to the file with the right size and endianness.
void
do_sized_write(Output_file*);
- int size_;
- bool big_endian_;
const Layout::Segment_list& segment_list_;
};
class Output_file_header : public Output_data
{
public:
- Output_file_header(int size,
- bool big_endian,
- const Target*,
+ Output_file_header(const Target*,
const Symbol_table*,
const Output_segment_headers*);
// Return the required alignment.
uint64_t
do_addralign() const
- { return Output_data::default_alignment(this->size_); }
+ { return Output_data::default_alignment(parameters->get_size()); }
// Set the address and offset--we only implement this for error
// checking.
void
do_sized_write(Output_file*);
- int size_;
- bool big_endian_;
const Target* target_;
const Symbol_table* symtab_;
const Output_segment_headers* segment_header_;
class Output_data_dynamic : public Output_section_data
{
public:
- Output_data_dynamic(const Target* target, Stringpool* pool)
- : Output_section_data(Output_data::default_alignment(target->get_size())),
- target_(target), entries_(), pool_(pool)
+ Output_data_dynamic(Stringpool* pool)
+ : Output_section_data(Output_data::default_alignment(
+ parameters->get_size())),
+ entries_(), pool_(pool)
{ }
// Add a new dynamic entry with a fixed numeric value.
// The type of the list of entries.
typedef std::vector<Dynamic_entry> Dynamic_entries;
- // The target.
- const Target* target_;
// The entries.
Dynamic_entries entries_;
// The pool used for strings.
// Initialize the parameters from the options.
Parameters::Parameters(const General_options* options)
- : optimization_level_(options->optimization_level())
+ : is_size_and_endian_valid_(false), size_(0), is_big_endian_(false),
+ optimization_level_(options->optimization_level())
{
if (options->is_shared())
this->output_file_type_ = OUTPUT_SHARED;
this->output_file_type_ = OUTPUT_EXECUTABLE;
}
+// Set the size and endianness.
+
+void
+Parameters::set_size_and_endianness(int size, bool is_big_endian)
+{
+ if (!this->is_size_and_endian_valid_)
+ {
+ this->size_ = size;
+ this->is_big_endian_ = is_big_endian;
+ this->is_size_and_endian_valid_ = true;
+ }
+ else
+ {
+ gold_assert(size == this->size_);
+ gold_assert(is_big_endian == this->is_big_endian_);
+ }
+}
+
+// Our local version of the variable, which is not const.
+
+static Parameters* static_parameters;
+
// The global variable.
const Parameters* parameters;
void
initialize_parameters(const General_options* options)
{
- parameters = new Parameters(options);
+ parameters = static_parameters = new Parameters(options);
+}
+
+void
+set_parameters_size_and_endianness(int size, bool is_big_endian)
+{
+ static_parameters->set_size_and_endianness(size, is_big_endian);
}
} // End namespace gold.
output_is_object() const
{ return this->output_file_type_ == OUTPUT_OBJECT; }
+ // The size of the output file we are generating. This should
+ // return 32 or 64.
+ int
+ get_size() const
+ {
+ gold_assert(this->is_size_and_endian_valid_);
+ return this->size_;
+ }
+
+ // Whether the output is big endian.
+ bool
+ is_big_endian() const
+ {
+ gold_assert(this->is_size_and_endian_valid_);
+ return this->is_big_endian_;
+ }
+
// The general linker optimization level.
int
optimization_level() const
{ return this->optimization_level_; }
+ // Set the size and endianness.
+ void
+ set_size_and_endianness(int size, bool is_big_endian);
+
private:
// The types of output files.
enum Output_file_type
// The type of the output file.
Output_file_type output_file_type_;
+ // Whether the size_ and is_big_endian_ fields are valid.
+ bool is_size_and_endian_valid_;
+ // The size of the output file--32 or 64.
+ int size_;
+ // Whether the output file is big endian.
+ bool is_big_endian_;
// The optimization level.
int optimization_level_;
};
// Initialize the global variable.
extern void initialize_parameters(const General_options*);
+// Set the size and endianness of the global parameters variable.
+extern void set_parameters_size_and_endianness(int size, bool is_big_endian);
+
} // End namespace gold.
#endif // !defined(GOLD_PARAMATERS_H)
// Class Symbol_table.
Symbol_table::Symbol_table()
- : size_(0), saw_undefined_(0), offset_(0), table_(), namepool_(),
+ : saw_undefined_(0), offset_(0), table_(), namepool_(),
forwarders_(), commons_(), warnings_()
{
}
size_t sym_name_size,
Symbol** sympointers)
{
- // We take the size from the first object we see.
- if (this->get_size() == 0)
- this->set_size(size);
-
- if (size != this->get_size() || size != relobj->target()->get_size())
- {
- fprintf(stderr, _("%s: %s: mixing 32-bit and 64-bit ELF objects\n"),
- program_name, relobj->name().c_str());
- gold_exit(false);
- }
+ gold_assert(size == relobj->target()->get_size());
+ gold_assert(size == parameters->get_size());
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
size_t versym_size,
const std::vector<const char*>* version_map)
{
- // We take the size from the first object we see.
- if (this->get_size() == 0)
- this->set_size(size);
-
- if (size != this->get_size() || size != dynobj->target()->get_size())
- {
- fprintf(stderr, _("%s: %s: mixing 32-bit and 64-bit ELF objects\n"),
- program_name, dynobj->name().c_str());
- gold_exit(false);
- }
+ gold_assert(size == dynobj->target()->get_size());
+ gold_assert(size == parameters->get_size());
if (versym != NULL && versym_size / 2 < count)
{
Sized_symbol<size>** poldsym
ACCEPT_SIZE_ENDIAN)
{
- gold_assert(this->size_ == size);
-
Symbol* oldsym;
Sized_symbol<size>* sym;
bool add_to_table = false;
bool offset_is_from_end,
bool only_if_ref)
{
- gold_assert(target->get_size() == this->size_);
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_in_output_data<32>(target, name, version, od,
gold_unreachable();
#endif
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_in_output_data<64>(target, name, version, od,
Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym;
- if (target->is_big_endian())
+ if (parameters->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) (
Symbol::Segment_offset_base offset_base,
bool only_if_ref)
{
- gold_assert(target->get_size() == this->size_);
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_in_output_segment<32>(target, name, version, os,
gold_unreachable();
#endif
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_in_output_segment<64>(target, name, version, os,
Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym;
- if (target->is_big_endian())
- sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
- target, &name, &version, only_if_ref, &oldsym
- SELECT_SIZE_ENDIAN(size, true));
+ if (parameters->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) (
+ target, &name, &version, only_if_ref, &oldsym
+ SELECT_SIZE_ENDIAN(size, true));
+#else
+ gold_unreachable();
+#endif
+ }
else
- sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
- target, &name, &version, only_if_ref, &oldsym
- SELECT_SIZE_ENDIAN(size, false));
+ {
+#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
+ sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
+ target, &name, &version, only_if_ref, &oldsym
+ SELECT_SIZE_ENDIAN(size, false));
+#else
+ gold_unreachable();
+#endif
+ }
if (sym == NULL)
return NULL;
elfcpp::STB binding, elfcpp::STV visibility,
unsigned char nonvis, bool only_if_ref)
{
- gold_assert(target->get_size() == this->size_);
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_as_constant<32>(target, name, version, value,
gold_unreachable();
#endif
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_as_constant<64>(target, name, version, value,
Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym;
- if (target->is_big_endian())
- sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
- target, &name, &version, only_if_ref, &oldsym
- SELECT_SIZE_ENDIAN(size, true));
+ if (parameters->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) (
+ target, &name, &version, only_if_ref, &oldsym
+ SELECT_SIZE_ENDIAN(size, true));
+#else
+ gold_unreachable();
+#endif
+ }
else
- sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
- target, &name, &version, only_if_ref, &oldsym
- SELECT_SIZE_ENDIAN(size, false));
+ {
+#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
+ sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
+ target, &name, &version, only_if_ref, &oldsym
+ SELECT_SIZE_ENDIAN(size, false));
+#else
+ gold_unreachable();
+#endif
+ }
if (sym == NULL)
return NULL;
this->first_dynamic_global_index_ = dyn_global_index;
this->dynamic_count_ = dyncount;
- if (this->size_ == 32)
- ret = this->sized_finalize<32>(index, off, pool);
- else if (this->size_ == 64)
- ret = this->sized_finalize<64>(index, off, pool);
+ if (parameters->get_size() == 32)
+ {
+#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_32_LITTLE)
+ ret = this->sized_finalize<32>(index, off, pool);
+#else
+ gold_unreachable();
+#endif
+ }
+ else if (parameters->get_size() == 64)
+ {
+#if defined(HAVE_TARGET_64_BIG) || defined(HAVE_TARGET_64_LITTLE)
+ ret = this->sized_finalize<64>(index, off, pool);
+#else
+ gold_unreachable();
+#endif
+ }
else
gold_unreachable();
Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
const Stringpool* dynpool, Output_file* of) const
{
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
- if (target->is_big_endian())
- this->sized_write_globals<32, true>(target, sympool, dynpool, of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_32_BIG
+ this->sized_write_globals<32, true>(target, sympool, dynpool, of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->sized_write_globals<32, false>(target, sympool, dynpool, of);
+ {
+#ifdef HAVE_TARGET_32_LITTLE
+ this->sized_write_globals<32, false>(target, sympool, dynpool, of);
+#else
+ gold_unreachable();
+#endif
+ }
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
- if (target->is_big_endian())
- this->sized_write_globals<64, true>(target, sympool, dynpool, of);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_64_BIG
+ this->sized_write_globals<64, true>(target, sympool, dynpool, of);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->sized_write_globals<64, false>(target, sympool, dynpool, of);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ this->sized_write_globals<64, false>(target, sympool, dynpool, of);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
// Write out a section symbol. Return the update offset.
void
-Symbol_table::write_section_symbol(const Target* target,
- const Output_section *os,
+Symbol_table::write_section_symbol(const Output_section *os,
Output_file* of,
off_t offset) const
{
- if (this->size_ == 32)
+ if (parameters->get_size() == 32)
{
- if (target->is_big_endian())
- this->sized_write_section_symbol<32, true>(os, of, offset);
+ 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
- this->sized_write_section_symbol<32, false>(os, of, offset);
+ {
+#ifdef HAVE_TARGET_32_LITTLE
+ this->sized_write_section_symbol<32, false>(os, of, offset);
+#else
+ gold_unreachable();
+#endif
+ }
}
- else if (this->size_ == 64)
+ else if (parameters->get_size() == 64)
{
- if (target->is_big_endian())
- this->sized_write_section_symbol<64, true>(os, of, offset);
+ if (parameters->is_big_endian())
+ {
+#ifdef HAVE_TARGET_64_BIG
+ this->sized_write_section_symbol<64, true>(os, of, offset);
+#else
+ gold_unreachable();
+#endif
+ }
else
- this->sized_write_section_symbol<64, false>(os, of, offset);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ this->sized_write_section_symbol<64, false>(os, of, offset);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
Symbol*
resolve_forwards(const Symbol* from) const;
- // Return the bitsize (32 or 64) of the symbols in the table.
- int
- get_size() const
- { return this->size_; }
-
// Return the sized version of a symbol in this table.
template<int size>
Sized_symbol<size>*
// Write out a section symbol. Return the updated offset.
void
- write_section_symbol(const Target*, const Output_section*, Output_file*,
- off_t) const;
+ write_section_symbol(const Output_section*, Output_file*, off_t) const;
private:
Symbol_table(const Symbol_table&);
Symbol_table& operator=(const Symbol_table&);
- // Set the size (32 or 64) of the symbols in the table.
- void
- set_size(int size)
- { this->size_ = size; }
-
// Make FROM a forwarder symbol to TO.
void
make_forwarder(Symbol* from, Symbol* to);
typedef std::vector<Symbol*> Commons_type;
- // The size of the symbols in the symbol table (32 or 64).
- int size_;
-
// We increment this every time we see a new undefined symbol, for
// use in archive groups.
int saw_undefined_;
Sized_symbol<size>*
Symbol_table::get_sized_symbol(Symbol* sym ACCEPT_SIZE) const
{
- gold_assert(size == this->get_size());
+ gold_assert(size == parameters->get_size());
return static_cast<Sized_symbol<size>*>(sym);
}
const Sized_symbol<size>*
Symbol_table::get_sized_symbol(const Symbol* sym ACCEPT_SIZE) const
{
- gold_assert(size == this->get_size());
+ gold_assert(size == parameters->get_size());
return static_cast<const Sized_symbol<size>*>(sym);
}