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
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);

View File

@ -740,8 +740,7 @@ Dynobj::elf_hash(const char* name)
// symbol table.
void
Dynobj::create_elf_hash_table(const Target* target,
const std::vector<Symbol*>& dynsyms,
Dynobj::create_elf_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash,
unsigned int* phashlen)
@ -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<true>(bucket, chain, phash, hashlen);
if (parameters->is_big_endian())
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
Dynobj::sized_create_elf_hash_table<true>(bucket, chain, phash,
hashlen);
#else
gold_unreachable();
#endif
}
else
Dynobj::sized_create_elf_hash_table<false>(bucket, chain, phash, hashlen);
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
Dynobj::sized_create_elf_hash_table<false>(bucket, chain, phash,
hashlen);
#else
gold_unreachable();
#endif
}
*pphash = phash;
*phashlen = hashlen;
@ -840,8 +853,7 @@ Dynobj::gnu_hash(const char* name)
// symbol table.
void
Dynobj::create_gnu_hash_table(const Target* target,
const std::vector<Symbol*>& dynsyms,
Dynobj::create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash,
unsigned int* phashlen)
@ -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();

View File

@ -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<Symbol*>& dynsyms,
create_elf_hash_table(const std::vector<Symbol*>& 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<Symbol*>& dynsyms,
create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash, unsigned int* phashlen);

View File

@ -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);

View File

@ -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_;
};

View File

@ -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.

View File

@ -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<Symbol*>& 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.

View File

@ -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<Symbol*>& 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_;
};

View File

@ -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;
}

View File

@ -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();

View File

@ -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_entry> Dynamic_entries;
// The target.
const Target* target_;
// The entries.
Dynamic_entries entries_;
// The pool used for strings.

View File

@ -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.

View File

@ -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)

View File

@ -190,7 +190,7 @@ Sized_symbol<size>::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<size>::sym_size;
@ -564,16 +556,8 @@ Symbol_table::add_from_dynobj(
size_t versym_size,
const std::vector<const char*>* version_map)
{
// We take the size from the first object we see.
if (this->get_size() == 0)
this->set_size(size);
if (size != this->get_size() || size != dynobj->target()->get_size())
{
fprintf(stderr, _("%s: %s: mixing 32-bit and 64-bit ELF objects\n"),
program_name, dynobj->name().c_str());
gold_exit(false);
}
gold_assert(size == dynobj->target()->get_size());
gold_assert(size == parameters->get_size());
if (versym != NULL && versym_size / 2 < count)
{
@ -696,8 +680,6 @@ Symbol_table::define_special_symbol(const Target* target, const char** pname,
Sized_symbol<size>** poldsym
ACCEPT_SIZE_ENDIAN)
{
gold_assert(this->size_ == size);
Symbol* oldsym;
Sized_symbol<size>* 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<size>* sym;
Sized_symbol<size>* oldsym;
if (target->is_big_endian())
if (parameters->is_big_endian())
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
@ -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<size>* sym;
Sized_symbol<size>* oldsym;
if (target->is_big_endian())
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, true));
if (parameters->is_big_endian())
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, true));
#else
gold_unreachable();
#endif
}
else
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, false));
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, false));
#else
gold_unreachable();
#endif
}
if (sym == NULL)
return NULL;
@ -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<size>* sym;
Sized_symbol<size>* oldsym;
if (target->is_big_endian())
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, true));
if (parameters->is_big_endian())
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, true));
#else
gold_unreachable();
#endif
}
else
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, false));
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, false) (
target, &name, &version, only_if_ref, &oldsym
SELECT_SIZE_ENDIAN(size, false));
#else
gold_unreachable();
#endif
}
if (sym == NULL)
return NULL;
@ -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();

View File

@ -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<int size>
Sized_symbol<size>*
@ -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<Symbol*> Commons_type;
// The size of the symbols in the symbol table (32 or 64).
int size_;
// We increment this every time we see a new undefined symbol, for
// use in archive groups.
int saw_undefined_;
@ -1108,7 +1094,7 @@ template<int size>
Sized_symbol<size>*
Symbol_table::get_sized_symbol(Symbol* sym ACCEPT_SIZE) const
{
gold_assert(size == this->get_size());
gold_assert(size == parameters->get_size());
return static_cast<Sized_symbol<size>*>(sym);
}
@ -1116,7 +1102,7 @@ template<int size>
const Sized_symbol<size>*
Symbol_table::get_sized_symbol(const Symbol* sym ACCEPT_SIZE) const
{
gold_assert(size == this->get_size());
gold_assert(size == parameters->get_size());
return static_cast<const Sized_symbol<size>*>(sym);
}