aboutsummaryrefslogtreecommitdiff
path: root/gold/layout.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-11-30 00:35:27 +0000
committerIan Lance Taylor <iant@google.com>2007-11-30 00:35:27 +0000
commit9a0910c33e1a6962d475ee0a994fd1f5e446a888 (patch)
treef30e7b369cc05383699fbe4780ee0839b8dbcdde /gold/layout.cc
parent71195202dfb59bb7b61b35dc4cc5d202fab12020 (diff)
downloadgdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.zip
gdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.tar.gz
gdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.tar.bz2
From Craig Silverstein: Add support for compressing .debug_str section.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r--gold/layout.cc46
1 files changed, 39 insertions, 7 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index d95aea4..f7c1e40 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -393,7 +393,7 @@ Output_section*
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
elfcpp::Elf_Xword flags)
{
- Output_section* os = new Output_section(name, type, flags);
+ Output_section* os = new Output_section(this->options_, name, type, flags);
this->section_list_.push_back(os);
if ((flags & elfcpp::SHF_ALLOC) == 0)
@@ -710,7 +710,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
// Set the file offsets of all the non-data sections which don't
// have to wait for the input sections.
- off = this->set_section_offsets(off, false);
+ off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS);
// Now that all sections have been created, set the section indexes.
shndx = this->set_section_indexes(shndx);
@@ -1059,7 +1059,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
// segment.
off_t
-Layout::set_section_offsets(off_t off, bool after_input_sections)
+Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
{
for (Section_list::iterator p = this->unattached_section_list_.begin();
p != this->unattached_section_list_.end();
@@ -1069,8 +1069,17 @@ Layout::set_section_offsets(off_t off, bool after_input_sections)
if (*p == this->symtab_section_)
continue;
- if ((*p)->after_input_sections() != after_input_sections)
- continue;
+ if (pass == BEFORE_INPUT_SECTIONS_PASS
+ && (*p)->after_input_sections())
+ continue;
+ else if (pass == AFTER_INPUT_SECTIONS_PASS
+ && (!(*p)->after_input_sections()
+ || (*p)->type() == elfcpp::SHT_STRTAB))
+ continue;
+ else if (pass == STRTAB_AFTER_INPUT_SECTIONS_PASS
+ && (!(*p)->after_input_sections()
+ || (*p)->type() != elfcpp::SHT_STRTAB))
+ continue;
off = align_address(off, (*p)->addralign());
(*p)->set_file_offset(off);
@@ -1080,6 +1089,19 @@ Layout::set_section_offsets(off_t off, bool after_input_sections)
return off;
}
+// Allow any section not associated with a segment to change its
+// output section name at the last minute.
+
+void
+Layout::modify_section_names()
+{
+ for (Section_list::iterator p = this->unattached_section_list_.begin();
+ p != this->unattached_section_list_.end();
+ ++p)
+ if ((*p)->maybe_modify_output_section_name())
+ this->namepool_.add((*p)->name(), true, NULL);
+}
+
// Set the section indexes of all the sections not associated with a
// segment.
@@ -1883,9 +1905,19 @@ void
Layout::write_sections_after_input_sections(Output_file* of)
{
// Determine the final section offsets, and thus the final output
- // file size.
+ // file size. Note we finalize the .shstrab last, to allow the
+ // after_input_section sections to modify their section-names before
+ // writing.
off_t off = this->output_file_size_;
- off = this->set_section_offsets(off, true);
+ off = this->set_section_offsets(off, AFTER_INPUT_SECTIONS_PASS);
+
+ // Determine the final section names as well (at least, for sections
+ // that we haven't written yet).
+ this->modify_section_names();
+
+ // Now that we've finalized the names, we can finalize the shstrab.
+ off = this->set_section_offsets(off, STRTAB_AFTER_INPUT_SECTIONS_PASS);
+
if (off > this->output_file_size_)
{
of->resize(off);