Handle output sections with more than 0x7fffffff bytes.

* object.h (class Relobj): Change map_to_output_ to
	output_sections_, and just keep a section pointer.  Change all
	uses.  Move comdat group support to Sized_relobj.
	(Relobj::is_section_specially_mapped): Remove.
	(Relobj::output_section): Remove poff parameter.  Change all
	callers.
	(Relobj::output_section_offset): New function.
	(Relobj::set_section_offset): Rewrite.
	(Relobj::map_to_output): Remove.
	(Relobj::output_sections): New function.
	(Relobj::do_output_section_offset): New pure virtual function.
	(Relobj::do_set_section_offset): Likewise.
	(class Sized_relobj): Add section_offsets_ field.  Add comdat
	group support from Relobj.  Update declarations.
	(Sized_relobj::get_output_section_offset): New function.
	(Sized_relobj::do_output_section_offset): New function.
	(Sized_relobj::do_set_section_offset): New function.
	* object.cc (Relobj::output_section_address): Remove.
	(Sized_relobj::Sized_relobj): Initialize new fields.
	(Sized_relobj::include_section_group): Cast find_kept_object to
	Sized_relobj.
	(Sized_relobj::include_linkonce_section): Likewise.
	(Sized_relobj::do_layout): Use separate arrays for output section
	and output offset.
	(Sized_relobj::do_count_local_symbols): Change map_to_output to
	output_sections.
	(Sized_relobj::do_finalize_local_symbols): Change map_to_output to
	output_sections and section_offsets.
	(Sized_relobj::write_local_symbols): Likewise.
	(map_to_kept_section): Compute output address directly.
	* reloc.cc (Sized_relobj::do_read_relocs): Change map_to_output to
	output_sections and section_offsets.
	(Sized_relobj::write_sections): Likewise.
	(Sized_relobj::relocate_sections): Likewise.
	* symtab.cc (sized_finalize_symbol): Use output_section_offset.
	* output.h (class Output_reloc): Update declarations.  Change
	u2_.relobj to Sized_relobj*.
	(class Output_data_reloc): Change add functions to use
	Sized_relobj*.
	* output.cc (Output_reloc::Output_reloc): Change relobj to
	Sized_relobj*.
	(Output_reloc::local_section_offset): Change return type to
	Elf_Addr.  Use get_output_section_offset.
	(Output_reloc::get_address): Likewise.
	(Output_section::is_input_address_mapped): Don't call
	is_section_specially_mapped.
	(Output_section::output_offset): Likewise.
	(Output_section::output_address): Likewise.
	(Output_section::starting_output_address): Likewise.
	* copy-relocs.cc (Copy_relocs::copy_reloc): Change object
	parameter to Sized_relobj*.
	(Copy_relocs::need_copy_reloc): Likewise.
	(Copy_relocs::save): Likewise.
	* copy-relocs.h (class Copy_relocs): Update declarations.
	(class Copy_relocs::Copy_reloc_entry): Change constructor to use
	Sized_relobj*.  Change relobj_ field to Sized_relobj*.
	* target-reloc.h (relocate_for_relocatable): Change
	offset_in_output_section type to Elf_Addr.  Change code that uses
	it as well.
	* layout.cc (Layout::layout): Always set *off.
	* mapfile.cc (Mapfile::print_input_section): Use
	output_section_offset.
	* i386.cc (Target_i386::copy_reloc): Change object parameter to
	Sized_relobj*.
	* powerpc.cc (Target_powerpc::copy_reloc): Likewise.
	* sparc.cc (Target_sparc::copy_reloc): Likewise.
	* x86_64.cc (Target_x86_64::copy_reloc): Likewise.
This commit is contained in:
Ian Lance Taylor
2008-07-10 23:01:20 +00:00
parent 4c28f408df
commit ef9beddf72
17 changed files with 378 additions and 286 deletions

View File

@@ -617,7 +617,7 @@ template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
Symbol* gsym,
unsigned int type,
Relobj* relobj,
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx,
Address address,
bool is_relative)
@@ -707,7 +707,7 @@ template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
Output_section* os,
unsigned int type,
Relobj* relobj,
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx,
Address address)
: address_(address), local_sym_index_(SECTION_CODE), type_(type),
@@ -755,12 +755,7 @@ set_needs_dynsym_index()
if (!this->is_section_symbol_)
this->u1_.relobj->set_needs_output_dynsym_entry(lsi);
else
{
section_offset_type dummy;
Output_section* os = this->u1_.relobj->output_section(lsi, &dummy);
gold_assert(os != NULL);
os->set_needs_dynsym_index();
}
this->u1_.relobj->output_section(lsi)->set_needs_dynsym_index();
}
break;
}
@@ -812,8 +807,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
}
else
{
section_offset_type dummy;
Output_section* os = this->u1_.relobj->output_section(lsi, &dummy);
Output_section* os = this->u1_.relobj->output_section(lsi);
gold_assert(os != NULL);
if (dynamic)
index = os->dynsym_index();
@@ -831,7 +825,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
// within the input section.
template<bool dynamic, int size, bool big_endian>
section_offset_type
typename elfcpp::Elf_types<size>::Elf_Addr
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
local_section_offset(Addend addend) const
{
@@ -840,14 +834,14 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
&& this->local_sym_index_ != INVALID_CODE
&& this->is_section_symbol_);
const unsigned int lsi = this->local_sym_index_;
section_offset_type offset;
Output_section* os = this->u1_.relobj->output_section(lsi, &offset);
Output_section* os = this->u1_.relobj->output_section(lsi);
gold_assert(os != NULL);
if (offset != -1)
Address offset = this->u1_.relobj->get_output_section_offset(lsi);
if (offset != -1U)
return offset + addend;
// This is a merge section.
offset = os->output_address(this->u1_.relobj, lsi, addend);
gold_assert(offset != -1);
gold_assert(offset != -1U);
return offset;
}
@@ -860,11 +854,10 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_address() const
Address address = this->address_;
if (this->shndx_ != INVALID_CODE)
{
section_offset_type off;
Output_section* os = this->u2_.relobj->output_section(this->shndx_,
&off);
Output_section* os = this->u2_.relobj->output_section(this->shndx_);
gold_assert(os != NULL);
if (off != -1)
Address off = this->u2_.relobj->get_output_section_offset(this->shndx_);
if (off != -1U)
address += os->address() + off;
else
{
@@ -1094,8 +1087,7 @@ Output_data_group<size, big_endian>::do_write(Output_file* of)
p != this->input_shndxes_.end();
++p, ++contents)
{
section_offset_type dummy;
Output_section* os = this->relobj_->output_section(*p, &dummy);
Output_section* os = this->relobj_->output_section(*p);
unsigned int output_shndx;
if (os != NULL)
@@ -1358,8 +1350,7 @@ Output_data_got<size, big_endian>::add_local_pair_with_rel(
this->entries_.push_back(Got_entry());
unsigned int got_offset = this->last_got_offset();
object->set_local_got_offset(symndx, got_type, got_offset);
section_offset_type off;
Output_section* os = object->output_section(shndx, &off);
Output_section* os = object->output_section(shndx);
rel_dyn->add_output_section(os, r_type_1, this, got_offset);
this->entries_.push_back(Got_entry(object, symndx));
@@ -1389,8 +1380,7 @@ Output_data_got<size, big_endian>::add_local_pair_with_rela(
this->entries_.push_back(Got_entry());
unsigned int got_offset = this->last_got_offset();
object->set_local_got_offset(symndx, got_type, got_offset);
section_offset_type off;
Output_section* os = object->output_section(shndx, &off);
Output_section* os = object->output_section(shndx);
rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0);
this->entries_.push_back(Got_entry(object, symndx));
@@ -1995,8 +1985,6 @@ Output_section::is_input_address_mapped(const Relobj* object,
unsigned int shndx,
off_t offset) const
{
gold_assert(object->is_section_specially_mapped(shndx));
for (Input_section_list::const_iterator p = this->input_sections_.begin();
p != this->input_sections_.end();
++p)
@@ -2021,7 +2009,6 @@ section_offset_type
Output_section::output_offset(const Relobj* object, unsigned int shndx,
section_offset_type offset) const
{
gold_assert(object->is_section_specially_mapped(shndx));
// This can only be called meaningfully when layout is complete.
gold_assert(Output_data::is_layout_complete());
@@ -2043,8 +2030,6 @@ uint64_t
Output_section::output_address(const Relobj* object, unsigned int shndx,
off_t offset) const
{
gold_assert(object->is_section_specially_mapped(shndx));
uint64_t addr = this->address() + this->first_input_offset_;
for (Input_section_list::const_iterator p = this->input_sections_.begin();
p != this->input_sections_.end();
@@ -2076,8 +2061,6 @@ uint64_t
Output_section::starting_output_address(const Relobj* object,
unsigned int shndx) const
{
gold_assert(object->is_section_specially_mapped(shndx));
uint64_t addr = this->address() + this->first_input_offset_;
for (Input_section_list::const_iterator p = this->input_sections_.begin();
p != this->input_sections_.end();