aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/ChangeLog13
-rw-r--r--gold/object.cc127
-rw-r--r--gold/object.h11
3 files changed, 113 insertions, 38 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index ae21427..62ee3ca 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,18 @@
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
* script.cc (Token::integer_value): Accept trailing M/m/K/k
modifier.
diff --git a/gold/object.cc b/gold/object.cc
index 322f56e..d3835df 100644
--- a/gold/object.cc
+++ b/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();
diff --git a/gold/object.h b/gold/object.h
index 8735f9e..9c363cd 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -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