+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>
PR gold/18152
const unsigned char*
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,
// but are not used here.
void
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();
+
this->set_shnum(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 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.
Dwo_file::~Dwo_file()
sd->verneed_size = 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)
{
// Get the dynamic symbols.
discarded_eh_frame_shndx_(-1U),
is_deferred_layout_(false),
deferred_layout_(),
- deferred_layout_relocs_(),
- compressed_sections_()
+ deferred_layout_relocs_()
{
this->e_type_ = ehdr.get_e_type();
}
unsigned int shnum,
const char* names,
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();
const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
if (uncompressed_size != -1ULL)
{
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];
if (decompress_input_section(contents, len,
this->has_eh_frame_ = true;
if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL)
- this->compressed_sections_
- = build_compressed_section_map(pshdrs, this->shnum(), names,
- sd->section_names_size, this);
+ {
+ 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()
&& parameters->options().gdb_index()
// 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(
+Object::decompressed_section_contents(
unsigned int shndx,
section_size_type* plen,
bool* is_new)
// 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()
+Object::discard_decompressed_sections()
{
if (this->compressed_sections_ == NULL)
return;
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
// or a 64-bit input object. This can be a regular object file
// (ET_REL) or a shared object (ET_DYN).
: name_(name), input_file_(input_file), offset_(offset), shnum_(-1U),
is_dynamic_(is_dynamic), is_needed_(false), uses_split_stack_(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)
{
set_no_export(bool 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
section_is_compressed(unsigned int shndx,
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
// to the size. Set *IS_NEW to true if the contents need to be freed
// by the caller.
const unsigned char*
decompressed_section_contents(unsigned int shndx, section_size_type* plen,
- bool* is_cached)
- { return this->do_decompressed_section_contents(shndx, plen, is_cached); }
+ bool* is_cached);
// Discard any buffers of decompressed sections. This is done
// at the end of the Add_symbols task.
void
- discard_decompressed_sections()
- { this->do_discard_decompressed_sections(); }
+ discard_decompressed_sections();
// Return the index of the first incremental relocation for symbol SYMNDX.
unsigned int
bool
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
// at the end of the Add_symbols task.
virtual void
do_get_incremental_reloc_count(unsigned int) const
{ 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:
// This class may not be copied.
Object(const Object&);
bool as_needed_ : 1;
// Many sections for objects with more than SHN_LORESERVE sections.
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.
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
// or an incremental (unchanged) object. This is size and endian specific.
set_output_local_symbol_count(unsigned int 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:
// For convenience.
typedef Sized_relobj_file<size, big_endian> This;
std::vector<Deferred_layout> deferred_layout_;
// The list of relocation sections whose layout was deferred.
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.