X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fobject.h;h=a15509a147c899bcc805911a9368adb0a03f4f08;hb=4120fa118fc46e07910c2f36d8ca0c790c2732b1;hp=8735f9e976cad99139d93ea8723bc2c98d153c31;hpb=487b39dfdd6cdfcac1124f2bcacd70a2da92f242;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/object.h b/gold/object.h index 8735f9e976..a15509a147 100644 --- a/gold/object.h +++ b/gold/object.h @@ -1,6 +1,6 @@ // object.h -- support for an object file for linking in gold -*- C++ -*- -// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2006-2015 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -41,13 +41,14 @@ class Cref; class Layout; class Output_data; class Output_section; +class Output_section_data; class Output_file; class Output_symtab_xindex; class Pluginobj; class Dynobj; class Object_merge_map; class Relocatable_relocs; -class Symbols_data; +struct Symbols_data; template class Stringpool_template; @@ -102,7 +103,7 @@ struct Symbol_location_info { std::string source_file; std::string enclosing_symbol_name; - int line_number; + elfcpp::STT enclosing_symbol_type; }; // Data about a single relocation section. This is read in @@ -314,6 +315,73 @@ class Got_offset_list Got_offset_list* got_next_; }; +// The Local_got_entry_key used to index the GOT offsets for local +// non-TLS symbols, and tp-relative offsets for TLS symbols. + +class Local_got_entry_key +{ + public: + Local_got_entry_key(unsigned int symndx, uint64_t addend) + : symndx_(symndx), addend_(addend) + {} + + // Whether this equals to another Local_got_entry_key. + bool + eq(const Local_got_entry_key& key) const + { + return (this->symndx_ == key.symndx_ && this->addend_ == key.addend_); + } + + // Compute a hash value for this using 64-bit FNV-1a hash. + size_t + hash_value() const + { + uint64_t h = 14695981039346656037ULL; // FNV offset basis. + uint64_t prime = 1099511628211ULL; + h = (h ^ static_cast(this->symndx_)) * prime; + h = (h ^ static_cast(this->addend_)) * prime; + return h; + } + + // Functors for associative containers. + struct equal_to + { + bool + operator()(const Local_got_entry_key& key1, + const Local_got_entry_key& key2) const + { return key1.eq(key2); } + }; + + struct hash + { + size_t + operator()(const Local_got_entry_key& key) const + { return key.hash_value(); } + }; + + private: + // The local symbol index. + unsigned int symndx_; + // The addend. + uint64_t addend_; +}; + +// Type for mapping section index to uncompressed size and contents. + +struct Compressed_section_info +{ + section_size_type size; + elfcpp::Elf_Xword flag; + const unsigned char* contents; +}; +typedef std::map Compressed_section_map; + +template +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). @@ -332,7 +400,8 @@ class Object : 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) { @@ -348,7 +417,7 @@ class Object this->input_file_->file().remove_object(); } - // Return the name of the object as we would report it to the tuser. + // Return the name of the object as we would report it to the user. const std::string& name() const { return this->name_; } @@ -363,6 +432,12 @@ class Object is_dynamic() const { return this->is_dynamic_; } + // Return the word size of the object file. + virtual int elfsize() const = 0; + + // Return TRUE if this is a big-endian object file. + virtual bool is_big_endian() const = 0; + // Return whether this object is needed--true if it is a dynamic // object which defines some symbol referenced by a regular object. // We keep the flag here rather than in Dynobj for convenience when @@ -507,7 +582,7 @@ class Object // Return the name of a section given a section index. std::string - section_name(unsigned int shndx) + section_name(unsigned int shndx) const { return this->do_section_name(shndx); } // Return the section flags given a section index. @@ -550,6 +625,13 @@ class Object output_section(unsigned int shndx) const { return this->do_output_section(shndx); } + // Given a section index, return its address. + // The return value will be -1U if the section is specially mapped, + // such as a merge section. + uint64_t + output_section_address(unsigned int shndx) + { return this->do_output_section_address(shndx); } + // Given a section index, return the offset in the Output_section. // The return value will be -1U if the section is specially mapped, // such as a merge section. @@ -700,6 +782,11 @@ class Object set_as_needed() { this->as_needed_ = true; } + // Clear flag that this object was linked with --as-needed. + void + clear_as_needed() + { this->as_needed_ = false; } + // Return whether this object was linked with --as-needed. bool as_needed() const @@ -718,12 +805,34 @@ class Object 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); + + // Discard any buffers of decompressed sections. This is done + // at the end of the Add_symbols task. + void + discard_decompressed_sections(); // Return the index of the first incremental relocation for symbol SYMNDX. unsigned int @@ -735,6 +844,11 @@ class Object get_incremental_reloc_count(unsigned int symndx) const { return this->do_get_incremental_reloc_count(symndx); } + // Return the output view for section SHNDX. + unsigned char* + get_output_view(unsigned int shndx, section_size_type* plen) const + { return this->do_get_output_view(shndx, plen); } + protected: // Returns NULL for Objects that are not dynamic objects. This method // is overridden in the Dynobj class. @@ -791,8 +905,9 @@ class Object // Return the location of the contents of a section. Implemented by // child class. - virtual Location - do_section_contents(unsigned int shndx) = 0; + virtual const unsigned char* + do_section_contents(unsigned int shndx, section_size_type* plen, + bool cache) = 0; // Get the size of a section--implemented by child class. virtual uint64_t @@ -800,7 +915,7 @@ class Object // Get the name of a section--implemented by child class. virtual std::string - do_section_name(unsigned int shndx) = 0; + do_section_name(unsigned int shndx) const = 0; // Get section flags--implemented by child class. virtual uint64_t @@ -836,6 +951,11 @@ class Object do_output_section(unsigned int) const { gold_unreachable(); } + // Get the address of a section--implemented by child class. + virtual uint64_t + do_output_section_address(unsigned int) + { gold_unreachable(); } + // Get the offset of a section--implemented by child class. virtual uint64_t do_output_section_offset(unsigned int) const @@ -865,6 +985,16 @@ class Object read_section_data(elfcpp::Elf_file*, Read_symbols_data*); + // Find the section header with the given NAME. If HDR is non-NULL + // then it is a section header returned from a previous call to this + // function and the next section header with the same name will be + // returned. + template + const unsigned char* + find_shdr(const unsigned char* pshdrs, const char* name, + const char* names, section_size_type names_size, + const unsigned char* hdr) const; + // Let the child class initialize the xindex object directly. void set_xindex(Xindex* xindex) @@ -886,11 +1016,11 @@ class Object 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; } + // Discard any buffers of decompressed sections. This is done + // at the end of the Add_symbols task. + virtual void + do_discard_decompressed_sections() + { } // Return the index of the first incremental relocation for symbol SYMNDX-- // implemented by child class. @@ -904,6 +1034,19 @@ class Object do_get_incremental_reloc_count(unsigned int) const { gold_unreachable(); } + // Return the output view for a section. + virtual unsigned char* + do_get_output_view(unsigned int, section_size_type*) 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&); @@ -938,6 +1081,9 @@ class 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. @@ -1009,6 +1155,66 @@ class Relobj : public Object scan_relocs(Symbol_table* symtab, Layout* layout, Read_relocs_data* rd) { return this->do_scan_relocs(symtab, layout, rd); } + // Return the value of the local symbol whose index is SYMNDX, plus + // ADDEND. ADDEND is passed in so that we can correctly handle the + // section symbol for a merge section. + uint64_t + local_symbol_value(unsigned int symndx, uint64_t addend) const + { return this->do_local_symbol_value(symndx, addend); } + + // Return the PLT offset for a local symbol. It is an error to call + // this if it doesn't have one. + unsigned int + local_plt_offset(unsigned int symndx) const + { return this->do_local_plt_offset(symndx); } + + // Return whether the local symbol SYMNDX has a GOT offset of type + // GOT_TYPE. + bool + local_has_got_offset(unsigned int symndx, unsigned int got_type) const + { return this->do_local_has_got_offset(symndx, got_type, 0); } + + // Return whether the local symbol SYMNDX plus ADDEND has a GOT offset + // of type GOT_TYPE. + bool + local_has_got_offset(unsigned int symndx, unsigned int got_type, + uint64_t addend) const + { return this->do_local_has_got_offset(symndx, got_type, addend); } + + // Return the GOT offset of type GOT_TYPE of the local symbol + // SYMNDX. It is an error to call this if the symbol does not have + // a GOT offset of the specified type. + unsigned int + local_got_offset(unsigned int symndx, unsigned int got_type) const + { return this->do_local_got_offset(symndx, got_type, 0); } + + // Return the GOT offset of type GOT_TYPE of the local symbol + // SYMNDX plus ADDEND. It is an error to call this if the symbol + // does not have a GOT offset of the specified type. + unsigned int + local_got_offset(unsigned int symndx, unsigned int got_type, + uint64_t addend) const + { return this->do_local_got_offset(symndx, got_type, addend); } + + // Set the GOT offset with type GOT_TYPE of the local symbol SYMNDX + // to GOT_OFFSET. + void + set_local_got_offset(unsigned int symndx, unsigned int got_type, + unsigned int got_offset) + { this->do_set_local_got_offset(symndx, got_type, got_offset, 0); } + + // Set the GOT offset with type GOT_TYPE of the local symbol SYMNDX + // plus ADDEND to GOT_OFFSET. + void + set_local_got_offset(unsigned int symndx, unsigned int got_type, + unsigned int got_offset, uint64_t addend) + { this->do_set_local_got_offset(symndx, got_type, got_offset, addend); } + + // Return whether the local symbol SYMNDX is a TLS symbol. + bool + local_is_tls(unsigned int symndx) const + { return this->do_local_is_tls(symndx); } + // The number of local symbols in the input symbol table. virtual unsigned int local_symbol_count() const @@ -1081,7 +1287,7 @@ class Relobj : public Object return this->output_sections_[shndx] != NULL; } - // The the output section of the input section with index SHNDX. + // The output section of the input section with index SHNDX. // This is only used currently to remove a section from the link in // relaxation. void @@ -1104,18 +1310,28 @@ class Relobj : public Object relocs_must_follow_section_writes() const { return this->relocs_must_follow_section_writes_; } - // Return the object merge map. Object_merge_map* - merge_map() const - { return this->object_merge_map_; } + get_or_create_merge_map(); - // Set the object merge map. + template void - set_merge_map(Object_merge_map* object_merge_map) - { - gold_assert(this->object_merge_map_ == NULL); - this->object_merge_map_ = object_merge_map; - } + initialize_input_to_output_map(unsigned int shndx, + typename elfcpp::Elf_types::Elf_Addr starting_address, + Unordered_map::Elf_Addr>* output_address) const; + + void + add_merge_mapping(Output_section_data *output_data, + unsigned int shndx, section_offset_type offset, + section_size_type length, + section_offset_type output_offset); + + bool + merge_output_offset(unsigned int shndx, section_offset_type offset, + section_offset_type *poutput) const; + + const Output_section_data* + find_merge_section(unsigned int shndx) const; // Record the relocatable reloc info for an input reloc section. void @@ -1149,6 +1365,16 @@ class Relobj : public Object do_get_incremental_reloc_count(unsigned int symndx) const { return this->reloc_counts_[symndx]; } + // Return the word size of the object file. + int + elfsize() const + { return this->do_elfsize(); } + + // Return TRUE if this is a big-endian object file. + bool + is_big_endian() const + { return this->do_is_big_endian(); } + protected: // The output section to be used for each input section, indexed by // the input section number. The output section is NULL if the @@ -1167,6 +1393,34 @@ class Relobj : public Object virtual void do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*) = 0; + // Return the value of a local symbol. + virtual uint64_t + do_local_symbol_value(unsigned int symndx, uint64_t addend) const = 0; + + // Return the PLT offset of a local symbol. + virtual unsigned int + do_local_plt_offset(unsigned int symndx) const = 0; + + // Return whether a local symbol plus addend has a GOT offset + // of a given type. + virtual bool + do_local_has_got_offset(unsigned int symndx, + unsigned int got_type, uint64_t addend) const = 0; + + // Return the GOT offset of a given type of a local symbol plus addend. + virtual unsigned int + do_local_got_offset(unsigned int symndx, unsigned int got_type, + uint64_t addend) const = 0; + + // Set the GOT offset with a given type for a local symbol plus addend. + virtual void + do_set_local_got_offset(unsigned int symndx, unsigned int got_type, + unsigned int got_offset, uint64_t addend) = 0; + + // Return whether local symbol SYMNDX is a TLS symbol. + virtual bool + do_local_is_tls(unsigned int symndx) const = 0; + // Return the number of local symbols--implemented by child class. virtual unsigned int do_local_symbol_count() const = 0; @@ -1285,6 +1539,16 @@ class Relobj : public Object return this->reloc_bases_[symndx] + counter; } + // Return the word size of the object file-- + // implemented by child class. + virtual int + do_elfsize() const = 0; + + // Return TRUE if this is a big-endian object file-- + // implemented by child class. + virtual bool + do_is_big_endian() const = 0; + private: // Mapping from input sections to output section. Output_sections output_sections_; @@ -1720,10 +1984,6 @@ class Reloc_symbol_changes std::vector vec_; }; -// Type for mapping section index to uncompressed size. - -typedef std::map 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. @@ -1775,47 +2035,6 @@ class Sized_relobj : public Relobj return this->section_offsets_[shndx]; } - // Return whether the local symbol SYMNDX has a GOT offset. - // For TLS symbols, the GOT entry will hold its tp-relative offset. - bool - local_has_got_offset(unsigned int symndx, unsigned int got_type) const - { - Local_got_offsets::const_iterator p = - this->local_got_offsets_.find(symndx); - return (p != this->local_got_offsets_.end() - && p->second->get_offset(got_type) != -1U); - } - - // Return the GOT offset of the local symbol SYMNDX. - unsigned int - local_got_offset(unsigned int symndx, unsigned int got_type) const - { - Local_got_offsets::const_iterator p = - this->local_got_offsets_.find(symndx); - gold_assert(p != this->local_got_offsets_.end()); - unsigned int off = p->second->get_offset(got_type); - gold_assert(off != -1U); - return off; - } - - // Set the GOT offset of the local symbol SYMNDX to GOT_OFFSET. - void - set_local_got_offset(unsigned int symndx, unsigned int got_type, - unsigned int got_offset) - { - Local_got_offsets::const_iterator p = - this->local_got_offsets_.find(symndx); - if (p != this->local_got_offsets_.end()) - p->second->set_offset(got_type, got_offset); - else - { - Got_offset_list* g = new Got_offset_list(got_type, got_offset); - std::pair ins = - this->local_got_offsets_.insert(std::make_pair(symndx, g)); - gold_assert(ins.second); - } - } - // Iterate over local symbols, calling a visitor class V for each GOT offset // associated with a local symbol. void @@ -1834,6 +2053,10 @@ class Sized_relobj : public Relobj section_offsets() { return this->section_offsets_; } + // Get the address of an output section. + uint64_t + do_output_section_address(unsigned int shndx); + // Get the offset of a section. uint64_t do_output_section_offset(unsigned int shndx) const @@ -1855,13 +2078,73 @@ class Sized_relobj : public Relobj : convert_types(off)); } + // Return whether the local symbol SYMNDX plus ADDEND has a GOT offset + // of type GOT_TYPE. + bool + do_local_has_got_offset(unsigned int symndx, unsigned int got_type, + uint64_t addend) const + { + Local_got_entry_key key(symndx, addend); + Local_got_offsets::const_iterator p = + this->local_got_offsets_.find(key); + return (p != this->local_got_offsets_.end() + && p->second->get_offset(got_type) != -1U); + } + + // Return the GOT offset of type GOT_TYPE of the local symbol + // SYMNDX plus ADDEND. + unsigned int + do_local_got_offset(unsigned int symndx, unsigned int got_type, + uint64_t addend) const + { + Local_got_entry_key key(symndx, addend); + Local_got_offsets::const_iterator p = + this->local_got_offsets_.find(key); + gold_assert(p != this->local_got_offsets_.end()); + unsigned int off = p->second->get_offset(got_type); + gold_assert(off != -1U); + return off; + } + + // Set the GOT offset with type GOT_TYPE of the local symbol SYMNDX + // plus ADDEND to GOT_OFFSET. + void + do_set_local_got_offset(unsigned int symndx, unsigned int got_type, + unsigned int got_offset, uint64_t addend) + { + Local_got_entry_key key(symndx, addend); + Local_got_offsets::const_iterator p = + this->local_got_offsets_.find(key); + if (p != this->local_got_offsets_.end()) + p->second->set_offset(got_type, got_offset); + else + { + Got_offset_list* g = new Got_offset_list(got_type, got_offset); + std::pair ins = + this->local_got_offsets_.insert(std::make_pair(key, g)); + gold_assert(ins.second); + } + } + + // Return the word size of the object file. + virtual int + do_elfsize() const + { return size; } + + // Return TRUE if this is a big-endian object file. + virtual bool + do_is_big_endian() const + { return big_endian; } + private: // The GOT offsets of local symbols. This map also stores GOT offsets // for tp-relative offsets for TLS symbols. - typedef Unordered_map Local_got_offsets; + typedef Unordered_map Local_got_offsets; // GOT offsets for local non-TLS symbols, and tp-relative offsets - // for TLS symbols, indexed by symbol number. + // for TLS symbols, indexed by local got entry key class. Local_got_offsets local_got_offsets_; // For each input section, the offset of the input section in its // output section. This is INVALID_ADDRESS if the input section requires a @@ -1912,6 +2195,11 @@ class Sized_relobj_file : public Sized_relobj sized_relobj() const { return this; } + // Return the ELF file type. + int + e_type() const + { return this->e_type_; } + // Return the number of symbols. This is only valid after // Object::add_symbols has been called. unsigned int @@ -1995,15 +2283,16 @@ class Sized_relobj_file : public Sized_relobj bool local_has_plt_offset(unsigned int symndx) const; - // Return the PLT offset for a local symbol. It is an error to call - // this if it doesn't have one. - unsigned int - local_plt_offset(unsigned int symndx) const; - // Set the PLT offset of the local symbol SYMNDX. void set_local_plt_offset(unsigned int symndx, unsigned int plt_offset); + // Adjust this local symbol value. Return false if the symbol + // should be discarded from the output file. + bool + adjust_local_symbol(Symbol_value* lv) const + { return this->do_adjust_local_symbol(lv); } + // Return the name of the symbol that spans the given offset in the // specified section in this object. This is used only for error // messages and is not particularly efficient. @@ -2033,6 +2322,10 @@ class Sized_relobj_file : public Sized_relobj Symbol_value* lv_out, const Symbol_table* symtab); + // Return true if the layout for this object was deferred. + bool is_deferred_layout() const + { return this->is_deferred_layout_; } + protected: typedef typename Sized_relobj::Output_sections Output_sections; @@ -2045,6 +2338,29 @@ class Sized_relobj_file : public Sized_relobj void do_read_symbols(Read_symbols_data*); + // Read the symbols. This is common code for all target-specific + // overrides of do_read_symbols. + void + base_read_symbols(Read_symbols_data*); + + // Return the value of a local symbol. + uint64_t + do_local_symbol_value(unsigned int symndx, uint64_t addend) const + { + const Symbol_value* symval = this->local_symbol(symndx); + return symval->value(this, addend); + } + + // Return the PLT offset for a local symbol. It is an error to call + // this if it doesn't have one. + unsigned int + do_local_plt_offset(unsigned int symndx) const; + + // Return whether local symbol SYMNDX is a TLS symbol. + bool + do_local_is_tls(unsigned int symndx) const + { return this->local_symbol(symndx)->is_tls_symbol(); } + // Return the number of local symbols. unsigned int do_local_symbol_count() const @@ -2123,13 +2439,23 @@ class Sized_relobj_file : public Sized_relobj // Get the name of a section. std::string - do_section_name(unsigned int shndx) + do_section_name(unsigned int shndx) const { return this->elf_file_.section_name(shndx); } // Return the location of the contents of a section. - Object::Location - do_section_contents(unsigned int shndx) - { return this->elf_file_.section_contents(shndx); } + const unsigned char* + do_section_contents(unsigned int shndx, section_size_type* plen, + bool cache) + { + Object::Location loc(this->elf_file_.section_contents(shndx)); + *plen = convert_to_section_size_type(loc.data_size); + if (*plen == 0) + { + static const unsigned char empty[1] = { '\0' }; + return empty; + } + return this->get_view(loc.file_offset, *plen, true, cache); + } // Return section flags. uint64_t @@ -2225,35 +2551,31 @@ class Sized_relobj_file : public Sized_relobj typedef std::vector Views; + // Stash away info for a number of special sections. + // Return true if any of the sections found require local symbols to be read. + virtual bool + do_find_special_sections(Read_symbols_data* sd); + // This may be overriden by a child class. virtual void do_relocate_sections(const Symbol_table* symtab, const Layout* layout, const unsigned char* pshdrs, Output_file* of, Views* pviews); + // Adjust this local symbol value. Return false if the symbol + // should be discarded from the output file. + virtual bool + do_adjust_local_symbol(Symbol_value*) const + { return true; } + // Allow a child to set output local symbol count. void 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; - return true; - } - return false; - } + // Return the output view for a section. + unsigned char* + do_get_output_view(unsigned int, section_size_type*) const; private: // For convenience. @@ -2306,9 +2628,18 @@ class Sized_relobj_file : public Sized_relobj // Layout an input section. void layout_section(Layout* layout, unsigned int shndx, const char* name, - typename This::Shdr& shdr, unsigned int reloc_shndx, + const typename This::Shdr& shdr, unsigned int reloc_shndx, unsigned int reloc_type); + // Layout an input .eh_frame section. + void + layout_eh_frame_section(Layout* layout, const unsigned char* symbols_data, + section_size_type symbols_size, + const unsigned char* symbol_names_data, + section_size_type symbol_names_size, + unsigned int shndx, const typename This::Shdr&, + unsigned int reloc_shndx, unsigned int reloc_type); + // Write section data to the output file. Record the views and // sizes in VIEWS for use when relocating. void @@ -2341,27 +2672,6 @@ class Sized_relobj_file : public Sized_relobj const Read_relocs_data::Relocs_list::iterator&, Relocatable_relocs*); - // Emit the relocs for --emit-relocs. - void - emit_relocs(const Relocate_info*, unsigned int, - unsigned int sh_type, const unsigned char* prelocs, - size_t reloc_count, Output_section*, Address output_offset, - unsigned char* view, Address address, - section_size_type view_size, - unsigned char* reloc_view, section_size_type reloc_view_size); - - // Emit the relocs for --emit-relocs, templatized on the type of the - // relocation section. - template - void - emit_relocs_reltype(const Relocate_info*, unsigned int, - const unsigned char* prelocs, size_t reloc_count, - Output_section*, Address output_offset, - unsigned char* view, Address address, - section_size_type view_size, - unsigned char* reloc_view, - section_size_type reloc_view_size); - // Scan the input relocations for --incremental. void incremental_relocs_scan(const Read_relocs_data::Relocs_list::iterator&); @@ -2495,6 +2805,9 @@ class Sized_relobj_file : public Sized_relobj // General access to the ELF file. elfcpp::Elf_file elf_file_; + // Type of ELF file (ET_REL or ET_EXEC). ET_EXEC files are allowed + // as input files only for the --just-symbols option. + int e_type_; // Index of SHT_SYMTAB section. unsigned int symtab_shndx_; // The number of local symbols. @@ -2523,12 +2836,15 @@ class Sized_relobj_file : public Sized_relobj // If this object has a GNU style .eh_frame section that is discarded in // output, record the index here. Otherwise it is -1U. unsigned int discarded_eh_frame_shndx_; + // True if the layout of this object was deferred, waiting for plugin + // replacement files. + bool is_deferred_layout_; // The list of sections whose layout was deferred. std::vector deferred_layout_; // The list of relocation sections whose layout was deferred. std::vector deferred_layout_relocs_; - // For compressed debug sections, map section index to uncompressed size. - Compressed_section_map* compressed_sections_; + // Pointer to the list of output views; valid only during do_relocate(). + const Views* output_views_; }; // A class to manage the list of all objects. @@ -2623,7 +2939,7 @@ class Input_objects // The list of dynamic objects included in the link. Dynobj_list dynobj_list_; // SONAMEs that we have seen. - Unordered_set sonames_; + Unordered_map sonames_; // Manage cross-references if requested. Cref* cref_; }; @@ -2644,6 +2960,8 @@ struct Relocate_info unsigned int reloc_shndx; // Section header of relocation section. const unsigned char* reloc_shdr; + // Info about how relocs should be handled + Relocatable_relocs* rr; // Section index of section being relocated. unsigned int data_shndx; // Section header of data section. @@ -2657,11 +2975,11 @@ struct Relocate_info // This is used to represent a section in an object and is used as the // key type for various section maps. -typedef std::pair Section_id; +typedef std::pair Section_id; // This is similar to Section_id but is used when the section // pointers are const. -typedef std::pair Const_section_id; +typedef std::pair Const_section_id; // The hash value is based on the address of an object in memory during // linking. It is okay to use this for looking up sections but never use