summaryrefslogtreecommitdiff
path: root/gold/layout.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gold/layout.cc')
-rw-r--r--gold/layout.cc51
1 files changed, 33 insertions, 18 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index f7c1e40be39..39008cd46fe 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -32,6 +32,7 @@
#include "symtab.h"
#include "dynobj.h"
#include "ehframe.h"
+#include "compressed_output.h"
#include "layout.h"
namespace gold
@@ -386,6 +387,22 @@ Layout::section_flags_to_segment(elfcpp::Elf_Xword flags)
return ret;
}
+// Sometimes we compress sections. This is typically done for
+// sections that are not part of normal program execution (such as
+// .debug_* sections), and where the readers of these sections know
+// how to deal with compressed sections. (To make it easier for them,
+// we will rename the ouput section in such cases from .foo to
+// .foo.zlib.nnnn, where nnnn is the uncompressed size.) This routine
+// doesn't say for certain whether we'll compress -- it depends on
+// commandline options as well -- just whether this section is a
+// candidate for compression.
+
+static bool
+is_compressible_debug_section(const char* secname)
+{
+ return (strncmp(secname, ".debug", sizeof(".debug") - 1) == 0);
+}
+
// Make a new Output_section, and attach it to segments as
// appropriate.
@@ -393,7 +410,14 @@ Output_section*
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
elfcpp::Elf_Xword flags)
{
- Output_section* os = new Output_section(this->options_, name, type, flags);
+ Output_section* os;
+ if ((flags & elfcpp::SHF_ALLOC) == 0
+ && this->options_.compress_debug_sections()
+ && is_compressible_debug_section(name))
+ os = new Output_compressed_section(&this->options_, name, type, flags);
+ else
+ os = new Output_section(name, type, flags);
+
this->section_list_.push_back(os);
if ((flags & elfcpp::SHF_ALLOC) == 0)
@@ -1070,6 +1094,10 @@ Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
continue;
if (pass == BEFORE_INPUT_SECTIONS_PASS
+ && (*p)->requires_postprocessing())
+ (*p)->create_postprocessing_buffer();
+
+ if (pass == BEFORE_INPUT_SECTIONS_PASS
&& (*p)->after_input_sections())
continue;
else if (pass == AFTER_INPUT_SECTIONS_PASS
@@ -1085,23 +1113,14 @@ Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
(*p)->set_file_offset(off);
(*p)->finalize_data_size();
off += (*p)->data_size();
+
+ // At this point the name must be set.
+ if (pass != STRTAB_AFTER_INPUT_SECTIONS_PASS)
+ this->namepool_.add((*p)->name(), false, NULL);
}
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.
@@ -1911,10 +1930,6 @@ Layout::write_sections_after_input_sections(Output_file* of)
off_t off = this->output_file_size_;
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);