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:
parent
b9c00dd73c
commit
14788a3f86
3 changed files with 113 additions and 38 deletions
|
@ -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
|
||||
|
|
127
gold/object.cc
127
gold/object.cc
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue