From 9e2dcb779c27737af88468b29aa1d2a15b0b770f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 10 Oct 2007 19:02:56 +0000 Subject: [PATCH] Implement -s and -S options which strip symbols. --- gold/layout.cc | 92 +++++++++++++++++++++++++++++----------------- gold/object.cc | 3 ++ gold/options.cc | 5 +++ gold/options.h | 30 +++++++++++++++ gold/parameters.cc | 7 ++++ gold/parameters.h | 25 ++++++++++++- gold/symtab.cc | 14 +++++-- 7 files changed, 138 insertions(+), 38 deletions(-) diff --git a/gold/layout.cc b/gold/layout.cc index af91d41d221..f7e136590a4 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -86,11 +86,19 @@ Layout::Hash_key::operator()(const Layout::Key& k) const return k.first + k.second.first + k.second.second; } +// Return whether PREFIX is a prefix of STR. + +static inline bool +is_prefix_of(const char* prefix, const char* str) +{ + return strncmp(prefix, str, strlen(prefix)) == 0; +} + // Whether to include this section in the link. template bool -Layout::include_section(Object*, const char*, +Layout::include_section(Object*, const char* name, const elfcpp::Shdr& shdr) { // Some section types are never linked. Some are only linked when @@ -111,8 +119,20 @@ Layout::include_section(Object*, const char*, case elfcpp::SHT_GROUP: return parameters->output_is_object(); + case elfcpp::SHT_PROGBITS: + if (parameters->strip_debug() + && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0) + { + // Debugging sections can only be recognized by name. + if (is_prefix_of(".debug", name) + || is_prefix_of(".gnu.linkonce.wi.", name) + || is_prefix_of(".line", name) + || is_prefix_of(".stab", name)) + return false; + } + return true; + default: - // FIXME: Handle stripping debug sections here. return true; } } @@ -973,32 +993,35 @@ Layout::create_symtab_sections(const Input_objects* input_objects, off = symtab->finalize(local_symcount, off, dynoff, dyn_global_index, dyncount, &this->sympool_); - this->sympool_.set_string_offsets(); + if (!parameters->strip_all()) + { + this->sympool_.set_string_offsets(); - const char* symtab_name = this->namepool_.add(".symtab", NULL); - Output_section* osymtab = this->make_output_section(symtab_name, - elfcpp::SHT_SYMTAB, - 0); - this->symtab_section_ = osymtab; + const char* symtab_name = this->namepool_.add(".symtab", NULL); + Output_section* osymtab = this->make_output_section(symtab_name, + elfcpp::SHT_SYMTAB, + 0); + this->symtab_section_ = osymtab; - Output_section_data* pos = new Output_data_space(off - startoff, - align); - osymtab->add_output_section_data(pos); + Output_section_data* pos = new Output_data_space(off - startoff, + align); + osymtab->add_output_section_data(pos); - const char* strtab_name = this->namepool_.add(".strtab", NULL); - Output_section* ostrtab = this->make_output_section(strtab_name, - elfcpp::SHT_STRTAB, - 0); + const char* strtab_name = this->namepool_.add(".strtab", NULL); + Output_section* ostrtab = this->make_output_section(strtab_name, + elfcpp::SHT_STRTAB, + 0); - Output_section_data* pstr = new Output_data_strtab(&this->sympool_); - ostrtab->add_output_section_data(pstr); + Output_section_data* pstr = new Output_data_strtab(&this->sympool_); + ostrtab->add_output_section_data(pstr); - osymtab->set_address(0, startoff); - osymtab->set_link_section(ostrtab); - osymtab->set_info(local_symcount); - osymtab->set_entsize(symsize); + osymtab->set_address(0, startoff); + osymtab->set_link_section(ostrtab); + osymtab->set_info(local_symcount); + osymtab->set_entsize(symsize); - *poff = off; + *poff = off; + } } // Create the .shstrtab section, which holds the names of the @@ -1555,19 +1578,22 @@ Layout::add_comdat(const char* signature, bool group) void Layout::write_data(const Symbol_table* symtab, Output_file* of) const { - const Output_section* symtab_section = this->symtab_section_; - for (Section_list::const_iterator p = this->section_list_.begin(); - p != this->section_list_.end(); - ++p) + if (!parameters->strip_all()) { - if ((*p)->needs_symtab_index()) + const Output_section* symtab_section = this->symtab_section_; + for (Section_list::const_iterator p = this->section_list_.begin(); + p != this->section_list_.end(); + ++p) { - gold_assert(symtab_section != NULL); - unsigned int index = (*p)->symtab_index(); - gold_assert(index > 0 && index != -1U); - off_t off = (symtab_section->offset() - + index * symtab_section->entsize()); - symtab->write_section_symbol(*p, of, off); + if ((*p)->needs_symtab_index()) + { + gold_assert(symtab_section != NULL); + unsigned int index = (*p)->symtab_index(); + gold_assert(index > 0 && index != -1U); + off_t off = (symtab_section->offset() + + index * symtab_section->entsize()); + symtab->write_section_symbol(*p, of, off); + } } } diff --git a/gold/object.cc b/gold/object.cc index cfdb17c2596..b8843e9c615 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -715,6 +715,9 @@ void Sized_relobj::write_local_symbols(Output_file* of, const Stringpool* sympool) { + if (parameters->strip_all()) + return; + gold_assert(this->symtab_shndx_ != -1U); if (this->symtab_shndx_ == 0) { diff --git a/gold/options.cc b/gold/options.cc index 4ddb1acdbb2..bd9f79729e7 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -334,6 +334,10 @@ options::Command_line_options::options[] = GENERAL_ARG('R', "rpath", N_("Add DIR to runtime search path"), N_("-R DIR, -rpath DIR"), ONE_DASH, &General_options::add_to_rpath), + GENERAL_NOARG('s', "strip-all", N_("Strip all symbols"), NULL, + TWO_DASHES, &General_options::set_strip_all), + GENERAL_NOARG('S', "strip-debug", N_("Strip debugging information"), NULL, + TWO_DASHES, &General_options::set_strip_debug), GENERAL_NOARG('\0', "eh-frame-hdr", N_("Create exception frame header"), NULL, TWO_DASHES, &General_options::set_create_eh_frame_hdr), GENERAL_ARG('\0', "rpath-link", @@ -378,6 +382,7 @@ General_options::General_options() optimization_level_(0), output_file_name_("a.out"), is_relocatable_(false), + strip_(STRIP_NONE), create_eh_frame_hdr_(false), rpath_(), rpath_link_(), diff --git a/gold/options.h b/gold/options.h index 159e7b25478..1e850cf2662 100644 --- a/gold/options.h +++ b/gold/options.h @@ -134,6 +134,16 @@ class General_options is_relocatable() const { return this->is_relocatable_; } + // -s: Strip all symbols. + bool + strip_all() const + { return this->strip_ == STRIP_ALL; } + + // -S: Strip debugging information. + bool + strip_debug() const + { return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; } + // --eh-frame-hdr: Whether to generate an exception frame header. bool create_eh_frame_hdr() const @@ -172,6 +182,17 @@ class General_options friend class Command_line; friend class options::Command_line_options; + // Which symbols to strip. + enum Strip + { + // Don't strip any symbols. + STRIP_NONE, + // Strip all symbols. + STRIP_ALL, + // Strip debugging information. + STRIP_DEBUG + }; + void set_export_dynamic() { this->export_dynamic_ = true; } @@ -200,6 +221,14 @@ class General_options set_relocatable() { this->is_relocatable_ = true; } + void + set_strip_all() + { this->strip_ = STRIP_ALL; } + + void + set_strip_debug() + { this->strip_ = STRIP_DEBUG; } + void set_create_eh_frame_hdr() { this->create_eh_frame_hdr_ = true; } @@ -238,6 +267,7 @@ class General_options int optimization_level_; const char* output_file_name_; bool is_relocatable_; + Strip strip_; bool create_eh_frame_hdr_; Dir_list rpath_; Dir_list rpath_link_; diff --git a/gold/parameters.cc b/gold/parameters.cc index 3c7cf288c48..337469a4ba6 100644 --- a/gold/parameters.cc +++ b/gold/parameters.cc @@ -42,6 +42,13 @@ Parameters::Parameters(const General_options* options) this->output_file_type_ = OUTPUT_OBJECT; else this->output_file_type_ = OUTPUT_EXECUTABLE; + + if (options->strip_all()) + this->strip_ = STRIP_ALL; + else if (options->strip_debug()) + this->strip_ = STRIP_DEBUG; + else + this->strip_ = STRIP_NONE; } // Set whether we are doing a static link. diff --git a/gold/parameters.h b/gold/parameters.h index a1509811981..8d8ef36b722 100644 --- a/gold/parameters.h +++ b/gold/parameters.h @@ -62,6 +62,16 @@ class Parameters sysroot() const { return this->sysroot_; } + // Whether to strip all symbols. + bool + strip_all() const + { return this->strip_ == STRIP_ALL; } + + // Whether to strip debugging information. + bool + strip_debug() const + { return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; } + // Whether we are doing a static link--a link in which none of the // input files are shared libraries. This is only known after we // have seen all the input files. @@ -114,11 +124,24 @@ class Parameters OUTPUT_OBJECT }; + // Which symbols to strip. + enum Strip + { + // Don't strip any symbols. + STRIP_NONE, + // Strip all symbols. + STRIP_ALL, + // Strip debugging information. + STRIP_DEBUG + }; + // The type of the output file. Output_file_type output_file_type_; // The target system root directory. std::string sysroot_; - + // Which symbols to strip. + Strip strip_; + // Whether the doing_static_link_ field is valid. bool is_doing_static_link_valid_; // Whether we are doing a static link. diff --git a/gold/symtab.cc b/gold/symtab.cc index c9ac1c9a825..5237b8cb916 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1316,10 +1316,16 @@ Symbol_table::sized_finalize(unsigned index, off_t off, Stringpool* pool) } sym->set_value(value); - sym->set_symtab_index(index); - pool->add(sym->name(), NULL); - ++index; - off += sym_size; + + if (parameters->strip_all()) + sym->set_symtab_index(-1U); + else + { + sym->set_symtab_index(index); + pool->add(sym->name(), NULL); + ++index; + off += sym_size; + } } this->output_count_ = index - orig_index; -- 2.30.2