PR gold/12629

* object.cc (Sized_relobj_file::layout_section): Change shdr
	parameter to be const.
	(Sized_relobj_file::layout_eh_frame_section): New function, broken
	out of do_layout.
	(Sized_relobj_file::do_layout): Defer .eh_frame sections if
	appropriate.  Call layout_eh_frame_section.
	(Sized_relobj_file::do_layout_deferred_sections): Handle .eh_frame
	sections.
	* object.h (class Sized_relobj_file): Update declarations.
This commit is contained in:
Ian Lance Taylor 2011-06-30 00:50:13 +00:00
parent b9c00dd73c
commit 14788a3f86
3 changed files with 113 additions and 38 deletions

View file

@ -1,3 +1,16 @@
2011-06-29 Ian Lance Taylor <iant@google.com>
PR gold/12629
* object.cc (Sized_relobj_file::layout_section): Change shdr
parameter to be const.
(Sized_relobj_file::layout_eh_frame_section): New function, broken
out of do_layout.
(Sized_relobj_file::do_layout): Defer .eh_frame sections if
appropriate. Call layout_eh_frame_section.
(Sized_relobj_file::do_layout_deferred_sections): Handle .eh_frame
sections.
* object.h (class Sized_relobj_file): Update declarations.
2011-06-29 Ian Lance Taylor <iant@google.com>
PR gold/12652

View file

@ -1018,12 +1018,13 @@ Sized_relobj_file<size, big_endian>::include_linkonce_section(
template<int size, bool big_endian>
inline void
Sized_relobj_file<size, big_endian>::layout_section(Layout* layout,
unsigned int shndx,
const char* name,
typename This::Shdr& shdr,
unsigned int reloc_shndx,
unsigned int reloc_type)
Sized_relobj_file<size, big_endian>::layout_section(
Layout* layout,
unsigned int shndx,
const char* name,
const typename This::Shdr& shdr,
unsigned int reloc_shndx,
unsigned int reloc_type)
{
off_t offset;
Output_section* os = layout->layout(this, shndx, name, shdr,
@ -1042,6 +1043,53 @@ Sized_relobj_file<size, big_endian>::layout_section(Layout* layout,
this->set_relocs_must_follow_section_writes();
}
// Layout an input .eh_frame section.
template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::layout_eh_frame_section(
Layout* layout,
const unsigned char* symbols_data,
section_size_type symbols_size,
const unsigned char* symbol_names_data,
section_size_type symbol_names_size,
unsigned int shndx,
const typename This::Shdr& shdr,
unsigned int reloc_shndx,
unsigned int reloc_type)
{
gold_assert(this->has_eh_frame_);
off_t offset;
Output_section* os = layout->layout_eh_frame(this,
symbols_data,
symbols_size,
symbol_names_data,
symbol_names_size,
shndx,
shdr,
reloc_shndx,
reloc_type,
&offset);
this->output_sections()[shndx] = os;
if (os == NULL || offset == -1)
{
// An object can contain at most one section holding exception
// frame information.
gold_assert(this->discarded_eh_frame_shndx_ == -1U);
this->discarded_eh_frame_shndx_ = shndx;
this->section_offsets()[shndx] = invalid_address;
}
else
this->section_offsets()[shndx] = convert_types<Address, off_t>(offset);
// If this section requires special handling, and if there are
// relocs that aply to it, then we must do the special handling
// before we apply the relocs.
if (os != NULL && offset == -1 && reloc_shndx != 0)
this->set_relocs_must_follow_section_writes();
}
// Lay out the input sections. We walk through the sections and check
// whether they should be included in the link. If they should, we
// pass them to the Layout object, which will return an output section
@ -1367,7 +1415,12 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
out_sections[i] = reinterpret_cast<Output_section*>(1);
out_section_offsets[i] = invalid_address;
}
else
else if (should_defer_layout)
this->deferred_layout_.push_back(Deferred_layout(i, name,
pshdrs,
reloc_shndx[i],
reloc_type[i]));
else
eh_frame_sections.push_back(i);
continue;
}
@ -1527,7 +1580,6 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
p != eh_frame_sections.end();
++p)
{
gold_assert(this->has_eh_frame_);
gold_assert(external_symbols_offset != 0);
unsigned int i = *p;
@ -1535,33 +1587,15 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
pshdr = section_headers_data + i * This::shdr_size;
typename This::Shdr shdr(pshdr);
off_t offset;
Output_section* os = layout->layout_eh_frame(this,
symbols_data,
symbols_size,
symbol_names_data,
symbol_names_size,
i, shdr,
reloc_shndx[i],
reloc_type[i],
&offset);
out_sections[i] = os;
if (os == NULL || offset == -1)
{
// An object can contain at most one section holding exception
// frame information.
gold_assert(this->discarded_eh_frame_shndx_ == -1U);
this->discarded_eh_frame_shndx_ = i;
out_section_offsets[i] = invalid_address;
}
else
out_section_offsets[i] = convert_types<Address, off_t>(offset);
// If this section requires special handling, and if there are
// relocs that apply to it, then we must do the special handling
// before we apply the relocs.
if (os != NULL && offset == -1 && reloc_shndx[i] != 0)
this->set_relocs_must_follow_section_writes();
this->layout_eh_frame_section(layout,
symbols_data,
symbols_size,
symbol_names_data,
symbol_names_size,
i,
shdr,
reloc_shndx[i],
reloc_type[i]);
}
if (is_gc_pass_two)
@ -1600,8 +1634,27 @@ Sized_relobj_file<size, big_endian>::do_layout_deferred_sections(Layout* layout)
if (!this->is_section_included(deferred->shndx_))
continue;
this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
shdr, deferred->reloc_shndx_, deferred->reloc_type_);
if (parameters->options().relocatable()
|| deferred->name_ != ".eh_frame"
|| !this->check_eh_frame_flags(&shdr))
this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
shdr, deferred->reloc_shndx_,
deferred->reloc_type_);
else
{
// Reading the symbols again here may be slow.
Read_symbols_data sd;
this->read_symbols(&sd);
this->layout_eh_frame_section(layout,
sd.symbols->data(),
sd.symbols_size,
sd.symbol_names->data(),
sd.symbol_names_size,
deferred->shndx_,
shdr,
deferred->reloc_shndx_,
deferred->reloc_type_);
}
}
this->deferred_layout_.clear();

View file

@ -2306,9 +2306,18 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
// Layout an input section.
void
layout_section(Layout* layout, unsigned int shndx, const char* name,
typename This::Shdr& shdr, unsigned int reloc_shndx,
const typename This::Shdr& shdr, unsigned int reloc_shndx,
unsigned int reloc_type);
// Layout an input .eh_frame section.
void
layout_eh_frame_section(Layout* layout, const unsigned char* symbols_data,
section_size_type symbols_size,
const unsigned char* symbol_names_data,
section_size_type symbol_names_size,
unsigned int shndx, const typename This::Shdr&,
unsigned int reloc_shndx, unsigned int reloc_type);
// Write section data to the output file. Record the views and
// sizes in VIEWS for use when relocating.
void