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<int size, bool big_endian>
bool
-Layout::include_section(Object*, const char*,
+Layout::include_section(Object*, const char* name,
const elfcpp::Shdr<size, big_endian>& shdr)
{
// Some section types are never linked. Some are only linked when
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;
}
}
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
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);
+ }
}
}
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",
optimization_level_(0),
output_file_name_("a.out"),
is_relocatable_(false),
+ strip_(STRIP_NONE),
create_eh_frame_hdr_(false),
rpath_(),
rpath_link_(),
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
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; }
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; }
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_;
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.
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.