* dwarf_reader.cc (Sized_dwarf_line_info::Sized_dwarf_line_info):
Call Object::decompressed_section_contents. * dwarf_reader.h (Sized_dwarf_line_info::~Sized_dwarf_line_info): New dtor. (Sized_dwarf_line_info::buffer_start_): New data member. * merge.cc (Output_merge_data::do_add_input_section): Call Object::decompressed_section_contents. (Output_merge_string::do_add_input_section): Likewise. * object.cc (need_decompressed_section): New function. (build_compressed_section_map): Decompress sections needed later. (Sized_relobj_file::do_decompressed_section_contents): New function. (Sized_relobj_file::do_discard_decompressed_sections): New function. * object.h (Object::decompressed_section_contents): New function. (Object::discard_decompressed_sections): New function. (Object::do_decompressed_section_contents): New function. (Object::do_discard_decompressed_sections): New function. (Compressed_section_info): New type. (Compressed_section_map): Include decompressed section contents. (Sized_relobj_file::do_decompressed_section_contents): New function. (Sized_relobj_file::do_discard_decompressed_sections): New function.
This commit is contained in:
parent
718cb7da5d
commit
5dd8762ad1
7 changed files with 246 additions and 66 deletions
130
gold/object.cc
130
gold/object.cc
|
@ -550,8 +550,22 @@ Sized_relobj_file<size, big_endian>::find_eh_frame(
|
|||
return false;
|
||||
}
|
||||
|
||||
// Return TRUE if this is a section whose contents will be needed in the
|
||||
// Add_symbols task.
|
||||
|
||||
static bool
|
||||
need_decompressed_section(const char* name)
|
||||
{
|
||||
// We will need .zdebug_str if this is not an incremental link
|
||||
// (i.e., we are processing string merge sections).
|
||||
if (!parameters->incremental() && strcmp(name, ".zdebug_str") == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build a table for any compressed debug sections, mapping each section index
|
||||
// to the uncompressed size.
|
||||
// to the uncompressed size and (if needed) the decompressed contents.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
Compressed_section_map*
|
||||
|
@ -562,9 +576,10 @@ build_compressed_section_map(
|
|||
section_size_type names_size,
|
||||
Sized_relobj_file<size, big_endian>* obj)
|
||||
{
|
||||
Compressed_section_map* uncompressed_sizes = new Compressed_section_map();
|
||||
Compressed_section_map* uncompressed_map = new Compressed_section_map();
|
||||
const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
|
||||
const unsigned char* p = pshdrs + shdr_size;
|
||||
|
||||
for (unsigned int i = 1; i < shnum; ++i, p += shdr_size)
|
||||
{
|
||||
typename elfcpp::Shdr<size, big_endian> shdr(p);
|
||||
|
@ -586,12 +601,38 @@ build_compressed_section_map(
|
|||
obj->section_contents(i, &len, false);
|
||||
uint64_t uncompressed_size = get_uncompressed_size(contents, len);
|
||||
if (uncompressed_size != -1ULL)
|
||||
(*uncompressed_sizes)[i] =
|
||||
convert_to_section_size_type(uncompressed_size);
|
||||
{
|
||||
Compressed_section_info info;
|
||||
info.size = convert_to_section_size_type(uncompressed_size);
|
||||
info.contents = NULL;
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
// If we're multi-threaded, it will help to decompress
|
||||
// any sections that will be needed during the Add_symbols
|
||||
// task, so that several decompressions can run in
|
||||
// parallel.
|
||||
if (parameters->options().threads())
|
||||
{
|
||||
unsigned char* uncompressed_data = NULL;
|
||||
if (need_decompressed_section(name))
|
||||
{
|
||||
uncompressed_data = new unsigned char[uncompressed_size];
|
||||
if (decompress_input_section(contents, len,
|
||||
uncompressed_data,
|
||||
uncompressed_size))
|
||||
info.contents = uncompressed_data;
|
||||
else
|
||||
delete[] uncompressed_data;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
(*uncompressed_map)[i] = info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return uncompressed_sizes;
|
||||
return uncompressed_map;
|
||||
}
|
||||
|
||||
// Read the sections and symbols from an object file.
|
||||
|
@ -2557,6 +2598,85 @@ Sized_relobj_file<size, big_endian>::do_get_global_symbol_counts(
|
|||
*used = count;
|
||||
}
|
||||
|
||||
// Return a view of the decompressed contents of a section. Set *PLEN
|
||||
// to the size. Set *IS_NEW to true if the contents need to be freed
|
||||
// by the caller.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
const unsigned char*
|
||||
Sized_relobj_file<size, big_endian>::do_decompressed_section_contents(
|
||||
unsigned int shndx,
|
||||
section_size_type* plen,
|
||||
bool* is_new)
|
||||
{
|
||||
section_size_type buffer_size;
|
||||
const unsigned char* buffer = this->section_contents(shndx, &buffer_size,
|
||||
false);
|
||||
|
||||
if (this->compressed_sections_ == NULL)
|
||||
{
|
||||
*plen = buffer_size;
|
||||
*is_new = false;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Compressed_section_map::const_iterator p =
|
||||
this->compressed_sections_->find(shndx);
|
||||
if (p == this->compressed_sections_->end())
|
||||
{
|
||||
*plen = buffer_size;
|
||||
*is_new = false;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
section_size_type uncompressed_size = p->second.size;
|
||||
if (p->second.contents != NULL)
|
||||
{
|
||||
*plen = uncompressed_size;
|
||||
*is_new = false;
|
||||
return p->second.contents;
|
||||
}
|
||||
|
||||
unsigned char* uncompressed_data = new unsigned char[uncompressed_size];
|
||||
if (!decompress_input_section(buffer,
|
||||
buffer_size,
|
||||
uncompressed_data,
|
||||
uncompressed_size))
|
||||
this->error(_("could not decompress section %s"),
|
||||
this->do_section_name(shndx).c_str());
|
||||
|
||||
// We could cache the results in p->second.contents and store
|
||||
// false in *IS_NEW, but build_compressed_section_map() would
|
||||
// have done so if it had expected it to be profitable. If
|
||||
// we reach this point, we expect to need the contents only
|
||||
// once in this pass.
|
||||
*plen = uncompressed_size;
|
||||
*is_new = true;
|
||||
return uncompressed_data;
|
||||
}
|
||||
|
||||
// Discard any buffers of uncompressed sections. This is done
|
||||
// at the end of the Add_symbols task.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Sized_relobj_file<size, big_endian>::do_discard_decompressed_sections()
|
||||
{
|
||||
if (this->compressed_sections_ == NULL)
|
||||
return;
|
||||
|
||||
for (Compressed_section_map::iterator p = this->compressed_sections_->begin();
|
||||
p != this->compressed_sections_->end();
|
||||
++p)
|
||||
{
|
||||
if (p->second.contents != NULL)
|
||||
{
|
||||
delete[] p->second.contents;
|
||||
p->second.contents = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Input_objects methods.
|
||||
|
||||
// Add a regular relocatable object to the list. Return false if this
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue