Support compressed debug sections in dynamic object files.
This patch adds support for reading compressed debug info in shared objects. It actually simplifies things, by moving the support for compressed sections all the way up to the top-level Object class, eliminating the need for several virtual methods. gold/ * dwp.cc (Sized_relobj_dwo::do_section_contents): Delete. (Sized_relobj_dwo::setup): Build compressed section map. (Sized_relobj_dwo::do_decompressed_section_contents): Delete. * dynobj.cc (Sized_dynobj::base_read_symbols): Build compressed section map. * object.cc (Sized_relobj_file::Sized_relobj_file): Remove compressed_sections_ field. (build_compressed_section_map): Take Object instead of Sized_relobj_file parameter; add decompress_if_needed parameter. (Sized_relobj_file::do_find_special_sections): Store compressed section map in parent Object. (Sized_relobj_file::do_decompressed_section_contents): Move implementation to Object::decompressed_section_contents. (Sized_relobj_file::do_discard_decompressed_sections): Move implementation to Object::discard_decompressed_sections. * object.h (build_compressed_section_map): Declare. (Object::Object): Add compressed_sections_ field. (Object::section_is_compressed): Move implementation here. (Object::decompressed_section_contents): De-virtualize. (Object::discard_decompressed_sections): De-virtualize. (Object::do_section_is_compressed): Delete. (Object::do_decompressed_section_contents): Delete. (Object::set_compressed_sections): New method. (Object::compressed_sections): New method. (Object::compressed_sections_): New data member. (Compressed_section_info, Compressed_section_map): Move to top of file. (Sized_relobj_file::do_section_is_compressed): Delete. (Sized_relobj_file::do_decompressed_section_contents): Delete. (Sized_relobj_file::do_discard_decompressed_sections): Delete. (Sized_relobj_file::compressed_sections_): Move to Object class.
This commit is contained in:
parent
bd9e0d4628
commit
0d5bbdb0e1
5 changed files with 128 additions and 129 deletions
|
@ -1,3 +1,36 @@
|
||||||
|
2015-03-21 Cary Coutant <cary@google.com>
|
||||||
|
|
||||||
|
* dwp.cc (Sized_relobj_dwo::do_section_contents): Delete.
|
||||||
|
(Sized_relobj_dwo::setup): Build compressed section map.
|
||||||
|
(Sized_relobj_dwo::do_decompressed_section_contents): Delete.
|
||||||
|
* dynobj.cc (Sized_dynobj::base_read_symbols): Build compressed
|
||||||
|
section map.
|
||||||
|
* object.cc (Sized_relobj_file::Sized_relobj_file): Remove
|
||||||
|
compressed_sections_ field.
|
||||||
|
(build_compressed_section_map): Take Object instead of
|
||||||
|
Sized_relobj_file parameter; add decompress_if_needed parameter.
|
||||||
|
(Sized_relobj_file::do_find_special_sections): Store compressed
|
||||||
|
section map in parent Object.
|
||||||
|
(Sized_relobj_file::do_decompressed_section_contents): Move
|
||||||
|
implementation to Object::decompressed_section_contents.
|
||||||
|
(Sized_relobj_file::do_discard_decompressed_sections): Move
|
||||||
|
implementation to Object::discard_decompressed_sections.
|
||||||
|
* object.h (build_compressed_section_map): Declare.
|
||||||
|
(Object::Object): Add compressed_sections_ field.
|
||||||
|
(Object::section_is_compressed): Move implementation here.
|
||||||
|
(Object::decompressed_section_contents): De-virtualize.
|
||||||
|
(Object::discard_decompressed_sections): De-virtualize.
|
||||||
|
(Object::do_section_is_compressed): Delete.
|
||||||
|
(Object::do_decompressed_section_contents): Delete.
|
||||||
|
(Object::set_compressed_sections): New method.
|
||||||
|
(Object::compressed_sections): New method.
|
||||||
|
(Object::compressed_sections_): New data member.
|
||||||
|
(Compressed_section_info, Compressed_section_map): Move to top of file.
|
||||||
|
(Sized_relobj_file::do_section_is_compressed): Delete.
|
||||||
|
(Sized_relobj_file::do_decompressed_section_contents): Delete.
|
||||||
|
(Sized_relobj_file::do_discard_decompressed_sections): Delete.
|
||||||
|
(Sized_relobj_file::compressed_sections_): Move to Object class.
|
||||||
|
|
||||||
2015-03-21 Cary Coutant <ccoutant@google.com>
|
2015-03-21 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
PR gold/18152
|
PR gold/18152
|
||||||
|
|
72
gold/dwp.cc
72
gold/dwp.cc
|
@ -284,14 +284,6 @@ class Sized_relobj_dwo : public Sized_relobj<size, big_endian>
|
||||||
const unsigned char*
|
const unsigned char*
|
||||||
do_section_contents(unsigned int, section_size_type*, bool);
|
do_section_contents(unsigned int, section_size_type*, bool);
|
||||||
|
|
||||||
// Return a view of the uncompressed contents of a section. Set *PLEN
|
|
||||||
// to the size. Set *IS_NEW to true if the contents need to be deleted
|
|
||||||
// by the caller.
|
|
||||||
const unsigned char*
|
|
||||||
do_decompressed_section_contents(unsigned int shndx,
|
|
||||||
section_size_type* plen,
|
|
||||||
bool* is_new);
|
|
||||||
|
|
||||||
// The following virtual functions are abstract in the base classes,
|
// The following virtual functions are abstract in the base classes,
|
||||||
// but are not used here.
|
// but are not used here.
|
||||||
|
|
||||||
|
@ -781,9 +773,36 @@ template <int size, bool big_endian>
|
||||||
void
|
void
|
||||||
Sized_relobj_dwo<size, big_endian>::setup()
|
Sized_relobj_dwo<size, big_endian>::setup()
|
||||||
{
|
{
|
||||||
|
const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
|
||||||
|
const off_t shoff = this->elf_file_.shoff();
|
||||||
const unsigned int shnum = this->elf_file_.shnum();
|
const unsigned int shnum = this->elf_file_.shnum();
|
||||||
|
|
||||||
this->set_shnum(shnum);
|
this->set_shnum(shnum);
|
||||||
this->section_offsets().resize(shnum);
|
this->section_offsets().resize(shnum);
|
||||||
|
|
||||||
|
// Read the section headers.
|
||||||
|
const unsigned char* const pshdrs = this->get_view(shoff, shnum * shdr_size,
|
||||||
|
true, false);
|
||||||
|
|
||||||
|
// Read the section names.
|
||||||
|
const unsigned char* pshdrnames =
|
||||||
|
pshdrs + this->elf_file_.shstrndx() * shdr_size;
|
||||||
|
typename elfcpp::Shdr<size, big_endian> shdrnames(pshdrnames);
|
||||||
|
if (shdrnames.get_sh_type() != elfcpp::SHT_STRTAB)
|
||||||
|
this->error(_("section name section has wrong type: %u"),
|
||||||
|
static_cast<unsigned int>(shdrnames.get_sh_type()));
|
||||||
|
section_size_type section_names_size =
|
||||||
|
convert_to_section_size_type(shdrnames.get_sh_size());
|
||||||
|
const unsigned char* namesu = this->get_view(shdrnames.get_sh_offset(),
|
||||||
|
section_names_size, false,
|
||||||
|
false);
|
||||||
|
const char* names = reinterpret_cast<const char*>(namesu);
|
||||||
|
|
||||||
|
Compressed_section_map* compressed_sections =
|
||||||
|
build_compressed_section_map<size, big_endian>(
|
||||||
|
pshdrs, this->shnum(), names, section_names_size, this, true);
|
||||||
|
if (compressed_sections != NULL && !compressed_sections->empty())
|
||||||
|
this->set_compressed_sections(compressed_sections);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a view of the contents of a section.
|
// Return a view of the contents of a section.
|
||||||
|
@ -805,43 +824,6 @@ Sized_relobj_dwo<size, big_endian>::do_section_contents(
|
||||||
return this->get_view(loc.file_offset, *plen, true, cache);
|
return this->get_view(loc.file_offset, *plen, true, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a view of the uncompressed contents of a section. Set *PLEN
|
|
||||||
// to the size. Set *IS_NEW to true if the contents need to be deleted
|
|
||||||
// by the caller.
|
|
||||||
|
|
||||||
template <int size, bool big_endian>
|
|
||||||
const unsigned char*
|
|
||||||
Sized_relobj_dwo<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->do_section_contents(shndx, &buffer_size,
|
|
||||||
false);
|
|
||||||
|
|
||||||
std::string sect_name = this->do_section_name(shndx);
|
|
||||||
if (!is_prefix_of(".zdebug_", sect_name.c_str()))
|
|
||||||
{
|
|
||||||
*plen = buffer_size;
|
|
||||||
*is_new = false;
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
section_size_type uncompressed_size = get_uncompressed_size(buffer,
|
|
||||||
buffer_size);
|
|
||||||
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->section_name(shndx).c_str());
|
|
||||||
*plen = uncompressed_size;
|
|
||||||
*is_new = true;
|
|
||||||
return uncompressed_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class Dwo_file.
|
// Class Dwo_file.
|
||||||
|
|
||||||
Dwo_file::~Dwo_file()
|
Dwo_file::~Dwo_file()
|
||||||
|
|
|
@ -374,6 +374,17 @@ Sized_dynobj<size, big_endian>::base_read_symbols(Read_symbols_data* sd)
|
||||||
sd->verneed_size = 0;
|
sd->verneed_size = 0;
|
||||||
sd->verneed_info = 0;
|
sd->verneed_info = 0;
|
||||||
|
|
||||||
|
const unsigned char* namesu = sd->section_names->data();
|
||||||
|
const char* names = reinterpret_cast<const char*>(namesu);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
if (this->dynsym_shndx_ != -1U)
|
if (this->dynsym_shndx_ != -1U)
|
||||||
{
|
{
|
||||||
// Get the dynamic symbols.
|
// Get the dynamic symbols.
|
||||||
|
|
|
@ -477,8 +477,7 @@ Sized_relobj_file<size, big_endian>::Sized_relobj_file(
|
||||||
discarded_eh_frame_shndx_(-1U),
|
discarded_eh_frame_shndx_(-1U),
|
||||||
is_deferred_layout_(false),
|
is_deferred_layout_(false),
|
||||||
deferred_layout_(),
|
deferred_layout_(),
|
||||||
deferred_layout_relocs_(),
|
deferred_layout_relocs_()
|
||||||
compressed_sections_()
|
|
||||||
{
|
{
|
||||||
this->e_type_ = ehdr.get_e_type();
|
this->e_type_ = ehdr.get_e_type();
|
||||||
}
|
}
|
||||||
|
@ -720,7 +719,8 @@ build_compressed_section_map(
|
||||||
unsigned int shnum,
|
unsigned int shnum,
|
||||||
const char* names,
|
const char* names,
|
||||||
section_size_type names_size,
|
section_size_type names_size,
|
||||||
Sized_relobj_file<size, big_endian>* obj)
|
Object* obj,
|
||||||
|
bool decompress_if_needed)
|
||||||
{
|
{
|
||||||
Compressed_section_map* uncompressed_map = 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 int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
|
||||||
|
@ -752,7 +752,7 @@ build_compressed_section_map(
|
||||||
if (uncompressed_size != -1ULL)
|
if (uncompressed_size != -1ULL)
|
||||||
{
|
{
|
||||||
unsigned char* uncompressed_data = NULL;
|
unsigned char* uncompressed_data = NULL;
|
||||||
if (need_decompressed_section(name))
|
if (decompress_if_needed && need_decompressed_section(name))
|
||||||
{
|
{
|
||||||
uncompressed_data = new unsigned char[uncompressed_size];
|
uncompressed_data = new unsigned char[uncompressed_size];
|
||||||
if (decompress_input_section(contents, len,
|
if (decompress_input_section(contents, len,
|
||||||
|
@ -786,9 +786,14 @@ Sized_relobj_file<size, big_endian>::do_find_special_sections(
|
||||||
this->has_eh_frame_ = true;
|
this->has_eh_frame_ = true;
|
||||||
|
|
||||||
if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL)
|
if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL)
|
||||||
this->compressed_sections_
|
{
|
||||||
= build_compressed_section_map(pshdrs, this->shnum(), names,
|
Compressed_section_map* compressed_sections =
|
||||||
sd->section_names_size, this);
|
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_
|
return (this->has_eh_frame_
|
||||||
|| (!parameters->options().relocatable()
|
|| (!parameters->options().relocatable()
|
||||||
&& parameters->options().gdb_index()
|
&& parameters->options().gdb_index()
|
||||||
|
@ -2849,9 +2854,8 @@ Sized_relobj_file<size, big_endian>::do_get_global_symbol_counts(
|
||||||
// to the size. Set *IS_NEW to true if the contents need to be freed
|
// to the size. Set *IS_NEW to true if the contents need to be freed
|
||||||
// by the caller.
|
// by the caller.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
|
||||||
const unsigned char*
|
const unsigned char*
|
||||||
Sized_relobj_file<size, big_endian>::do_decompressed_section_contents(
|
Object::decompressed_section_contents(
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
section_size_type* plen,
|
section_size_type* plen,
|
||||||
bool* is_new)
|
bool* is_new)
|
||||||
|
@ -2905,9 +2909,8 @@ Sized_relobj_file<size, big_endian>::do_decompressed_section_contents(
|
||||||
// Discard any buffers of uncompressed sections. This is done
|
// Discard any buffers of uncompressed sections. This is done
|
||||||
// at the end of the Add_symbols task.
|
// at the end of the Add_symbols task.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
|
||||||
void
|
void
|
||||||
Sized_relobj_file<size, big_endian>::do_discard_decompressed_sections()
|
Object::discard_decompressed_sections()
|
||||||
{
|
{
|
||||||
if (this->compressed_sections_ == NULL)
|
if (this->compressed_sections_ == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
116
gold/object.h
116
gold/object.h
|
@ -315,6 +315,21 @@ class Got_offset_list
|
||||||
Got_offset_list* got_next_;
|
Got_offset_list* got_next_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Type for mapping section index to uncompressed size and contents.
|
||||||
|
|
||||||
|
struct Compressed_section_info
|
||||||
|
{
|
||||||
|
section_size_type size;
|
||||||
|
const unsigned char* contents;
|
||||||
|
};
|
||||||
|
typedef std::map<unsigned int, Compressed_section_info> Compressed_section_map;
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
Compressed_section_map*
|
||||||
|
build_compressed_section_map(const unsigned char* pshdrs, unsigned int shnum,
|
||||||
|
const char* names, section_size_type names_size,
|
||||||
|
Object* obj, bool decompress_if_needed);
|
||||||
|
|
||||||
// Object is an abstract base class which represents either a 32-bit
|
// Object is an abstract base class which represents either a 32-bit
|
||||||
// or a 64-bit input object. This can be a regular object file
|
// or a 64-bit input object. This can be a regular object file
|
||||||
// (ET_REL) or a shared object (ET_DYN).
|
// (ET_REL) or a shared object (ET_DYN).
|
||||||
|
@ -333,7 +348,8 @@ class Object
|
||||||
: name_(name), input_file_(input_file), offset_(offset), shnum_(-1U),
|
: name_(name), input_file_(input_file), offset_(offset), shnum_(-1U),
|
||||||
is_dynamic_(is_dynamic), is_needed_(false), uses_split_stack_(false),
|
is_dynamic_(is_dynamic), is_needed_(false), uses_split_stack_(false),
|
||||||
has_no_split_stack_(false), no_export_(false),
|
has_no_split_stack_(false), no_export_(false),
|
||||||
is_in_system_directory_(false), as_needed_(false), xindex_(NULL)
|
is_in_system_directory_(false), as_needed_(false), xindex_(NULL),
|
||||||
|
compressed_sections_(NULL)
|
||||||
{
|
{
|
||||||
if (input_file != NULL)
|
if (input_file != NULL)
|
||||||
{
|
{
|
||||||
|
@ -726,26 +742,34 @@ class Object
|
||||||
set_no_export(bool value)
|
set_no_export(bool value)
|
||||||
{ this->no_export_ = value; }
|
{ this->no_export_ = value; }
|
||||||
|
|
||||||
// Return TRUE if the section is a compressed debug section, and set
|
|
||||||
// *UNCOMPRESSED_SIZE to the size of the uncompressed data.
|
|
||||||
bool
|
bool
|
||||||
section_is_compressed(unsigned int shndx,
|
section_is_compressed(unsigned int shndx,
|
||||||
section_size_type* uncompressed_size) const
|
section_size_type* uncompressed_size) const
|
||||||
{ return this->do_section_is_compressed(shndx, uncompressed_size); }
|
{
|
||||||
|
if (this->compressed_sections_ == NULL)
|
||||||
|
return false;
|
||||||
|
Compressed_section_map::const_iterator p =
|
||||||
|
this->compressed_sections_->find(shndx);
|
||||||
|
if (p != this->compressed_sections_->end())
|
||||||
|
{
|
||||||
|
if (uncompressed_size != NULL)
|
||||||
|
*uncompressed_size = p->second.size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Return a view of the decompressed contents of a section. Set *PLEN
|
// 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
|
// to the size. Set *IS_NEW to true if the contents need to be freed
|
||||||
// by the caller.
|
// by the caller.
|
||||||
const unsigned char*
|
const unsigned char*
|
||||||
decompressed_section_contents(unsigned int shndx, section_size_type* plen,
|
decompressed_section_contents(unsigned int shndx, section_size_type* plen,
|
||||||
bool* is_cached)
|
bool* is_cached);
|
||||||
{ return this->do_decompressed_section_contents(shndx, plen, is_cached); }
|
|
||||||
|
|
||||||
// Discard any buffers of decompressed sections. This is done
|
// Discard any buffers of decompressed sections. This is done
|
||||||
// at the end of the Add_symbols task.
|
// at the end of the Add_symbols task.
|
||||||
void
|
void
|
||||||
discard_decompressed_sections()
|
discard_decompressed_sections();
|
||||||
{ this->do_discard_decompressed_sections(); }
|
|
||||||
|
|
||||||
// Return the index of the first incremental relocation for symbol SYMNDX.
|
// Return the index of the first incremental relocation for symbol SYMNDX.
|
||||||
unsigned int
|
unsigned int
|
||||||
|
@ -924,27 +948,6 @@ class Object
|
||||||
bool
|
bool
|
||||||
handle_split_stack_section(const char* name);
|
handle_split_stack_section(const char* name);
|
||||||
|
|
||||||
// Return TRUE if the section is a compressed debug section, and set
|
|
||||||
// *UNCOMPRESSED_SIZE to the size of the uncompressed data.
|
|
||||||
virtual bool
|
|
||||||
do_section_is_compressed(unsigned int, section_size_type*) const
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
// Return a view of the decompressed contents of a section. Set *PLEN
|
|
||||||
// to the size. This default implementation simply returns the
|
|
||||||
// raw section contents and sets *IS_NEW to false to indicate
|
|
||||||
// that the contents do not need to be freed by the caller.
|
|
||||||
// This function must be overridden for any types of object files
|
|
||||||
// that might contain compressed sections.
|
|
||||||
virtual const unsigned char*
|
|
||||||
do_decompressed_section_contents(unsigned int shndx,
|
|
||||||
section_size_type* plen,
|
|
||||||
bool* is_new)
|
|
||||||
{
|
|
||||||
*is_new = false;
|
|
||||||
return this->do_section_contents(shndx, plen, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Discard any buffers of decompressed sections. This is done
|
// Discard any buffers of decompressed sections. This is done
|
||||||
// at the end of the Add_symbols task.
|
// at the end of the Add_symbols task.
|
||||||
virtual void
|
virtual void
|
||||||
|
@ -963,6 +966,14 @@ class Object
|
||||||
do_get_incremental_reloc_count(unsigned int) const
|
do_get_incremental_reloc_count(unsigned int) const
|
||||||
{ gold_unreachable(); }
|
{ gold_unreachable(); }
|
||||||
|
|
||||||
|
void
|
||||||
|
set_compressed_sections(Compressed_section_map* compressed_sections)
|
||||||
|
{ this->compressed_sections_ = compressed_sections; }
|
||||||
|
|
||||||
|
Compressed_section_map*
|
||||||
|
compressed_sections()
|
||||||
|
{ return this->compressed_sections_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This class may not be copied.
|
// This class may not be copied.
|
||||||
Object(const Object&);
|
Object(const Object&);
|
||||||
|
@ -997,6 +1008,9 @@ class Object
|
||||||
bool as_needed_ : 1;
|
bool as_needed_ : 1;
|
||||||
// Many sections for objects with more than SHN_LORESERVE sections.
|
// Many sections for objects with more than SHN_LORESERVE sections.
|
||||||
Xindex* xindex_;
|
Xindex* xindex_;
|
||||||
|
// For compressed debug sections, map section index to uncompressed size
|
||||||
|
// and contents.
|
||||||
|
Compressed_section_map* compressed_sections_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A regular object (ET_REL). This is an abstract base class itself.
|
// A regular object (ET_REL). This is an abstract base class itself.
|
||||||
|
@ -1871,15 +1885,6 @@ class Reloc_symbol_changes
|
||||||
std::vector<Symbol*> vec_;
|
std::vector<Symbol*> vec_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type for mapping section index to uncompressed size and contents.
|
|
||||||
|
|
||||||
struct Compressed_section_info
|
|
||||||
{
|
|
||||||
section_size_type size;
|
|
||||||
const unsigned char* contents;
|
|
||||||
};
|
|
||||||
typedef std::map<unsigned int, Compressed_section_info> Compressed_section_map;
|
|
||||||
|
|
||||||
// Abstract base class for a regular object file, either a real object file
|
// Abstract base class for a regular object file, either a real object file
|
||||||
// or an incremental (unchanged) object. This is size and endian specific.
|
// or an incremental (unchanged) object. This is size and endian specific.
|
||||||
|
|
||||||
|
@ -2462,38 +2467,6 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
||||||
set_output_local_symbol_count(unsigned int value)
|
set_output_local_symbol_count(unsigned int value)
|
||||||
{ this->output_local_symbol_count_ = value; }
|
{ this->output_local_symbol_count_ = value; }
|
||||||
|
|
||||||
// Return TRUE if the section is a compressed debug section, and set
|
|
||||||
// *UNCOMPRESSED_SIZE to the size of the uncompressed data.
|
|
||||||
bool
|
|
||||||
do_section_is_compressed(unsigned int shndx,
|
|
||||||
section_size_type* uncompressed_size) const
|
|
||||||
{
|
|
||||||
if (this->compressed_sections_ == NULL)
|
|
||||||
return false;
|
|
||||||
Compressed_section_map::const_iterator p =
|
|
||||||
this->compressed_sections_->find(shndx);
|
|
||||||
if (p != this->compressed_sections_->end())
|
|
||||||
{
|
|
||||||
if (uncompressed_size != NULL)
|
|
||||||
*uncompressed_size = p->second.size;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a view of the uncompressed contents of a section. Set *PLEN
|
|
||||||
// to the size. Set *IS_NEW to true if the contents need to be deleted
|
|
||||||
// by the caller.
|
|
||||||
const unsigned char*
|
|
||||||
do_decompressed_section_contents(unsigned int shndx,
|
|
||||||
section_size_type* plen,
|
|
||||||
bool* is_new);
|
|
||||||
|
|
||||||
// Discard any buffers of decompressed sections. This is done
|
|
||||||
// at the end of the Add_symbols task.
|
|
||||||
void
|
|
||||||
do_discard_decompressed_sections();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// For convenience.
|
// For convenience.
|
||||||
typedef Sized_relobj_file<size, big_endian> This;
|
typedef Sized_relobj_file<size, big_endian> This;
|
||||||
|
@ -2760,9 +2733,6 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
||||||
std::vector<Deferred_layout> deferred_layout_;
|
std::vector<Deferred_layout> deferred_layout_;
|
||||||
// The list of relocation sections whose layout was deferred.
|
// The list of relocation sections whose layout was deferred.
|
||||||
std::vector<Deferred_layout> deferred_layout_relocs_;
|
std::vector<Deferred_layout> deferred_layout_relocs_;
|
||||||
// For compressed debug sections, map section index to uncompressed size
|
|
||||||
// and contents.
|
|
||||||
Compressed_section_map* compressed_sections_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A class to manage the list of all objects.
|
// A class to manage the list of all objects.
|
||||||
|
|
Loading…
Reference in a new issue