From e94cf1277329c4eaba3b398b446e693550463c77 Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Thu, 1 May 2008 01:23:21 +0000 Subject: * layout.cc (Layout::include_section): Refactored check for debug info section. (Layout::add_comdat): Add new parameters. Change type of signature parameter. Add object and shndx to signatures table. (Layout::find_kept_object): New function. * layout.h: Include . (Layout::is_debug_info_section): New function. (Layout::add_comdat): Add new parameters. (Layout::find_kept_object): New function. (Layout::Kept_section): New struct. (Layout::Signatures): Change type of map range. * object.cc (Relobj::output_section_address): New function. (Sized_relobj::include_section_group): Add new parameters. Change calls to Layout::add_comdat. Change to build table of kept comdat groups and table mapping discarded sections to kept sections. (Sized_relobj::include_linkonce_section): Likewise. Add new parameter. (Sized_relobj::do_layout): Change calls to include_section_group and include_linkonce_section. (Sized_relobj::do_finalize_local_symbols): Do not set local symbol value to zero when section is discarded. (Sized_relobj::map_to_kept_section): New function. * object.h (Relobj::output_section_address): New function. (Relobj::Comdat_group): New type. (Relobj::find_comdat_group): New function. (Relobj::Comdat_group_table): New type. (Relobj::Kept_comdat_section): New type. (Relobj::Kept_comdat_section_table): New type. (Relobj::add_comdat_group): New function. (Relobj::set_kept_comdat_section): New function. (Relobj::get_kept_comdat_section): New function. (Relobj::comdat_groups_): New field. (Relobj::kept_comdat_sections_): New field. (Symbol_value::input_value): Update comment. (Sized_relobj::map_to_kept_section) New function. (Sized_relobj::include_linkonce_section): Add new parameter. * target-reloc.h (Comdat_behavior): New type. (get_comdat_behavior): New function. (relocate_section): Add code to map a discarded section to the corresponding kept section when applying a relocation. --- gold/object.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 3 deletions(-) (limited to 'gold/object.h') diff --git a/gold/object.h b/gold/object.h index aaaa48d..52359af 100644 --- a/gold/object.h +++ b/gold/object.h @@ -561,6 +561,8 @@ class Relobj : public Object Relobj(const std::string& name, Input_file* input_file, off_t offset = 0) : Object(name, input_file, false, offset), map_to_output_(), + comdat_groups_(), + kept_comdat_sections_(), map_to_relocatable_relocs_(NULL), object_merge_map_(NULL), relocs_must_follow_section_writes_(false) @@ -647,6 +649,10 @@ class Relobj : public Object this->map_to_output_[shndx].offset = off; } + // Return the output address of the input section SHNDX. + uint64_t + output_section_address(unsigned int shndx) const; + // Return true if we need to wait for output sections to be written // before we can apply relocations. This is true if the object has // any relocations for sections which require special handling, such @@ -684,6 +690,24 @@ class Relobj : public Object return (*this->map_to_relocatable_relocs_)[reloc_shndx]; } + // Information needed to keep track of kept comdat groups. This is + // simply a map from the section name to its section index. This may + // not be a one-to-one mapping, but we ignore that possibility since + // this is used only to attempt to handle stray relocations from + // non-comdat debug sections that refer to comdat loadable sections. + typedef Unordered_map Comdat_group; + + // Find a comdat group table given its group section SHNDX. + Comdat_group* + find_comdat_group(unsigned int shndx) const + { + Comdat_group_table::const_iterator p = + this->comdat_groups_.find(shndx); + if (p != this->comdat_groups_.end()) + return p->second; + return NULL; + } + protected: // What we need to know to map an input section to an output // section. We keep an array of these, one for each input section, @@ -698,6 +722,23 @@ class Relobj : public Object section_offset_type offset; }; + // A map from group section index to the table of group members. + typedef std::map Comdat_group_table; + + // To keep track of discarded comdat sections, we need to map a member + // section index to the object and section index of the corresponding + // kept section. + struct Kept_comdat_section + { + Kept_comdat_section(Relobj* object, unsigned int shndx) + : object_(object), shndx_(shndx) + { } + Relobj* object_; + unsigned int shndx_; + }; + typedef std::map + Kept_comdat_section_table; + // Read the relocs--implemented by child class. virtual void do_read_relocs(Read_relocs_data*) = 0; @@ -745,6 +786,30 @@ class Relobj : public Object map_to_output() const { return this->map_to_output_; } + // Record a new comdat group whose group section index is SHNDX. + void + add_comdat_group(unsigned int shndx, Comdat_group* group) + { this->comdat_groups_[shndx] = group; } + + // Record a mapping from discarded section SHNDX to the corresponding + // kept section. + void + set_kept_comdat_section(unsigned int shndx, Kept_comdat_section* kept) + { + this->kept_comdat_sections_[shndx] = kept; + } + + // Find the kept section corresponding to the discarded section SHNDX. + Kept_comdat_section* + get_kept_comdat_section(unsigned int shndx) const + { + Kept_comdat_section_table::const_iterator p = + this->kept_comdat_sections_.find(shndx); + if (p == this->kept_comdat_sections_.end()) + return NULL; + return p->second; + } + // Set the size of the relocatable relocs array. void size_relocatable_relocs() @@ -762,6 +827,10 @@ class Relobj : public Object private: // Mapping from input sections to output section. std::vector map_to_output_; + // Table of kept comdat groups. + Comdat_group_table comdat_groups_; + // Table mapping discarded comdat sections to corresponding kept sections. + Kept_comdat_section_table kept_comdat_sections_; // Mapping from input section index to the information recorded for // the relocations. This is only used for a relocatable link. std::vector* map_to_relocatable_relocs_; @@ -927,7 +996,7 @@ class Symbol_value { this->u_.value = value; } // Return the input value. This is only called by - // finalize_local_symbols. + // finalize_local_symbols and (in special cases) relocate_section. Value input_value() const { return this->u_.value; } @@ -1288,6 +1357,12 @@ class Sized_relobj : public Relobj get_symbol_location_info(unsigned int shndx, off_t offset, Symbol_location_info* info); + // Look for a kept section corresponding to the given discarded section, + // and return its output address. This is used only for relocations in + // debugging sections. + Address + map_to_kept_section(unsigned int shndx, bool* found) const; + protected: // Read the symbols. void @@ -1421,12 +1496,12 @@ class Sized_relobj : public Relobj // Whether to include a section group in the link. bool include_section_group(Symbol_table*, Layout*, unsigned int, const char*, - const elfcpp::Shdr&, + const unsigned char*, const char *, section_size_type, std::vector*); // Whether to include a linkonce section in the link. bool - include_linkonce_section(Layout*, const char*, + include_linkonce_section(Layout*, unsigned int, const char*, const elfcpp::Shdr&); // Views and sizes when relocating. -- cgit v1.1