* 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:
Cary Coutant 2012-02-29 21:22:29 +00:00
parent 718cb7da5d
commit 5dd8762ad1
7 changed files with 246 additions and 66 deletions

View file

@ -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