// Return TRUE if this is a section whose contents will be needed in the
// Add_symbols task. This function is only called for sections that have
-// already passed the test in is_compressed_debug_section(), so we know
-// that the section name begins with ".zdebug".
+// already passed the test in is_compressed_debug_section() and the debug
+// section name prefix, ".debug"/".zdebug", has been skipped.
static bool
need_decompressed_section(const char* name)
{
- // Skip over the ".zdebug" and a quick check for the "_".
- name += 7;
if (*name++ != '_')
return false;
}
const char* name = names + shdr.get_sh_name();
- if (is_compressed_debug_section(name))
+ bool is_compressed = ((shdr.get_sh_flags()
+ & elfcpp::SHF_COMPRESSED) != 0);
+ bool is_zcompressed = (!is_compressed
+ && is_compressed_debug_section(name));
+
+ if (is_zcompressed || is_compressed)
{
section_size_type len;
const unsigned char* contents =
obj->section_contents(i, &len, false);
- uint64_t uncompressed_size = get_uncompressed_size(contents, len);
+ uint64_t uncompressed_size;
+ if (is_zcompressed)
+ {
+ // Skip over the ".zdebug" prefix.
+ name += 7;
+ uncompressed_size = get_uncompressed_size(contents, len);
+ }
+ else
+ {
+ // Skip over the ".debug" prefix.
+ name += 6;
+ elfcpp::Chdr<size, big_endian> chdr(contents);
+ uncompressed_size = chdr.get_ch_size();
+ }
Compressed_section_info info;
info.size = convert_to_section_size_type(uncompressed_size);
+ info.flag = shdr.get_sh_flags();
info.contents = NULL;
if (uncompressed_size != -1ULL)
{
uncompressed_data = new unsigned char[uncompressed_size];
if (decompress_input_section(contents, len,
uncompressed_data,
- uncompressed_size))
+ uncompressed_size,
+ size, big_endian,
+ shdr.get_sh_flags()))
info.contents = uncompressed_data;
else
delete[] uncompressed_data;
if (this->find_eh_frame(pshdrs, names, sd->section_names_size))
this->has_eh_frame_ = true;
- if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL)
- {
- Compressed_section_map* compressed_sections =
- build_compressed_section_map<size, big_endian>(
- pshdrs, this->shnum(), names, sd->section_names_size, this, true);
- if (compressed_sections != NULL)
- this->set_compressed_sections(compressed_sections);
- }
+ Compressed_section_map* compressed_sections =
+ build_compressed_section_map<size, big_endian>(
+ pshdrs, this->shnum(), names, sd->section_names_size, this, true);
+ if (compressed_sections != NULL)
+ this->set_compressed_sections(compressed_sections);
return (this->has_eh_frame_
|| (!parameters->options().relocatable()
|| shdr.get_sh_type() == elfcpp::SHT_INIT_ARRAY
|| shdr.get_sh_type() == elfcpp::SHT_FINI_ARRAY)
{
- symtab->gc()->worklist().push(Section_id(this, i));
+ symtab->gc()->worklist().push_back(Section_id(this, i));
}
// If the section name XXX can be represented as a C identifier
// it cannot be discarded if there are references to
// Loop over the local symbols.
const Output_sections& out_sections(this->output_sections());
+ std::vector<Address>& out_section_offsets(this->section_offsets());
unsigned int shnum = this->shnum();
unsigned int count = 0;
unsigned int dyncount = 0;
bool strip_all = parameters->options().strip_all();
bool discard_all = parameters->options().discard_all();
bool discard_locals = parameters->options().discard_locals();
+ bool discard_sec_merge = parameters->options().discard_sec_merge();
for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
{
elfcpp::Sym<size, big_endian> sym(psyms);
continue;
}
+ // By default, discard temporary local symbols in merge sections.
// If --discard-locals option is used, discard all temporary local
// symbols. These symbols start with system-specific local label
// prefixes, typically .L for ELF system. We want to be compatible
// - the symbol has a name.
//
// We do not discard a symbol if it needs a dynamic symbol entry.
- if (discard_locals
+ if ((discard_locals
+ || (discard_sec_merge
+ && is_ordinary
+ && out_section_offsets[shndx] == invalid_address))
&& sym.get_st_type() != elfcpp::STT_FILE
&& !lv.needs_output_dynsym_entry()
&& lv.may_be_discarded_from_output_symtab()
if (!decompress_input_section(buffer,
buffer_size,
uncompressed_data,
- uncompressed_size))
+ uncompressed_size,
+ elfsize(),
+ is_big_endian(),
+ p->second.flag))
this->error(_("could not decompress section %s"),
this->do_section_name(shndx).c_str());