From 9025d29d14ae287d2bc338ef1b0bfa043799e15c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 26 Sep 2007 07:01:35 +0000 Subject: [PATCH] Put size and endianness in parameters. --- gold/common.cc | 4 +- gold/dynobj.cc | 94 +++++++++++++++++-------- gold/dynobj.h | 4 +- gold/ehframe.cc | 7 +- gold/ehframe.h | 4 +- gold/gold.cc | 4 +- gold/layout.cc | 55 ++++++--------- gold/layout.h | 16 ++--- gold/object.cc | 3 + gold/output.cc | 187 ++++++++++++++++++++++++++++++++++++------------- gold/output.h | 33 +++------ gold/parameters.cc | 33 ++++++++- gold/parameters.h | 30 ++++++++ gold/symtab.cc | 200 +++++++++++++++++++++++++++++++++++------------------ gold/symtab.h | 20 +----- 15 files changed, 450 insertions(+), 244 deletions(-) diff --git a/gold/common.cc b/gold/common.cc index e2e9f9f..f723de3 100644 --- a/gold/common.cc +++ b/gold/common.cc @@ -135,7 +135,7 @@ Sort_commons::operator()(const Symbol* pa, const Symbol* pb) const 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); @@ -143,7 +143,7 @@ Symbol_table::allocate_commons(const General_options& options, Layout* 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); diff --git a/gold/dynobj.cc b/gold/dynobj.cc index 2ccb8f5..09e7126 100644 --- a/gold/dynobj.cc +++ b/gold/dynobj.cc @@ -740,8 +740,7 @@ Dynobj::elf_hash(const char* name) // symbol table. void -Dynobj::create_elf_hash_table(const Target* target, - const std::vector& dynsyms, +Dynobj::create_elf_hash_table(const std::vector& dynsyms, unsigned int local_dynsym_count, unsigned char** pphash, unsigned int* phashlen) @@ -774,10 +773,24 @@ Dynobj::create_elf_hash_table(const Target* target, * 4); unsigned char* phash = new unsigned char[hashlen]; - if (target->is_big_endian()) - Dynobj::sized_create_elf_hash_table(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(bucket, chain, phash, + hashlen); +#else + gold_unreachable(); +#endif + } else - Dynobj::sized_create_elf_hash_table(bucket, chain, phash, hashlen); + { +#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) + Dynobj::sized_create_elf_hash_table(bucket, chain, phash, + hashlen); +#else + gold_unreachable(); +#endif + } *pphash = phash; *phashlen = hashlen; @@ -840,8 +853,7 @@ Dynobj::gnu_hash(const char* name) // symbol table. void -Dynobj::create_gnu_hash_table(const Target* target, - const std::vector& dynsyms, +Dynobj::create_gnu_hash_table(const std::vector& dynsyms, unsigned int local_dynsym_count, unsigned char** pphash, 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 // 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(); diff --git a/gold/dynobj.h b/gold/dynobj.h index 189bf68..e6b0a52 100644 --- a/gold/dynobj.h +++ b/gold/dynobj.h @@ -56,7 +56,7 @@ class Dynobj : public Object // 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& dynsyms, + create_elf_hash_table(const std::vector& dynsyms, unsigned int local_dynsym_count, unsigned char** pphash, unsigned int* phashlen); @@ -66,7 +66,7 @@ class Dynobj : public Object // 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& dynsyms, + create_gnu_hash_table(const std::vector& dynsyms, unsigned int local_dynsym_count, unsigned char** pphash, unsigned int* phashlen); diff --git a/gold/ehframe.cc b/gold/ehframe.cc index 1e0583a..607654b 100644 --- a/gold/ehframe.cc +++ b/gold/ehframe.cc @@ -75,10 +75,9 @@ const int eh_frame_hdr_size = 4; // 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) { } @@ -109,7 +108,7 @@ Eh_frame_hdr::do_write(Output_file* of) 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); diff --git a/gold/ehframe.h b/gold/ehframe.h index 1f6c022..0641ac8 100644 --- a/gold/ehframe.h +++ b/gold/ehframe.h @@ -42,7 +42,7 @@ namespace gold 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 @@ -53,8 +53,6 @@ class Eh_frame_hdr : public Output_section_data do_write(Output_file*); private: - // The output target. - const Target* target_; // The .eh_frame section. Output_section* eh_frame_section_; }; diff --git a/gold/gold.cc b/gold/gold.cc index a73cadb..7d01a81 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -250,9 +250,7 @@ queue_final_tasks(const General_options& options, // 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. diff --git a/gold/layout.cc b/gold/layout.cc index a05ebf1..83c8c6a 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -251,7 +251,7 @@ Layout::layout_eh_frame(Relobj* object, 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 = @@ -404,8 +404,7 @@ Layout::create_initial_dynamic_sections(const Input_objects* input_objects, 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_); } @@ -519,7 +518,6 @@ off_t 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); @@ -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 // 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); } @@ -566,10 +564,8 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab) 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) @@ -577,11 +573,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab) // 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); @@ -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); // 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(); @@ -604,7 +596,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab) 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); @@ -826,18 +818,18 @@ Layout::set_section_offsets(off_t off, unsigned int* pshndx) // 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; @@ -960,10 +952,10 @@ Layout::create_shstrtab() // 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_); @@ -1020,7 +1012,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab, 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; @@ -1079,7 +1071,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab, 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); @@ -1101,7 +1093,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab, // 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& dynamic_symbols, 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()) 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 @@ -1134,9 +1126,9 @@ Layout::create_version_sections(const Target* target, const Versions* versions, #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 @@ -1486,8 +1478,7 @@ Layout::add_comdat(const char* signature, bool group) // 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(); @@ -1501,7 +1492,7 @@ Layout::write_data(const Symbol_table* symtab, const Target* target, 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); } } @@ -1517,7 +1508,7 @@ Layout::write_data(const Symbol_table* symtab, const Target* target, 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); } } @@ -1560,7 +1551,7 @@ Write_data_task::locks(Workqueue* workqueue) 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. diff --git a/gold/layout.h b/gold/layout.h index 609de50..3e09d62 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -167,7 +167,7 @@ class Layout // 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* @@ -220,8 +220,7 @@ class Layout // 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* @@ -229,7 +228,7 @@ class Layout // 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 @@ -248,7 +247,7 @@ class Layout // Create the version sections. void - create_version_sections(const Target*, const Versions*, + create_version_sections(const Versions*, unsigned int local_symcount, const std::vector& dynamic_symbols, const Output_section* dynstr); @@ -374,10 +373,8 @@ class Write_data_task : public Task { 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. @@ -394,7 +391,6 @@ class Write_data_task : public Task private: const Layout* layout_; const Symbol_table* symtab_; - const Target* target_; Output_file* of_; Task_token* final_blocker_; }; diff --git a/gold/object.cc b/gold/object.cc index d64e120..3051909 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -794,6 +794,9 @@ Input_objects::add_object(Object* obj) gold_exit(false); } + set_parameters_size_and_endianness(target->get_size(), + target->is_big_endian()); + return true; } diff --git a/gold/output.cc b/gold/output.cc index 6d782e2..34fdc67 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -78,15 +78,11 @@ Output_data::default_alignment(int size) // 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) @@ -100,6 +96,7 @@ Output_section_headers::Output_section_headers( 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; @@ -116,19 +113,43 @@ Output_section_headers::Output_section_headers( 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(); @@ -185,11 +206,10 @@ Output_section_headers::do_sized_write(Output_file* of) // 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; @@ -204,19 +224,43 @@ Output_segment_headers::Output_segment_headers( 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(); @@ -245,19 +289,16 @@ Output_segment_headers::do_sized_write(Output_file* of) // 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; @@ -284,19 +325,43 @@ Output_file_header::set_section_info(const Output_section_headers* shdrs, 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(); @@ -722,9 +787,9 @@ Output_data_dynamic::Dynamic_entry::write( 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(); @@ -739,9 +804,9 @@ Output_data_dynamic::do_set_address(uint64_t, off_t) 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(); @@ -753,19 +818,43 @@ Output_data_dynamic::do_set_address(uint64_t, off_t) 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(); diff --git a/gold/output.h b/gold/output.h index 195aee7..7f783d6 100644 --- a/gold/output.h +++ b/gold/output.h @@ -29,6 +29,7 @@ #include "elfcpp.h" #include "layout.h" #include "reloc-types.h" +#include "parameters.h" namespace gold { @@ -203,9 +204,7 @@ class Output_data 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*); @@ -217,7 +216,7 @@ class Output_section_headers : public Output_data // 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. @@ -225,8 +224,6 @@ class Output_section_headers : public Output_data 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_; @@ -238,8 +235,7 @@ class Output_section_headers : public Output_data 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 @@ -248,7 +244,7 @@ class Output_segment_headers : public Output_data // 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. @@ -256,8 +252,6 @@ class Output_segment_headers : public Output_data void do_sized_write(Output_file*); - int size_; - bool big_endian_; const Layout::Segment_list& segment_list_; }; @@ -266,9 +260,7 @@ class Output_segment_headers : public Output_data 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*); @@ -284,7 +276,7 @@ class Output_file_header : public Output_data // 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. @@ -298,8 +290,6 @@ class Output_file_header : public Output_data void do_sized_write(Output_file*); - int size_; - bool big_endian_; const Target* target_; const Symbol_table* symtab_; 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 { 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. @@ -1150,8 +1141,6 @@ class Output_data_dynamic : public Output_section_data // The type of the list of entries. typedef std::vector Dynamic_entries; - // The target. - const Target* target_; // The entries. Dynamic_entries entries_; // The pool used for strings. diff --git a/gold/parameters.cc b/gold/parameters.cc index 462eeea..db377f8 100644 --- a/gold/parameters.cc +++ b/gold/parameters.cc @@ -31,7 +31,8 @@ namespace gold // Initialize the parameters from the options. Parameters::Parameters(const General_options* options) - : 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; @@ -41,6 +42,28 @@ Parameters::Parameters(const General_options* options) 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; @@ -50,7 +73,13 @@ 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. diff --git a/gold/parameters.h b/gold/parameters.h index cfbf953..fafd345 100644 --- a/gold/parameters.h +++ b/gold/parameters.h @@ -56,11 +56,32 @@ class Parameters 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 @@ -75,6 +96,12 @@ class Parameters // 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_; }; @@ -85,6 +112,9 @@ extern const Parameters* parameters; // 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) diff --git a/gold/symtab.cc b/gold/symtab.cc index c68b9ca..332c59f 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -190,7 +190,7 @@ Sized_symbol::init(const char* name, Value_type value, Size_type symsize, // 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_() { } @@ -467,16 +467,8 @@ Symbol_table::add_from_relobj( 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::sym_size; @@ -564,16 +556,8 @@ Symbol_table::add_from_dynobj( size_t versym_size, const std::vector* 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) { @@ -696,8 +680,6 @@ Symbol_table::define_special_symbol(const Target* target, const char** pname, Sized_symbol** poldsym ACCEPT_SIZE_ENDIAN) { - gold_assert(this->size_ == size); - Symbol* oldsym; Sized_symbol* sym; 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 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, @@ -794,7 +775,7 @@ Symbol_table::define_in_output_data(const Target* target, const char* name, 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, @@ -831,7 +812,7 @@ Symbol_table::do_define_in_output_data( Sized_symbol* sym; Sized_symbol* 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) ( @@ -878,8 +859,7 @@ Symbol_table::define_in_output_segment(const Target* target, const char* name, 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, @@ -890,7 +870,7 @@ Symbol_table::define_in_output_segment(const Target* target, const char* name, 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, @@ -926,14 +906,26 @@ Symbol_table::do_define_in_output_segment( Sized_symbol* sym; Sized_symbol* 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; @@ -959,8 +951,7 @@ Symbol_table::define_as_constant(const Target* target, const char* name, 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, @@ -970,7 +961,7 @@ Symbol_table::define_as_constant(const Target* target, const char* name, 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, @@ -1003,14 +994,26 @@ Symbol_table::do_define_as_constant( Sized_symbol* sym; Sized_symbol* 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; @@ -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->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(); @@ -1285,19 +1300,43 @@ void 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(); @@ -1463,24 +1502,47 @@ Symbol_table::sized_write_symbol( // 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(); diff --git a/gold/symtab.h b/gold/symtab.h index 36414bc..918c974 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -851,11 +851,6 @@ class Symbol_table 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 Sized_symbol* @@ -917,18 +912,12 @@ class Symbol_table // 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); @@ -1055,9 +1044,6 @@ class Symbol_table typedef std::vector 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_; @@ -1108,7 +1094,7 @@ template Sized_symbol* 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*>(sym); } @@ -1116,7 +1102,7 @@ template const Sized_symbol* 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*>(sym); } -- 2.7.4