diff options
author | Ian Lance Taylor <iant@google.com> | 2007-11-30 00:35:27 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2007-11-30 00:35:27 +0000 |
commit | 9a0910c33e1a6962d475ee0a994fd1f5e446a888 (patch) | |
tree | f30e7b369cc05383699fbe4780ee0839b8dbcdde /gold/output.cc | |
parent | 71195202dfb59bb7b61b35dc4cc5d202fab12020 (diff) | |
download | gdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.zip gdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.tar.gz gdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.tar.bz2 |
From Craig Silverstein: Add support for compressing .debug_str section.
Diffstat (limited to 'gold/output.cc')
-rw-r--r-- | gold/output.cc | 112 |
1 files changed, 91 insertions, 21 deletions
diff --git a/gold/output.cc b/gold/output.cc index d89c72a..351c21d 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -32,6 +32,7 @@ #include "libiberty.h" // for unlink_if_ordinary() #include "parameters.h" +#include "compressed_output.h" #include "object.h" #include "symtab.h" #include "reloc.h" @@ -1033,9 +1034,11 @@ Output_section::Input_section::write(Output_file* of) // Construct an Output_section. NAME will point into a Stringpool. -Output_section::Output_section(const char* name, elfcpp::Elf_Word type, +Output_section::Output_section(const General_options& options, + const char* name, elfcpp::Elf_Word type, elfcpp::Elf_Xword flags) - : name_(name), + : options_(options), + name_(name), addralign_(0), entsize_(0), link_section_(NULL), @@ -1079,6 +1082,22 @@ Output_section::set_entsize(uint64_t v) gold_assert(this->entsize_ == v); } +// 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_section(const char* secname) +{ + return (strncmp(secname, ".debug", sizeof(".debug") - 1) == 0); +} + // Add the input section SHNDX, with header SHDR, named SECNAME, in // OBJECT, to the Output_section. RELOC_SHNDX is the index of a // relocation section which applies to this section, or 0 if none, or @@ -1126,7 +1145,8 @@ Output_section::add_input_section(Sized_relobj<size, big_endian>* object, && reloc_shndx == 0) { if (this->add_merge_input_section(object, shndx, sh_flags, - entsize, addralign)) + entsize, addralign, + is_compressible_section(secname))) { // Tell the relocation routines that they need to call the // output_offset method to determine the final address. @@ -1213,7 +1233,8 @@ Output_section::add_output_merge_section(Output_section_data* posd, bool Output_section::add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags, uint64_t entsize, - uint64_t addralign) + uint64_t addralign, + bool is_compressible_section) { bool is_string = (flags & elfcpp::SHF_STRINGS) != 0; @@ -1227,30 +1248,56 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx, p != this->input_sections_.end(); ++p) if (p->is_merge_section(is_string, entsize, addralign)) - break; + { + p->add_input_section(object, shndx); + return true; + } // We handle the actual constant merging in Output_merge_data or // Output_merge_string_data. - if (p != this->input_sections_.end()) - p->add_input_section(object, shndx); + Output_section_data* posd; + if (!is_string) + posd = new Output_merge_data(entsize, addralign); + else if (is_compressible_section && options_.compress_debug_sections()) + { + switch (entsize) + { + case 1: + posd = new Output_compressed_string<char>(addralign, this->options_); + break; + case 2: + posd = new Output_compressed_string<uint16_t>(addralign, + this->options_); + break; + case 4: + posd = new Output_compressed_string<uint32_t>(addralign, + this->options_); + break; + default: + return false; + } + } else { - Output_section_data* posd; - if (!is_string) - posd = new Output_merge_data(entsize, addralign); - else if (entsize == 1) - posd = new Output_merge_string<char>(addralign); - else if (entsize == 2) - posd = new Output_merge_string<uint16_t>(addralign); - else if (entsize == 4) - posd = new Output_merge_string<uint32_t>(addralign); - else - return false; - - this->add_output_merge_section(posd, is_string, entsize); - posd->add_input_section(object, shndx); + switch (entsize) + { + case 1: + posd = new Output_merge_string<char>(addralign); + break; + case 2: + posd = new Output_merge_string<uint16_t>(addralign); + break; + case 4: + posd = new Output_merge_string<uint32_t>(addralign); + break; + default: + return false; + } } + this->add_output_merge_section(posd, is_string, entsize); + posd->add_input_section(object, shndx); + return true; } @@ -1367,6 +1414,29 @@ Output_section::set_final_data_size() this->set_data_size(off - startoff); } +// Ask each output_section_data member if it wants to change the name +// of the output section. If any of them says yes, use this to set +// the new name. This should be called after all processing of this +// output section is done, but before the name is finally committed to +// the output-section's header. + +bool +Output_section::maybe_modify_output_section_name() +{ + for (Input_section_list::const_iterator it = input_sections_.begin(); + it != input_sections_.end(); + ++it) + { + const char* newname = it->modified_output_section_name(this->name()); + if (newname != NULL) + { + this->set_name(newname); + return true; + } + } + return false; +} + // Write the section header to *OSHDR. template<int size, bool big_endian> |