This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gold patch committed: Fix .eh_frame sections when using plugins
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Wed, 29 Jun 2011 17:51:55 -0700
- Subject: gold patch committed: Fix .eh_frame sections when using plugins
When using plugins, section layout is deferred for objects following a
claimed object. Unfortunately, .eh_frame section layout was not being
deferred. This matters when it comes to handling crtend.o. This lead
to the poor debugging experience described in PR 12629. This patch
fixes the problem by deferring the layout of .eh_frame sections when
appropriate. Committed to mainline.
Ian
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.
Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.144
diff -u -p -r1.144 object.cc
--- object.cc 29 Jun 2011 21:39:19 -0000 1.144
+++ object.cc 30 Jun 2011 00:47:23 -0000
@@ -1018,12 +1018,13 @@ Sized_relobj_file<size, big_endian>::inc
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>::lay
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_
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_
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_
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_
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();
Index: object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.111
diff -u -p -r1.111 object.h
--- object.h 25 Jun 2011 00:40:56 -0000 1.111
+++ object.h 30 Jun 2011 00:47:23 -0000
@@ -2306,9 +2306,18 @@ class Sized_relobj_file : public Sized_r
// 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