forked from Imagelibrary/binutils-gdb
Fix failure in exception_static_test.
Because the __EH_FRAME_BEGIN__ symbol is provided in an empty .eh_frame section in crtbeginT.o, if crt1.o has a non-empty .eh_frame section, we place all optimized .eh_frame sections into the output section ahead of the __EH_FRAME_BEGIN__ symbol, which breaks EH for statically-linked binaries. This patch fixes the problem by delaying the attachment of the optimized .eh_frame sections to the output section until we see the end marker section (or to the end of pass 1 if we never see an end marker). gold/ PR gold/14675 * ehframe.cc (Eh_frame::add_ehframe_input_section): Change return type; return enum indicating whether .eh_frame section is empty, optimizable, unrecognized, or an end marker. Adjust explicit instantiations. * ehframe.h (Eh_frame::Eh_frame_section_disposition): New enum type. (Eh_frame::add_ehframe_input_section): Change return type. * gold.cc (queue_middle_tasks): Call Layout::finalize_eh_frame_section. * layout.cc (Layout::layout_eh_frame): Don't add optimized sections to the .eh_frame output section until we see the end marker. (Layout::finalize_eh_frame_section): New. * layout.h: (Layout::finalize_eh_frame_section): New.
This commit is contained in:
@@ -1420,15 +1420,21 @@ Layout::layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
|
||||
|
||||
elfcpp::Elf_Xword orig_flags = os->flags();
|
||||
|
||||
if (!parameters->incremental()
|
||||
&& this->eh_frame_data_->add_ehframe_input_section(object,
|
||||
symbols,
|
||||
symbols_size,
|
||||
symbol_names,
|
||||
symbol_names_size,
|
||||
shndx,
|
||||
reloc_shndx,
|
||||
reloc_type))
|
||||
Eh_frame::Eh_frame_section_disposition disp =
|
||||
Eh_frame::EH_UNRECOGNIZED_SECTION;
|
||||
if (!parameters->incremental())
|
||||
{
|
||||
disp = this->eh_frame_data_->add_ehframe_input_section(object,
|
||||
symbols,
|
||||
symbols_size,
|
||||
symbol_names,
|
||||
symbol_names_size,
|
||||
shndx,
|
||||
reloc_shndx,
|
||||
reloc_type);
|
||||
}
|
||||
|
||||
if (disp == Eh_frame::EH_OPTIMIZABLE_SECTION)
|
||||
{
|
||||
os->update_flags_for_input_section(shdr.get_sh_flags());
|
||||
|
||||
@@ -1440,35 +1446,49 @@ Layout::layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
|
||||
os->set_order(ORDER_RELRO);
|
||||
}
|
||||
|
||||
// We found a .eh_frame section we are going to optimize, so now
|
||||
// we can add the set of optimized sections to the output
|
||||
// section. We need to postpone adding this until we've found a
|
||||
// section we can optimize so that the .eh_frame section in
|
||||
// crtbegin.o winds up at the start of the output section.
|
||||
if (!this->added_eh_frame_data_)
|
||||
{
|
||||
os->add_output_section_data(this->eh_frame_data_);
|
||||
this->added_eh_frame_data_ = true;
|
||||
}
|
||||
*off = -1;
|
||||
return os;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We couldn't handle this .eh_frame section for some reason.
|
||||
// Add it as a normal section.
|
||||
bool saw_sections_clause = this->script_options_->saw_sections_clause();
|
||||
*off = os->add_input_section(this, object, shndx, ".eh_frame", shdr,
|
||||
reloc_shndx, saw_sections_clause);
|
||||
this->have_added_input_section_ = true;
|
||||
|
||||
if ((orig_flags & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR))
|
||||
!= (os->flags() & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR)))
|
||||
os->set_order(this->default_section_order(os, false));
|
||||
}
|
||||
if (disp == Eh_frame::EH_END_MARKER_SECTION && !this->added_eh_frame_data_)
|
||||
{
|
||||
// We found the end marker section, so now we can add the set of
|
||||
// optimized sections to the output section. We need to postpone
|
||||
// adding this until we've found a section we can optimize so that
|
||||
// the .eh_frame section in crtbeginT.o winds up at the start of
|
||||
// the output section.
|
||||
os->add_output_section_data(this->eh_frame_data_);
|
||||
this->added_eh_frame_data_ = true;
|
||||
}
|
||||
|
||||
// We couldn't handle this .eh_frame section for some reason.
|
||||
// Add it as a normal section.
|
||||
bool saw_sections_clause = this->script_options_->saw_sections_clause();
|
||||
*off = os->add_input_section(this, object, shndx, ".eh_frame", shdr,
|
||||
reloc_shndx, saw_sections_clause);
|
||||
this->have_added_input_section_ = true;
|
||||
|
||||
if ((orig_flags & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR))
|
||||
!= (os->flags() & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR)))
|
||||
os->set_order(this->default_section_order(os, false));
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
void
|
||||
Layout::finalize_eh_frame_section()
|
||||
{
|
||||
// If we never found an end marker section, we need to add the
|
||||
// optimized eh sections to the output section now.
|
||||
if (!parameters->incremental()
|
||||
&& this->eh_frame_section_ != NULL
|
||||
&& !this->added_eh_frame_data_)
|
||||
{
|
||||
this->eh_frame_section_->add_output_section_data(this->eh_frame_data_);
|
||||
this->added_eh_frame_data_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Create and return the magic .eh_frame section. Create
|
||||
// .eh_frame_hdr also if appropriate. OBJECT is the object with the
|
||||
// input .eh_frame section; it may be NULL.
|
||||
|
||||
Reference in New Issue
Block a user