Put size and endianness in parameters.

This commit is contained in:
Ian Lance Taylor 2007-09-26 07:01:35 +00:00
parent cc941dee48
commit 9025d29d14
15 changed files with 450 additions and 244 deletions

View file

@ -135,7 +135,7 @@ Sort_commons<size>::operator()(const Symbol* pa, const Symbol* pb) const
void void
Symbol_table::allocate_commons(const General_options& options, Layout* layout) 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) #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
this->do_allocate_commons<32>(options, layout); this->do_allocate_commons<32>(options, layout);
@ -143,7 +143,7 @@ Symbol_table::allocate_commons(const General_options& options, Layout* layout)
gold_unreachable(); gold_unreachable();
#endif #endif
} }
else if (this->get_size() == 64) else if (parameters->get_size() == 64)
{ {
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
this->do_allocate_commons<64>(options, layout); this->do_allocate_commons<64>(options, layout);

View file

@ -740,8 +740,7 @@ Dynobj::elf_hash(const char* name)
// symbol table. // symbol table.
void void
Dynobj::create_elf_hash_table(const Target* target, Dynobj::create_elf_hash_table(const std::vector<Symbol*>& dynsyms,
const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count, unsigned int local_dynsym_count,
unsigned char** pphash, unsigned char** pphash,
unsigned int* phashlen) unsigned int* phashlen)
@ -774,10 +773,24 @@ Dynobj::create_elf_hash_table(const Target* target,
* 4); * 4);
unsigned char* phash = new unsigned char[hashlen]; unsigned char* phash = new unsigned char[hashlen];
if (target->is_big_endian()) if (parameters->is_big_endian())
Dynobj::sized_create_elf_hash_table<true>(bucket, chain, phash, hashlen); {
#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 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; *pphash = phash;
*phashlen = hashlen; *phashlen = hashlen;
@ -840,8 +853,7 @@ Dynobj::gnu_hash(const char* name)
// symbol table. // symbol table.
void void
Dynobj::create_gnu_hash_table(const Target* target, Dynobj::create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count, unsigned int local_dynsym_count,
unsigned char** pphash, unsigned char** pphash,
unsigned int* phashlen) unsigned int* phashlen)
@ -890,37 +902,61 @@ Dynobj::create_gnu_hash_table(const Target* target,
// For the actual data generation we call out to a templatized // For the actual data generation we call out to a templatized
// function. // function.
int size = target->get_size(); int size = parameters->get_size();
bool big_endian = target->is_big_endian(); bool big_endian = parameters->is_big_endian();
if (size == 32) if (size == 32)
{ {
if (big_endian) if (big_endian)
Dynobj::sized_create_gnu_hash_table<32, true>(hashed_dynsyms, {
dynsym_hashvals, #ifdef HAVE_TARGET_32_BIG
unhashed_dynsym_index, Dynobj::sized_create_gnu_hash_table<32, true>(hashed_dynsyms,
pphash, dynsym_hashvals,
phashlen); unhashed_dynsym_index,
pphash,
phashlen);
#else
gold_unreachable();
#endif
}
else else
Dynobj::sized_create_gnu_hash_table<32, false>(hashed_dynsyms, {
dynsym_hashvals, #ifdef HAVE_TARGET_32_LITTLE
unhashed_dynsym_index, Dynobj::sized_create_gnu_hash_table<32, false>(hashed_dynsyms,
pphash, dynsym_hashvals,
phashlen); unhashed_dynsym_index,
pphash,
phashlen);
#else
gold_unreachable();
#endif
}
} }
else if (size == 64) else if (size == 64)
{ {
if (big_endian) if (big_endian)
Dynobj::sized_create_gnu_hash_table<64, true>(hashed_dynsyms, {
dynsym_hashvals, #ifdef HAVE_TARGET_64_BIG
unhashed_dynsym_index, Dynobj::sized_create_gnu_hash_table<64, true>(hashed_dynsyms,
pphash, dynsym_hashvals,
phashlen); unhashed_dynsym_index,
pphash,
phashlen);
#else
gold_unreachable();
#endif
}
else else
Dynobj::sized_create_gnu_hash_table<64, false>(hashed_dynsyms, {
dynsym_hashvals, #ifdef HAVE_TARGET_64_LITTLE
unhashed_dynsym_index, Dynobj::sized_create_gnu_hash_table<64, false>(hashed_dynsyms,
pphash, dynsym_hashvals,
phashlen); unhashed_dynsym_index,
pphash,
phashlen);
#else
gold_unreachable();
#endif
}
} }
else else
gold_unreachable(); gold_unreachable();

View file

@ -56,7 +56,7 @@ class Dynobj : public Object
// number of local dynamic symbols, which is the index of the first // number of local dynamic symbols, which is the index of the first
// dynamic gobal symbol. // dynamic gobal symbol.
static void 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 int local_dynsym_count,
unsigned char** pphash, unsigned char** pphash,
unsigned int* phashlen); unsigned int* phashlen);
@ -66,7 +66,7 @@ class Dynobj : public Object
// of local dynamic symbols, which is the index of the first dynamic // of local dynamic symbols, which is the index of the first dynamic
// gobal symbol. // gobal symbol.
static void 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 int local_dynsym_count,
unsigned char** pphash, unsigned int* phashlen); unsigned char** pphash, unsigned int* phashlen);

View file

@ -75,10 +75,9 @@ const int eh_frame_hdr_size = 4;
// Construct the exception frame header. // Construct the exception frame header.
Eh_frame_hdr::Eh_frame_hdr(const Target* target, Eh_frame_hdr::Eh_frame_hdr(Output_section* eh_frame_section)
Output_section* eh_frame_section)
: Output_section_data(4), : Output_section_data(4),
target_(target), eh_frame_section_(eh_frame_section) eh_frame_section_(eh_frame_section)
{ {
} }
@ -109,7 +108,7 @@ Eh_frame_hdr::do_write(Output_file* of)
uint64_t eh_frame_hdr_address = this->address(); uint64_t eh_frame_hdr_address = this->address();
uint64_t eh_frame_offset = (eh_frame_address - uint64_t eh_frame_offset = (eh_frame_address -
(eh_frame_hdr_address + 4)); (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); elfcpp::Swap<32, true>::writeval(oview + 4, eh_frame_offset);
else else
elfcpp::Swap<32, false>::writeval(oview + 4, eh_frame_offset); elfcpp::Swap<32, false>::writeval(oview + 4, eh_frame_offset);

View file

@ -42,7 +42,7 @@ namespace gold
class Eh_frame_hdr : public Output_section_data class Eh_frame_hdr : public Output_section_data
{ {
public: public:
Eh_frame_hdr(const Target*, Output_section* eh_frame_section); Eh_frame_hdr(Output_section* eh_frame_section);
// Set the final data size. // Set the final data size.
void void
@ -53,8 +53,6 @@ class Eh_frame_hdr : public Output_section_data
do_write(Output_file*); do_write(Output_file*);
private: private:
// The output target.
const Target* target_;
// The .eh_frame section. // The .eh_frame section.
Output_section* eh_frame_section_; Output_section* eh_frame_section_;
}; };

View file

@ -250,9 +250,7 @@ queue_final_tasks(const General_options& options,
// Queue a task to write out everything else. // Queue a task to write out everything else.
final_blocker->add_blocker(); final_blocker->add_blocker();
workqueue->queue(new Write_data_task(layout, symtab, workqueue->queue(new Write_data_task(layout, symtab, of, final_blocker));
input_objects->target(),
of, final_blocker));
// Queue a task to close the output file. This will be blocked by // Queue a task to close the output file. This will be blocked by
// FINAL_BLOCKER. // FINAL_BLOCKER.

View file

@ -251,7 +251,7 @@ Layout::layout_eh_frame(Relobj* object,
elfcpp::SHT_PROGBITS, elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC); 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); hdr_os->add_output_section_data(hdr_posd);
Output_segment* hdr_oseg = Output_segment* hdr_oseg =
@ -404,8 +404,7 @@ Layout::create_initial_dynamic_sections(const Input_objects* input_objects,
elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL,
elfcpp::STV_HIDDEN, 0, false, false); elfcpp::STV_HIDDEN, 0, false, false);
this->dynamic_data_ = new Output_data_dynamic(input_objects->target(), this->dynamic_data_ = new Output_data_dynamic(&this->dynpool_);
&this->dynpool_);
this->dynamic_section_->add_output_section_data(this->dynamic_data_); this->dynamic_section_->add_output_section_data(this->dynamic_data_);
} }
@ -519,7 +518,6 @@ off_t
Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab) Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
{ {
Target* const target = input_objects->target(); Target* const target = input_objects->target();
const int size = target->get_size();
target->finalize_sections(this); target->finalize_sections(this);
@ -557,7 +555,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
// Create the version sections. We can't do this until the // Create the version sections. We can't do this until the
// dynamic string table is complete. // 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); dynamic_symbols, dynstr);
} }
@ -566,10 +564,8 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
Output_segment* load_seg = this->find_first_load_seg(); Output_segment* load_seg = this->find_first_load_seg();
// Lay out the segment headers. // Lay out the segment headers.
bool big_endian = target->is_big_endian();
Output_segment_headers* segment_headers; Output_segment_headers* segment_headers;
segment_headers = new Output_segment_headers(size, big_endian, segment_headers = new Output_segment_headers(this->segment_list_);
this->segment_list_);
load_seg->add_initial_output_data(segment_headers); load_seg->add_initial_output_data(segment_headers);
this->special_output_list_.push_back(segment_headers); this->special_output_list_.push_back(segment_headers);
if (phdr_seg != NULL) if (phdr_seg != NULL)
@ -577,11 +573,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
// Lay out the file header. // Lay out the file header.
Output_file_header* file_header; Output_file_header* file_header;
file_header = new Output_file_header(size, file_header = new Output_file_header(target, symtab, segment_headers);
big_endian,
target,
symtab,
segment_headers);
load_seg->add_initial_output_data(file_header); load_seg->add_initial_output_data(file_header);
this->special_output_list_.push_back(file_header); this->special_output_list_.push_back(file_header);
@ -594,7 +586,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
off_t off = this->set_segment_offsets(target, load_seg, &shndx); off_t off = this->set_segment_offsets(target, load_seg, &shndx);
// Create the symbol table sections. // 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. // Create the .shstrtab section.
Output_section* shstrtab_section = this->create_shstrtab(); Output_section* shstrtab_section = this->create_shstrtab();
@ -604,7 +596,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
off = this->set_section_offsets(off, &shndx); off = this->set_section_offsets(off, &shndx);
// Create the section table header. // 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); file_header->set_section_info(oshdrs, shstrtab_section);
@ -826,18 +818,18 @@ Layout::set_section_offsets(off_t off, unsigned int* pshndx)
// fully laid out. // fully laid out.
void void
Layout::create_symtab_sections(int size, const Input_objects* input_objects, Layout::create_symtab_sections(const Input_objects* input_objects,
Symbol_table* symtab, Symbol_table* symtab,
off_t* poff) off_t* poff)
{ {
int symsize; int symsize;
unsigned int align; unsigned int align;
if (size == 32) if (parameters->get_size() == 32)
{ {
symsize = elfcpp::Elf_sizes<32>::sym_size; symsize = elfcpp::Elf_sizes<32>::sym_size;
align = 4; align = 4;
} }
else if (size == 64) else if (parameters->get_size() == 64)
{ {
symsize = elfcpp::Elf_sizes<64>::sym_size; symsize = elfcpp::Elf_sizes<64>::sym_size;
align = 8; align = 8;
@ -960,10 +952,10 @@ Layout::create_shstrtab()
// offset. // offset.
Output_section_headers* Output_section_headers*
Layout::create_shdrs(int size, bool big_endian, off_t* poff) Layout::create_shdrs(off_t* poff)
{ {
Output_section_headers* oshdrs; Output_section_headers* oshdrs;
oshdrs = new Output_section_headers(size, big_endian, this, oshdrs = new Output_section_headers(this,
&this->segment_list_, &this->segment_list_,
&this->unattached_section_list_, &this->unattached_section_list_,
&this->namepool_); &this->namepool_);
@ -1020,7 +1012,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab,
int symsize; int symsize;
unsigned int align; unsigned int align;
const int size = target->get_size(); const int size = parameters->get_size();
if (size == 32) if (size == 32)
{ {
symsize = elfcpp::Elf_sizes<32>::sym_size; symsize = elfcpp::Elf_sizes<32>::sym_size;
@ -1079,7 +1071,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab,
unsigned char* phash; unsigned char* phash;
unsigned int hashlen; unsigned int hashlen;
Dynobj::create_elf_hash_table(target, *pdynamic_symbols, local_symcount, Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
&phash, &hashlen); &phash, &hashlen);
const char* hash_name = this->namepool_.add(".hash", NULL); const char* hash_name = this->namepool_.add(".hash", NULL);
@ -1101,7 +1093,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab,
// Create the version sections. // Create the version sections.
void void
Layout::create_version_sections(const Target* target, const Versions* versions, Layout::create_version_sections(const Versions* versions,
unsigned int local_symcount, unsigned int local_symcount,
const std::vector<Symbol*>& dynamic_symbols, const std::vector<Symbol*>& dynamic_symbols,
const Output_section* dynstr) const Output_section* dynstr)
@ -1109,9 +1101,9 @@ Layout::create_version_sections(const Target* target, const Versions* versions,
if (!versions->any_defs() && !versions->any_needs()) if (!versions->any_defs() && !versions->any_needs())
return; 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 #ifdef HAVE_TARGET_32_BIG
this->sized_create_version_sections this->sized_create_version_sections
@ -1134,9 +1126,9 @@ Layout::create_version_sections(const Target* target, const Versions* versions,
#endif #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 #ifdef HAVE_TARGET_64_BIG
this->sized_create_version_sections this->sized_create_version_sections
@ -1486,8 +1478,7 @@ Layout::add_comdat(const char* signature, bool group)
// Write out data not associated with a section or the symbol table. // Write out data not associated with a section or the symbol table.
void void
Layout::write_data(const Symbol_table* symtab, const Target* target, Layout::write_data(const Symbol_table* symtab, Output_file* of) const
Output_file* of) const
{ {
const Output_section* symtab_section = this->symtab_section_; const Output_section* symtab_section = this->symtab_section_;
for (Section_list::const_iterator p = this->section_list_.begin(); for (Section_list::const_iterator p = this->section_list_.begin();
@ -1501,7 +1492,7 @@ Layout::write_data(const Symbol_table* symtab, const Target* target,
gold_assert(index > 0 && index != -1U); gold_assert(index > 0 && index != -1U);
off_t off = (symtab_section->offset() off_t off = (symtab_section->offset()
+ index * symtab_section->entsize()); + index * symtab_section->entsize());
symtab->write_section_symbol(target, *p, of, off); symtab->write_section_symbol(*p, of, off);
} }
} }
@ -1517,7 +1508,7 @@ Layout::write_data(const Symbol_table* symtab, const Target* target,
gold_assert(index > 0 && index != -1U); gold_assert(index > 0 && index != -1U);
off_t off = (dynsym_section->offset() off_t off = (dynsym_section->offset()
+ index * dynsym_section->entsize()); + index * dynsym_section->entsize());
symtab->write_section_symbol(target, *p, of, off); symtab->write_section_symbol(*p, of, off);
} }
} }
@ -1560,7 +1551,7 @@ Write_data_task::locks(Workqueue* workqueue)
void void
Write_data_task::run(Workqueue*) 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_symbols_task methods.

View file

@ -167,7 +167,7 @@ class Layout
// Write out data not associated with an input file or the symbol // Write out data not associated with an input file or the symbol
// table. // table.
void 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. // Return an output section named NAME, or NULL if there is none.
Output_section* Output_section*
@ -220,8 +220,7 @@ class Layout
// Create the output sections for the symbol table. // Create the output sections for the symbol table.
void void
create_symtab_sections(int size, const Input_objects*, Symbol_table*, create_symtab_sections(const Input_objects*, Symbol_table*, off_t*);
off_t*);
// Create the .shstrtab section. // Create the .shstrtab section.
Output_section* Output_section*
@ -229,7 +228,7 @@ class Layout
// Create the section header table. // Create the section header table.
Output_section_headers* Output_section_headers*
create_shdrs(int size, bool big_endian, off_t*); create_shdrs(off_t*);
// Create the dynamic symbol table. // Create the dynamic symbol table.
void void
@ -248,7 +247,7 @@ class Layout
// Create the version sections. // Create the version sections.
void void
create_version_sections(const Target*, const Versions*, create_version_sections(const Versions*,
unsigned int local_symcount, unsigned int local_symcount,
const std::vector<Symbol*>& dynamic_symbols, const std::vector<Symbol*>& dynamic_symbols,
const Output_section* dynstr); const Output_section* dynstr);
@ -374,10 +373,8 @@ class Write_data_task : public Task
{ {
public: public:
Write_data_task(const Layout* layout, const Symbol_table* symtab, Write_data_task(const Layout* layout, const Symbol_table* symtab,
const Target* target, Output_file* of, Output_file* of, Task_token* final_blocker)
Task_token* final_blocker) : layout_(layout), symtab_(symtab), of_(of), final_blocker_(final_blocker)
: layout_(layout), symtab_(symtab), target_(target), of_(of),
final_blocker_(final_blocker)
{ } { }
// The standard Task methods. // The standard Task methods.
@ -394,7 +391,6 @@ class Write_data_task : public Task
private: private:
const Layout* layout_; const Layout* layout_;
const Symbol_table* symtab_; const Symbol_table* symtab_;
const Target* target_;
Output_file* of_; Output_file* of_;
Task_token* final_blocker_; Task_token* final_blocker_;
}; };

View file

@ -794,6 +794,9 @@ Input_objects::add_object(Object* obj)
gold_exit(false); gold_exit(false);
} }
set_parameters_size_and_endianness(target->get_size(),
target->is_big_endian());
return true; return true;
} }

View file

@ -78,15 +78,11 @@ Output_data::default_alignment(int size)
// segment and section lists are complete at construction time. // segment and section lists are complete at construction time.
Output_section_headers::Output_section_headers( Output_section_headers::Output_section_headers(
int size,
bool big_endian,
const Layout* layout, const Layout* layout,
const Layout::Segment_list* segment_list, const Layout::Segment_list* segment_list,
const Layout::Section_list* unattached_section_list, const Layout::Section_list* unattached_section_list,
const Stringpool* secnamepool) const Stringpool* secnamepool)
: size_(size), : layout_(layout),
big_endian_(big_endian),
layout_(layout),
segment_list_(segment_list), segment_list_(segment_list),
unattached_section_list_(unattached_section_list), unattached_section_list_(unattached_section_list),
secnamepool_(secnamepool) secnamepool_(secnamepool)
@ -100,6 +96,7 @@ Output_section_headers::Output_section_headers(
count += (*p)->output_section_count(); count += (*p)->output_section_count();
count += unattached_section_list->size(); count += unattached_section_list->size();
const int size = parameters->get_size();
int shdr_size; int shdr_size;
if (size == 32) if (size == 32)
shdr_size = elfcpp::Elf_sizes<32>::shdr_size; shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
@ -116,19 +113,43 @@ Output_section_headers::Output_section_headers(
void void
Output_section_headers::do_write(Output_file* of) Output_section_headers::do_write(Output_file* of)
{ {
if (this->size_ == 32) if (parameters->get_size() == 32)
{ {
if (this->big_endian_) if (parameters->is_big_endian())
this->do_sized_write<32, true>(of); {
#ifdef HAVE_TARGET_32_BIG
this->do_sized_write<32, true>(of);
#else
gold_unreachable();
#endif
}
else 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_) if (parameters->is_big_endian())
this->do_sized_write<64, true>(of); {
#ifdef HAVE_TARGET_64_BIG
this->do_sized_write<64, true>(of);
#else
gold_unreachable();
#endif
}
else 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 else
gold_unreachable(); gold_unreachable();
@ -185,11 +206,10 @@ Output_section_headers::do_sized_write(Output_file* of)
// Output_segment_header methods. // Output_segment_header methods.
Output_segment_headers::Output_segment_headers( Output_segment_headers::Output_segment_headers(
int size,
bool big_endian,
const Layout::Segment_list& segment_list) 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; int phdr_size;
if (size == 32) if (size == 32)
phdr_size = elfcpp::Elf_sizes<32>::phdr_size; phdr_size = elfcpp::Elf_sizes<32>::phdr_size;
@ -204,19 +224,43 @@ Output_segment_headers::Output_segment_headers(
void void
Output_segment_headers::do_write(Output_file* of) Output_segment_headers::do_write(Output_file* of)
{ {
if (this->size_ == 32) if (parameters->get_size() == 32)
{ {
if (this->big_endian_) if (parameters->is_big_endian())
this->do_sized_write<32, true>(of); {
#ifdef HAVE_TARGET_32_BIG
this->do_sized_write<32, true>(of);
#else
gold_unreachable();
#endif
}
else else
{
#ifdef HAVE_TARGET_32_LITTLE
this->do_sized_write<32, false>(of); 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_) if (parameters->is_big_endian())
this->do_sized_write<64, true>(of); {
#ifdef HAVE_TARGET_64_BIG
this->do_sized_write<64, true>(of);
#else
gold_unreachable();
#endif
}
else 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 else
gold_unreachable(); gold_unreachable();
@ -245,19 +289,16 @@ Output_segment_headers::do_sized_write(Output_file* of)
// Output_file_header methods. // Output_file_header methods.
Output_file_header::Output_file_header(int size, Output_file_header::Output_file_header(const Target* target,
bool big_endian,
const Target* target,
const Symbol_table* symtab, const Symbol_table* symtab,
const Output_segment_headers* osh) const Output_segment_headers* osh)
: size_(size), : target_(target),
big_endian_(big_endian),
target_(target),
symtab_(symtab), symtab_(symtab),
segment_header_(osh), segment_header_(osh),
section_header_(NULL), section_header_(NULL),
shstrtab_(NULL) shstrtab_(NULL)
{ {
const int size = parameters->get_size();
int ehdr_size; int ehdr_size;
if (size == 32) if (size == 32)
ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size; ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size;
@ -284,19 +325,43 @@ Output_file_header::set_section_info(const Output_section_headers* shdrs,
void void
Output_file_header::do_write(Output_file* of) Output_file_header::do_write(Output_file* of)
{ {
if (this->size_ == 32) if (parameters->get_size() == 32)
{ {
if (this->big_endian_) if (parameters->is_big_endian())
this->do_sized_write<32, true>(of); {
#ifdef HAVE_TARGET_32_BIG
this->do_sized_write<32, true>(of);
#else
gold_unreachable();
#endif
}
else 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_) if (parameters->is_big_endian())
this->do_sized_write<64, true>(of); {
#ifdef HAVE_TARGET_64_BIG
this->do_sized_write<64, true>(of);
#else
gold_unreachable();
#endif
}
else 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 else
gold_unreachable(); gold_unreachable();
@ -722,9 +787,9 @@ Output_data_dynamic::Dynamic_entry::write(
void void
Output_data_dynamic::do_adjust_output_section(Output_section* os) 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); 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); os->set_entsize(elfcpp::Elf_sizes<64>::dyn_size);
else else
gold_unreachable(); gold_unreachable();
@ -739,9 +804,9 @@ Output_data_dynamic::do_set_address(uint64_t, off_t)
this->add_constant(elfcpp::DT_NULL, 0); this->add_constant(elfcpp::DT_NULL, 0);
int dyn_size; int dyn_size;
if (this->target_->get_size() == 32) if (parameters->get_size() == 32)
dyn_size = elfcpp::Elf_sizes<32>::dyn_size; 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; dyn_size = elfcpp::Elf_sizes<64>::dyn_size;
else else
gold_unreachable(); gold_unreachable();
@ -753,19 +818,43 @@ Output_data_dynamic::do_set_address(uint64_t, off_t)
void void
Output_data_dynamic::do_write(Output_file* of) 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()) if (parameters->is_big_endian())
this->sized_write<32, true>(of); {
#ifdef HAVE_TARGET_32_BIG
this->sized_write<32, true>(of);
#else
gold_unreachable();
#endif
}
else 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()) if (parameters->is_big_endian())
this->sized_write<64, true>(of); {
#ifdef HAVE_TARGET_64_BIG
this->sized_write<64, true>(of);
#else
gold_unreachable();
#endif
}
else else
this->sized_write<64, false>(of); {
#ifdef HAVE_TARGET_64_LITTLE
this->sized_write<64, false>(of);
#else
gold_unreachable();
#endif
}
} }
else else
gold_unreachable(); gold_unreachable();

View file

@ -29,6 +29,7 @@
#include "elfcpp.h" #include "elfcpp.h"
#include "layout.h" #include "layout.h"
#include "reloc-types.h" #include "reloc-types.h"
#include "parameters.h"
namespace gold namespace gold
{ {
@ -203,9 +204,7 @@ class Output_data
class Output_section_headers : public Output_data class Output_section_headers : public Output_data
{ {
public: public:
Output_section_headers(int size, Output_section_headers(const Layout*,
bool big_endian,
const Layout*,
const Layout::Segment_list*, const Layout::Segment_list*,
const Layout::Section_list*, const Layout::Section_list*,
const Stringpool*); const Stringpool*);
@ -217,7 +216,7 @@ class Output_section_headers : public Output_data
// Return the required alignment. // Return the required alignment.
uint64_t uint64_t
do_addralign() const do_addralign() const
{ return Output_data::default_alignment(this->size_); } { return Output_data::default_alignment(parameters->get_size()); }
private: private:
// Write the data to the file with the right size and endianness. // Write the data to the file with the right size and endianness.
@ -225,8 +224,6 @@ class Output_section_headers : public Output_data
void void
do_sized_write(Output_file*); do_sized_write(Output_file*);
int size_;
bool big_endian_;
const Layout* layout_; const Layout* layout_;
const Layout::Segment_list* segment_list_; const Layout::Segment_list* segment_list_;
const Layout::Section_list* unattached_section_list_; const Layout::Section_list* unattached_section_list_;
@ -238,8 +235,7 @@ class Output_section_headers : public Output_data
class Output_segment_headers : public Output_data class Output_segment_headers : public Output_data
{ {
public: public:
Output_segment_headers(int size, bool big_endian, Output_segment_headers(const Layout::Segment_list& segment_list);
const Layout::Segment_list& segment_list);
// Write the data to the file. // Write the data to the file.
void void
@ -248,7 +244,7 @@ class Output_segment_headers : public Output_data
// Return the required alignment. // Return the required alignment.
uint64_t uint64_t
do_addralign() const do_addralign() const
{ return Output_data::default_alignment(this->size_); } { return Output_data::default_alignment(parameters->get_size()); }
private: private:
// Write the data to the file with the right size and endianness. // Write the data to the file with the right size and endianness.
@ -256,8 +252,6 @@ class Output_segment_headers : public Output_data
void void
do_sized_write(Output_file*); do_sized_write(Output_file*);
int size_;
bool big_endian_;
const Layout::Segment_list& segment_list_; const Layout::Segment_list& segment_list_;
}; };
@ -266,9 +260,7 @@ class Output_segment_headers : public Output_data
class Output_file_header : public Output_data class Output_file_header : public Output_data
{ {
public: public:
Output_file_header(int size, Output_file_header(const Target*,
bool big_endian,
const Target*,
const Symbol_table*, const Symbol_table*,
const Output_segment_headers*); const Output_segment_headers*);
@ -284,7 +276,7 @@ class Output_file_header : public Output_data
// Return the required alignment. // Return the required alignment.
uint64_t uint64_t
do_addralign() const 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 // Set the address and offset--we only implement this for error
// checking. // checking.
@ -298,8 +290,6 @@ class Output_file_header : public Output_data
void void
do_sized_write(Output_file*); do_sized_write(Output_file*);
int size_;
bool big_endian_;
const Target* target_; const Target* target_;
const Symbol_table* symtab_; const Symbol_table* symtab_;
const Output_segment_headers* segment_header_; const Output_segment_headers* segment_header_;
@ -1025,9 +1015,10 @@ class Output_data_got : public Output_section_data
class Output_data_dynamic : public Output_section_data class Output_data_dynamic : public Output_section_data
{ {
public: public:
Output_data_dynamic(const Target* target, Stringpool* pool) Output_data_dynamic(Stringpool* pool)
: Output_section_data(Output_data::default_alignment(target->get_size())), : Output_section_data(Output_data::default_alignment(
target_(target), entries_(), pool_(pool) parameters->get_size())),
entries_(), pool_(pool)
{ } { }
// Add a new dynamic entry with a fixed numeric value. // Add a new dynamic entry with a fixed numeric value.
@ -1150,8 +1141,6 @@ class Output_data_dynamic : public Output_section_data
// The type of the list of entries. // The type of the list of entries.
typedef std::vector<Dynamic_entry> Dynamic_entries; typedef std::vector<Dynamic_entry> Dynamic_entries;
// The target.
const Target* target_;
// The entries. // The entries.
Dynamic_entries entries_; Dynamic_entries entries_;
// The pool used for strings. // The pool used for strings.

View file

@ -31,7 +31,8 @@ namespace gold
// Initialize the parameters from the options. // Initialize the parameters from the options.
Parameters::Parameters(const General_options* 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()) if (options->is_shared())
this->output_file_type_ = OUTPUT_SHARED; this->output_file_type_ = OUTPUT_SHARED;
@ -41,6 +42,28 @@ Parameters::Parameters(const General_options* options)
this->output_file_type_ = OUTPUT_EXECUTABLE; 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. // The global variable.
const Parameters* parameters; const Parameters* parameters;
@ -50,7 +73,13 @@ const Parameters* parameters;
void void
initialize_parameters(const General_options* options) 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. } // End namespace gold.

View file

@ -56,11 +56,32 @@ class Parameters
output_is_object() const output_is_object() const
{ return this->output_file_type_ == OUTPUT_OBJECT; } { 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. // The general linker optimization level.
int int
optimization_level() const optimization_level() const
{ return this->optimization_level_; } { return this->optimization_level_; }
// Set the size and endianness.
void
set_size_and_endianness(int size, bool is_big_endian);
private: private:
// The types of output files. // The types of output files.
enum Output_file_type enum Output_file_type
@ -75,6 +96,12 @@ class Parameters
// The type of the output file. // The type of the output file.
Output_file_type output_file_type_; 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. // The optimization level.
int optimization_level_; int optimization_level_;
}; };
@ -85,6 +112,9 @@ extern const Parameters* parameters;
// Initialize the global variable. // Initialize the global variable.
extern void initialize_parameters(const General_options*); 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. } // End namespace gold.
#endif // !defined(GOLD_PARAMATERS_H) #endif // !defined(GOLD_PARAMATERS_H)

View file

@ -190,7 +190,7 @@ Sized_symbol<size>::init(const char* name, Value_type value, Size_type symsize,
// Class Symbol_table. // Class Symbol_table.
Symbol_table::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_() forwarders_(), commons_(), warnings_()
{ {
} }
@ -467,16 +467,8 @@ Symbol_table::add_from_relobj(
size_t sym_name_size, size_t sym_name_size,
Symbol** sympointers) Symbol** sympointers)
{ {
// We take the size from the first object we see. gold_assert(size == relobj->target()->get_size());
if (this->get_size() == 0) gold_assert(size == parameters->get_size());
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);
}
const int sym_size = elfcpp::Elf_sizes<size>::sym_size; const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
@ -564,16 +556,8 @@ Symbol_table::add_from_dynobj(
size_t versym_size, size_t versym_size,
const std::vector<const char*>* version_map) const std::vector<const char*>* version_map)
{ {
// We take the size from the first object we see. gold_assert(size == dynobj->target()->get_size());
if (this->get_size() == 0) gold_assert(size == parameters->get_size());
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);
}
if (versym != NULL && versym_size / 2 < count) if (versym != NULL && versym_size / 2 < count)
{ {
@ -696,8 +680,6 @@ Symbol_table::define_special_symbol(const Target* target, const char** pname,
Sized_symbol<size>** poldsym Sized_symbol<size>** poldsym
ACCEPT_SIZE_ENDIAN) ACCEPT_SIZE_ENDIAN)
{ {
gold_assert(this->size_ == size);
Symbol* oldsym; Symbol* oldsym;
Sized_symbol<size>* sym; Sized_symbol<size>* sym;
bool add_to_table = false; bool add_to_table = false;
@ -781,8 +763,7 @@ Symbol_table::define_in_output_data(const Target* target, const char* name,
bool offset_is_from_end, bool offset_is_from_end,
bool only_if_ref) bool only_if_ref)
{ {
gold_assert(target->get_size() == this->size_); if (parameters->get_size() == 32)
if (this->size_ == 32)
{ {
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_in_output_data<32>(target, name, version, od, return this->do_define_in_output_data<32>(target, name, version, od,
@ -794,7 +775,7 @@ Symbol_table::define_in_output_data(const Target* target, const char* name,
gold_unreachable(); gold_unreachable();
#endif #endif
} }
else if (this->size_ == 64) else if (parameters->get_size() == 64)
{ {
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_in_output_data<64>(target, name, version, od, return this->do_define_in_output_data<64>(target, name, version, od,
@ -831,7 +812,7 @@ Symbol_table::do_define_in_output_data(
Sized_symbol<size>* sym; Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym; 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) #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) ( sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
@ -878,8 +859,7 @@ Symbol_table::define_in_output_segment(const Target* target, const char* name,
Symbol::Segment_offset_base offset_base, Symbol::Segment_offset_base offset_base,
bool only_if_ref) bool only_if_ref)
{ {
gold_assert(target->get_size() == this->size_); if (parameters->get_size() == 32)
if (this->size_ == 32)
{ {
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_in_output_segment<32>(target, name, version, os, return this->do_define_in_output_segment<32>(target, name, version, os,
@ -890,7 +870,7 @@ Symbol_table::define_in_output_segment(const Target* target, const char* name,
gold_unreachable(); gold_unreachable();
#endif #endif
} }
else if (this->size_ == 64) else if (parameters->get_size() == 64)
{ {
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_in_output_segment<64>(target, name, version, os, return this->do_define_in_output_segment<64>(target, name, version, os,
@ -926,14 +906,26 @@ Symbol_table::do_define_in_output_segment(
Sized_symbol<size>* sym; Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym; Sized_symbol<size>* oldsym;
if (target->is_big_endian()) if (parameters->is_big_endian())
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) ( {
target, &name, &version, only_if_ref, &oldsym #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
SELECT_SIZE_ENDIAN(size, true)); 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 else
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) ( {
target, &name, &version, only_if_ref, &oldsym #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
SELECT_SIZE_ENDIAN(size, false)); 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) if (sym == NULL)
return NULL; return NULL;
@ -959,8 +951,7 @@ Symbol_table::define_as_constant(const Target* target, const char* name,
elfcpp::STB binding, elfcpp::STV visibility, elfcpp::STB binding, elfcpp::STV visibility,
unsigned char nonvis, bool only_if_ref) unsigned char nonvis, bool only_if_ref)
{ {
gold_assert(target->get_size() == this->size_); if (parameters->get_size() == 32)
if (this->size_ == 32)
{ {
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_as_constant<32>(target, name, version, value, return this->do_define_as_constant<32>(target, name, version, value,
@ -970,7 +961,7 @@ Symbol_table::define_as_constant(const Target* target, const char* name,
gold_unreachable(); gold_unreachable();
#endif #endif
} }
else if (this->size_ == 64) else if (parameters->get_size() == 64)
{ {
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_as_constant<64>(target, name, version, value, return this->do_define_as_constant<64>(target, name, version, value,
@ -1003,14 +994,26 @@ Symbol_table::do_define_as_constant(
Sized_symbol<size>* sym; Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym; Sized_symbol<size>* oldsym;
if (target->is_big_endian()) if (parameters->is_big_endian())
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) ( {
target, &name, &version, only_if_ref, &oldsym #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
SELECT_SIZE_ENDIAN(size, true)); 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 else
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) ( {
target, &name, &version, only_if_ref, &oldsym #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
SELECT_SIZE_ENDIAN(size, false)); 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) if (sym == NULL)
return NULL; return NULL;
@ -1135,10 +1138,22 @@ Symbol_table::finalize(unsigned int index, off_t off, off_t dynoff,
this->first_dynamic_global_index_ = dyn_global_index; this->first_dynamic_global_index_ = dyn_global_index;
this->dynamic_count_ = dyncount; this->dynamic_count_ = dyncount;
if (this->size_ == 32) if (parameters->get_size() == 32)
ret = this->sized_finalize<32>(index, off, pool); {
else if (this->size_ == 64) #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_32_LITTLE)
ret = this->sized_finalize<64>(index, off, pool); 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 else
gold_unreachable(); gold_unreachable();
@ -1285,19 +1300,43 @@ void
Symbol_table::write_globals(const Target* target, const Stringpool* sympool, Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
const Stringpool* dynpool, Output_file* of) const const Stringpool* dynpool, Output_file* of) const
{ {
if (this->size_ == 32) if (parameters->get_size() == 32)
{ {
if (target->is_big_endian()) if (parameters->is_big_endian())
this->sized_write_globals<32, true>(target, sympool, dynpool, of); {
#ifdef HAVE_TARGET_32_BIG
this->sized_write_globals<32, true>(target, sympool, dynpool, of);
#else
gold_unreachable();
#endif
}
else 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()) if (parameters->is_big_endian())
this->sized_write_globals<64, true>(target, sympool, dynpool, of); {
#ifdef HAVE_TARGET_64_BIG
this->sized_write_globals<64, true>(target, sympool, dynpool, of);
#else
gold_unreachable();
#endif
}
else 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 else
gold_unreachable(); gold_unreachable();
@ -1463,24 +1502,47 @@ Symbol_table::sized_write_symbol(
// Write out a section symbol. Return the update offset. // Write out a section symbol. Return the update offset.
void void
Symbol_table::write_section_symbol(const Target* target, Symbol_table::write_section_symbol(const Output_section *os,
const Output_section *os,
Output_file* of, Output_file* of,
off_t offset) const off_t offset) const
{ {
if (this->size_ == 32) if (parameters->get_size() == 32)
{ {
if (target->is_big_endian()) if (parameters->is_big_endian())
this->sized_write_section_symbol<32, true>(os, of, offset); {
#ifdef HAVE_TARGET_32_BIG
this->sized_write_section_symbol<32, true>(os, of, offset);
#else
gold_unreachable();
#endif
}
else 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()) if (parameters->is_big_endian())
this->sized_write_section_symbol<64, true>(os, of, offset); {
#ifdef HAVE_TARGET_64_BIG
this->sized_write_section_symbol<64, true>(os, of, offset);
#else
gold_unreachable();
#endif
}
else 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 else
gold_unreachable(); gold_unreachable();

View file

@ -851,11 +851,6 @@ class Symbol_table
Symbol* Symbol*
resolve_forwards(const Symbol* from) const; 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. // Return the sized version of a symbol in this table.
template<int size> template<int size>
Sized_symbol<size>* Sized_symbol<size>*
@ -917,18 +912,12 @@ class Symbol_table
// Write out a section symbol. Return the updated offset. // Write out a section symbol. Return the updated offset.
void void
write_section_symbol(const Target*, const Output_section*, Output_file*, write_section_symbol(const Output_section*, Output_file*, off_t) const;
off_t) const;
private: private:
Symbol_table(const Symbol_table&); Symbol_table(const Symbol_table&);
Symbol_table& operator=(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. // Make FROM a forwarder symbol to TO.
void void
make_forwarder(Symbol* from, Symbol* to); make_forwarder(Symbol* from, Symbol* to);
@ -1055,9 +1044,6 @@ class Symbol_table
typedef std::vector<Symbol*> Commons_type; 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 // We increment this every time we see a new undefined symbol, for
// use in archive groups. // use in archive groups.
int saw_undefined_; int saw_undefined_;
@ -1108,7 +1094,7 @@ template<int size>
Sized_symbol<size>* Sized_symbol<size>*
Symbol_table::get_sized_symbol(Symbol* sym ACCEPT_SIZE) const 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); return static_cast<Sized_symbol<size>*>(sym);
} }
@ -1116,7 +1102,7 @@ template<int size>
const Sized_symbol<size>* const Sized_symbol<size>*
Symbol_table::get_sized_symbol(const Symbol* sym ACCEPT_SIZE) const 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); return static_cast<const Sized_symbol<size>*>(sym);
} }