12a6b7db3Sskrll // dynobj.h -- dynamic object support for gold -*- C++ -*- 22a6b7db3Sskrll 3*f22f0ef4Schristos // Copyright (C) 2006-2022 Free Software Foundation, Inc. 42a6b7db3Sskrll // Written by Ian Lance Taylor <iant@google.com>. 52a6b7db3Sskrll 62a6b7db3Sskrll // This file is part of gold. 72a6b7db3Sskrll 82a6b7db3Sskrll // This program is free software; you can redistribute it and/or modify 92a6b7db3Sskrll // it under the terms of the GNU General Public License as published by 102a6b7db3Sskrll // the Free Software Foundation; either version 3 of the License, or 112a6b7db3Sskrll // (at your option) any later version. 122a6b7db3Sskrll 132a6b7db3Sskrll // This program is distributed in the hope that it will be useful, 142a6b7db3Sskrll // but WITHOUT ANY WARRANTY; without even the implied warranty of 152a6b7db3Sskrll // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 162a6b7db3Sskrll // GNU General Public License for more details. 172a6b7db3Sskrll 182a6b7db3Sskrll // You should have received a copy of the GNU General Public License 192a6b7db3Sskrll // along with this program; if not, write to the Free Software 202a6b7db3Sskrll // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 212a6b7db3Sskrll // MA 02110-1301, USA. 222a6b7db3Sskrll 232a6b7db3Sskrll #ifndef GOLD_DYNOBJ_H 242a6b7db3Sskrll #define GOLD_DYNOBJ_H 252a6b7db3Sskrll 262a6b7db3Sskrll #include <vector> 272a6b7db3Sskrll 282a6b7db3Sskrll #include "stringpool.h" 292a6b7db3Sskrll #include "object.h" 302a6b7db3Sskrll 312a6b7db3Sskrll namespace gold 322a6b7db3Sskrll { 332a6b7db3Sskrll 342a6b7db3Sskrll class Version_script_info; 352a6b7db3Sskrll 362a6b7db3Sskrll // A dynamic object (ET_DYN). This is an abstract base class itself. 372a6b7db3Sskrll // The implementations is the template class Sized_dynobj. 382a6b7db3Sskrll 392a6b7db3Sskrll class Dynobj : public Object 402a6b7db3Sskrll { 412a6b7db3Sskrll public: 422a6b7db3Sskrll // We keep a list of all the DT_NEEDED entries we find. 432a6b7db3Sskrll typedef std::vector<std::string> Needed; 442a6b7db3Sskrll 452a6b7db3Sskrll Dynobj(const std::string& name, Input_file* input_file, off_t offset = 0); 462a6b7db3Sskrll 472a6b7db3Sskrll // Return the name to use in a DT_NEEDED entry for this object. 482a6b7db3Sskrll const char* soname()492a6b7db3Sskrll soname() const 502a6b7db3Sskrll { return this->soname_.c_str(); } 512a6b7db3Sskrll 522a6b7db3Sskrll // Return the list of DT_NEEDED strings. 532a6b7db3Sskrll const Needed& needed()542a6b7db3Sskrll needed() const 552a6b7db3Sskrll { return this->needed_; } 562a6b7db3Sskrll 572a6b7db3Sskrll // Return whether this dynamic object has any DT_NEEDED entries 582a6b7db3Sskrll // which were not seen during the link. 592a6b7db3Sskrll bool has_unknown_needed_entries()602a6b7db3Sskrll has_unknown_needed_entries() const 612a6b7db3Sskrll { 622a6b7db3Sskrll gold_assert(this->unknown_needed_ != UNKNOWN_NEEDED_UNSET); 632a6b7db3Sskrll return this->unknown_needed_ == UNKNOWN_NEEDED_TRUE; 642a6b7db3Sskrll } 652a6b7db3Sskrll 662a6b7db3Sskrll // Set whether this dynamic object has any DT_NEEDED entries which 672a6b7db3Sskrll // were not seen during the link. 682a6b7db3Sskrll void set_has_unknown_needed_entries(bool set)692a6b7db3Sskrll set_has_unknown_needed_entries(bool set) 702a6b7db3Sskrll { 712a6b7db3Sskrll gold_assert(this->unknown_needed_ == UNKNOWN_NEEDED_UNSET); 722a6b7db3Sskrll this->unknown_needed_ = set ? UNKNOWN_NEEDED_TRUE : UNKNOWN_NEEDED_FALSE; 732a6b7db3Sskrll } 742a6b7db3Sskrll 755ba6b03cSchristos // Return the word size of the object file. 765ba6b03cSchristos int elfsize()775ba6b03cSchristos elfsize() const 785ba6b03cSchristos { gold_unreachable(); } 795ba6b03cSchristos 805ba6b03cSchristos // Return TRUE if this is a big-endian object file. 815ba6b03cSchristos bool is_big_endian()825ba6b03cSchristos is_big_endian() const 835ba6b03cSchristos { gold_unreachable(); } 845ba6b03cSchristos 852a6b7db3Sskrll // Compute the ELF hash code for a string. 862a6b7db3Sskrll static uint32_t 872a6b7db3Sskrll elf_hash(const char*); 882a6b7db3Sskrll 892a6b7db3Sskrll // Create a standard ELF hash table, setting *PPHASH and *PHASHLEN. 902a6b7db3Sskrll // DYNSYMS is the global dynamic symbols. LOCAL_DYNSYM_COUNT is the 912a6b7db3Sskrll // number of local dynamic symbols, which is the index of the first 922a6b7db3Sskrll // dynamic gobal symbol. 932a6b7db3Sskrll static void 942a6b7db3Sskrll create_elf_hash_table(const std::vector<Symbol*>& dynsyms, 952a6b7db3Sskrll unsigned int local_dynsym_count, 962a6b7db3Sskrll unsigned char** pphash, 972a6b7db3Sskrll unsigned int* phashlen); 982a6b7db3Sskrll 992a6b7db3Sskrll // Create a GNU hash table, setting *PPHASH and *PHASHLEN. DYNSYMS 1002a6b7db3Sskrll // is the global dynamic symbols. LOCAL_DYNSYM_COUNT is the number 1012a6b7db3Sskrll // of local dynamic symbols, which is the index of the first dynamic 1022a6b7db3Sskrll // gobal symbol. 1032a6b7db3Sskrll static void 1042a6b7db3Sskrll create_gnu_hash_table(const std::vector<Symbol*>& dynsyms, 1052a6b7db3Sskrll unsigned int local_dynsym_count, 1062a6b7db3Sskrll unsigned char** pphash, unsigned int* phashlen); 1072a6b7db3Sskrll 1082a6b7db3Sskrll protected: 10905caefcfSchristos // Return a pointer to this object. 11005caefcfSchristos virtual Dynobj* do_dynobj()11105caefcfSchristos do_dynobj() 11205caefcfSchristos { return this; } 11305caefcfSchristos 1142a6b7db3Sskrll // Set the DT_SONAME string. 1152a6b7db3Sskrll void set_soname_string(const char * s)1162a6b7db3Sskrll set_soname_string(const char* s) 1172a6b7db3Sskrll { this->soname_.assign(s); } 1182a6b7db3Sskrll 1192a6b7db3Sskrll // Add an entry to the list of DT_NEEDED strings. 1202a6b7db3Sskrll void add_needed(const char * s)1212a6b7db3Sskrll add_needed(const char* s) 1222a6b7db3Sskrll { this->needed_.push_back(std::string(s)); } 1232a6b7db3Sskrll 1242a6b7db3Sskrll private: 1252a6b7db3Sskrll // Compute the GNU hash code for a string. 1262a6b7db3Sskrll static uint32_t 1272a6b7db3Sskrll gnu_hash(const char*); 1282a6b7db3Sskrll 1292a6b7db3Sskrll // Compute the number of hash buckets to use. 1302a6b7db3Sskrll static unsigned int 1312a6b7db3Sskrll compute_bucket_count(const std::vector<uint32_t>& hashcodes, 1322a6b7db3Sskrll bool for_gnu_hash_table); 1332a6b7db3Sskrll 1342a6b7db3Sskrll // Sized version of create_elf_hash_table. 1355ba6b03cSchristos template<int size, bool big_endian> 1362a6b7db3Sskrll static void 1372a6b7db3Sskrll sized_create_elf_hash_table(const std::vector<uint32_t>& bucket, 1382a6b7db3Sskrll const std::vector<uint32_t>& chain, 1392a6b7db3Sskrll unsigned char* phash, 1402a6b7db3Sskrll unsigned int hashlen); 1412a6b7db3Sskrll 1422a6b7db3Sskrll // Sized version of create_gnu_hash_table. 1432a6b7db3Sskrll template<int size, bool big_endian> 1442a6b7db3Sskrll static void 1452a6b7db3Sskrll sized_create_gnu_hash_table(const std::vector<Symbol*>& hashed_dynsyms, 1462a6b7db3Sskrll const std::vector<uint32_t>& dynsym_hashvals, 1472a6b7db3Sskrll unsigned int unhashed_dynsym_count, 1482a6b7db3Sskrll unsigned char** pphash, 1492a6b7db3Sskrll unsigned int* phashlen); 1502a6b7db3Sskrll 1512a6b7db3Sskrll // Values for the has_unknown_needed_entries_ field. 1522a6b7db3Sskrll enum Unknown_needed 1532a6b7db3Sskrll { 1542a6b7db3Sskrll UNKNOWN_NEEDED_UNSET, 1552a6b7db3Sskrll UNKNOWN_NEEDED_TRUE, 1562a6b7db3Sskrll UNKNOWN_NEEDED_FALSE 1572a6b7db3Sskrll }; 1582a6b7db3Sskrll 1592a6b7db3Sskrll // The DT_SONAME name, if any. 1602a6b7db3Sskrll std::string soname_; 1612a6b7db3Sskrll // The list of DT_NEEDED entries. 1622a6b7db3Sskrll Needed needed_; 1632a6b7db3Sskrll // Whether this dynamic object has any DT_NEEDED entries not seen 1642a6b7db3Sskrll // during the link. 1652a6b7db3Sskrll Unknown_needed unknown_needed_; 1662a6b7db3Sskrll }; 1672a6b7db3Sskrll 1682a6b7db3Sskrll // A dynamic object, size and endian specific version. 1692a6b7db3Sskrll 1702a6b7db3Sskrll template<int size, bool big_endian> 1712a6b7db3Sskrll class Sized_dynobj : public Dynobj 1722a6b7db3Sskrll { 1732a6b7db3Sskrll public: 17405caefcfSchristos typedef typename Sized_relobj_file<size, big_endian>::Symbols Symbols; 1752a6b7db3Sskrll 1762a6b7db3Sskrll Sized_dynobj(const std::string& name, Input_file* input_file, off_t offset, 1772a6b7db3Sskrll const typename elfcpp::Ehdr<size, big_endian>&); 1782a6b7db3Sskrll 179b578a859Schristos // Set up the object file based on TARGET. 1802a6b7db3Sskrll void 181b578a859Schristos setup(); 1822a6b7db3Sskrll 1832a6b7db3Sskrll // Read the symbols. 1842a6b7db3Sskrll void 1852a6b7db3Sskrll do_read_symbols(Read_symbols_data*); 1862a6b7db3Sskrll 1872a6b7db3Sskrll // Lay out the input sections. 1882a6b7db3Sskrll void 1892a6b7db3Sskrll do_layout(Symbol_table*, Layout*, Read_symbols_data*); 1902a6b7db3Sskrll 1912a6b7db3Sskrll // Add the symbols to the symbol table. 1922a6b7db3Sskrll void 193b578a859Schristos do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); 194b578a859Schristos 195b578a859Schristos Archive::Should_include 196b578a859Schristos do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, 197b578a859Schristos std::string* why); 1982a6b7db3Sskrll 19905caefcfSchristos // Iterate over global symbols, calling a visitor class V for each. 20005caefcfSchristos void 20105caefcfSchristos do_for_all_global_symbols(Read_symbols_data* sd, 20205caefcfSchristos Library_base::Symbol_visitor_base* v); 20305caefcfSchristos 20405caefcfSchristos // Iterate over local symbols, calling a visitor class V for each GOT offset 20505caefcfSchristos // associated with a local symbol. 20605caefcfSchristos void 20705caefcfSchristos do_for_all_local_got_entries(Got_offset_list::Visitor* v) const; 20805caefcfSchristos 2092a6b7db3Sskrll // Get the size of a section. 2102a6b7db3Sskrll uint64_t do_section_size(unsigned int shndx)2112a6b7db3Sskrll do_section_size(unsigned int shndx) 2122a6b7db3Sskrll { return this->elf_file_.section_size(shndx); } 2132a6b7db3Sskrll 2142a6b7db3Sskrll // Get the name of a section. 2152a6b7db3Sskrll std::string do_section_name(unsigned int shndx)2165ba6b03cSchristos do_section_name(unsigned int shndx) const 2172a6b7db3Sskrll { return this->elf_file_.section_name(shndx); } 2182a6b7db3Sskrll 2192a6b7db3Sskrll // Return a view of the contents of a section. Set *PLEN to the 2202a6b7db3Sskrll // size. 22105caefcfSchristos const unsigned char* do_section_contents(unsigned int shndx,section_size_type * plen,bool cache)22205caefcfSchristos do_section_contents(unsigned int shndx, section_size_type* plen, 22305caefcfSchristos bool cache) 22405caefcfSchristos { 22505caefcfSchristos Location loc(this->elf_file_.section_contents(shndx)); 22605caefcfSchristos *plen = convert_to_section_size_type(loc.data_size); 22705caefcfSchristos if (*plen == 0) 22805caefcfSchristos { 22905caefcfSchristos static const unsigned char empty[1] = { '\0' }; 23005caefcfSchristos return empty; 23105caefcfSchristos } 23205caefcfSchristos return this->get_view(loc.file_offset, *plen, true, cache); 23305caefcfSchristos } 2342a6b7db3Sskrll 2352a6b7db3Sskrll // Return section flags. 2362a6b7db3Sskrll uint64_t do_section_flags(unsigned int shndx)2372a6b7db3Sskrll do_section_flags(unsigned int shndx) 2382a6b7db3Sskrll { return this->elf_file_.section_flags(shndx); } 2392a6b7db3Sskrll 240b578a859Schristos // Not used for dynobj. 241b578a859Schristos uint64_t do_section_entsize(unsigned int)242b578a859Schristos do_section_entsize(unsigned int ) 243b578a859Schristos { gold_unreachable(); } 244b578a859Schristos 2452a6b7db3Sskrll // Return section address. 2462a6b7db3Sskrll uint64_t do_section_address(unsigned int shndx)2472a6b7db3Sskrll do_section_address(unsigned int shndx) 2482a6b7db3Sskrll { return this->elf_file_.section_addr(shndx); } 2492a6b7db3Sskrll 2502a6b7db3Sskrll // Return section type. 2512a6b7db3Sskrll unsigned int do_section_type(unsigned int shndx)2522a6b7db3Sskrll do_section_type(unsigned int shndx) 2532a6b7db3Sskrll { return this->elf_file_.section_type(shndx); } 2542a6b7db3Sskrll 2552a6b7db3Sskrll // Return the section link field. 2562a6b7db3Sskrll unsigned int do_section_link(unsigned int shndx)2572a6b7db3Sskrll do_section_link(unsigned int shndx) 2582a6b7db3Sskrll { return this->elf_file_.section_link(shndx); } 2592a6b7db3Sskrll 2602a6b7db3Sskrll // Return the section link field. 2612a6b7db3Sskrll unsigned int do_section_info(unsigned int shndx)2622a6b7db3Sskrll do_section_info(unsigned int shndx) 2632a6b7db3Sskrll { return this->elf_file_.section_info(shndx); } 2642a6b7db3Sskrll 2652a6b7db3Sskrll // Return the section alignment. 2662a6b7db3Sskrll uint64_t do_section_addralign(unsigned int shndx)2672a6b7db3Sskrll do_section_addralign(unsigned int shndx) 2682a6b7db3Sskrll { return this->elf_file_.section_addralign(shndx); } 2692a6b7db3Sskrll 2702a6b7db3Sskrll // Return the Xindex structure to use. 2712a6b7db3Sskrll Xindex* 2722a6b7db3Sskrll do_initialize_xindex(); 2732a6b7db3Sskrll 2742a6b7db3Sskrll // Get symbol counts. 2752a6b7db3Sskrll void 2762a6b7db3Sskrll do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const; 2772a6b7db3Sskrll 278b578a859Schristos // Get the global symbols. 279b578a859Schristos const Symbols* do_get_global_symbols()280b578a859Schristos do_get_global_symbols() const 281b578a859Schristos { return this->symbols_; } 282b578a859Schristos 2835ba6b03cSchristos protected: 2845ba6b03cSchristos // Read the symbols. This is common code for all target-specific 2855ba6b03cSchristos // overrides of do_read_symbols(). 2865ba6b03cSchristos void 2875ba6b03cSchristos base_read_symbols(Read_symbols_data*); 2885ba6b03cSchristos 2892a6b7db3Sskrll private: 2902a6b7db3Sskrll // For convenience. 2912a6b7db3Sskrll typedef Sized_dynobj<size, big_endian> This; 2922a6b7db3Sskrll static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; 2932a6b7db3Sskrll static const int sym_size = elfcpp::Elf_sizes<size>::sym_size; 2942a6b7db3Sskrll static const int dyn_size = elfcpp::Elf_sizes<size>::dyn_size; 2952a6b7db3Sskrll typedef elfcpp::Shdr<size, big_endian> Shdr; 2962a6b7db3Sskrll typedef elfcpp::Dyn<size, big_endian> Dyn; 2972a6b7db3Sskrll 2982a6b7db3Sskrll // Adjust a section index if necessary. 2992a6b7db3Sskrll unsigned int adjust_shndx(unsigned int shndx)3002a6b7db3Sskrll adjust_shndx(unsigned int shndx) 3012a6b7db3Sskrll { 3022a6b7db3Sskrll if (shndx >= elfcpp::SHN_LORESERVE) 3032a6b7db3Sskrll shndx += this->elf_file_.large_shndx_offset(); 3042a6b7db3Sskrll return shndx; 3052a6b7db3Sskrll } 3062a6b7db3Sskrll 3072a6b7db3Sskrll // Find the dynamic symbol table and the version sections, given the 3082a6b7db3Sskrll // section headers. 3092a6b7db3Sskrll void 3102a6b7db3Sskrll find_dynsym_sections(const unsigned char* pshdrs, 3112a6b7db3Sskrll unsigned int* pversym_shndx, 3122a6b7db3Sskrll unsigned int* pverdef_shndx, 3132a6b7db3Sskrll unsigned int* pverneed_shndx, 3142a6b7db3Sskrll unsigned int* pdynamic_shndx); 3152a6b7db3Sskrll 3162a6b7db3Sskrll // Read the dynamic symbol section SHNDX. 3172a6b7db3Sskrll void 3182a6b7db3Sskrll read_dynsym_section(const unsigned char* pshdrs, unsigned int shndx, 3192a6b7db3Sskrll elfcpp::SHT type, unsigned int link, 3202a6b7db3Sskrll File_view** view, section_size_type* view_size, 3212a6b7db3Sskrll unsigned int* view_info); 3222a6b7db3Sskrll 3232a6b7db3Sskrll // Read the dynamic tags. 3242a6b7db3Sskrll void 3252a6b7db3Sskrll read_dynamic(const unsigned char* pshdrs, unsigned int dynamic_shndx, 3262a6b7db3Sskrll unsigned int strtab_shndx, const unsigned char* strtabu, 3272a6b7db3Sskrll off_t strtab_size); 3282a6b7db3Sskrll 3292a6b7db3Sskrll // Mapping from version number to version name. 3302a6b7db3Sskrll typedef std::vector<const char*> Version_map; 3312a6b7db3Sskrll 3322a6b7db3Sskrll // Create the version map. 3332a6b7db3Sskrll void 3342a6b7db3Sskrll make_version_map(Read_symbols_data* sd, Version_map*) const; 3352a6b7db3Sskrll 3362a6b7db3Sskrll // Add version definitions to the version map. 3372a6b7db3Sskrll void 3382a6b7db3Sskrll make_verdef_map(Read_symbols_data* sd, Version_map*) const; 3392a6b7db3Sskrll 3402a6b7db3Sskrll // Add version references to the version map. 3412a6b7db3Sskrll void 3422a6b7db3Sskrll make_verneed_map(Read_symbols_data* sd, Version_map*) const; 3432a6b7db3Sskrll 3442a6b7db3Sskrll // Add an entry to the version map. 3452a6b7db3Sskrll void 3462a6b7db3Sskrll set_version_map(Version_map*, unsigned int ndx, const char* name) const; 3472a6b7db3Sskrll 3482a6b7db3Sskrll // General access to the ELF file. 3492a6b7db3Sskrll elfcpp::Elf_file<size, big_endian, Object> elf_file_; 3502a6b7db3Sskrll // The section index of the dynamic symbol table. 3512a6b7db3Sskrll unsigned int dynsym_shndx_; 3522a6b7db3Sskrll // The entries in the symbol table for the symbols. We only keep 3532a6b7db3Sskrll // this if we need it to print symbol information. 3542a6b7db3Sskrll Symbols* symbols_; 3552a6b7db3Sskrll // Number of defined symbols. 3562a6b7db3Sskrll size_t defined_count_; 3572a6b7db3Sskrll }; 3582a6b7db3Sskrll 3592a6b7db3Sskrll // A base class for Verdef and Verneed_version which just handles the 3602a6b7db3Sskrll // version index which will be stored in the SHT_GNU_versym section. 3612a6b7db3Sskrll 3622a6b7db3Sskrll class Version_base 3632a6b7db3Sskrll { 3642a6b7db3Sskrll public: Version_base()3652a6b7db3Sskrll Version_base() 3662a6b7db3Sskrll : index_(-1U) 3672a6b7db3Sskrll { } 3682a6b7db3Sskrll 3692a6b7db3Sskrll virtual ~Version_base()3702a6b7db3Sskrll ~Version_base() 3712a6b7db3Sskrll { } 3722a6b7db3Sskrll 3732a6b7db3Sskrll // Return the version index. 3742a6b7db3Sskrll unsigned int index()3752a6b7db3Sskrll index() const 3762a6b7db3Sskrll { 3772a6b7db3Sskrll gold_assert(this->index_ != -1U); 3782a6b7db3Sskrll return this->index_; 3792a6b7db3Sskrll } 3802a6b7db3Sskrll 3812a6b7db3Sskrll // Set the version index. 3822a6b7db3Sskrll void set_index(unsigned int index)3832a6b7db3Sskrll set_index(unsigned int index) 3842a6b7db3Sskrll { 3852a6b7db3Sskrll gold_assert(this->index_ == -1U); 3862a6b7db3Sskrll this->index_ = index; 3872a6b7db3Sskrll } 3882a6b7db3Sskrll 3892a6b7db3Sskrll // Clear the weak flag in a version definition. 3902a6b7db3Sskrll virtual void 3912a6b7db3Sskrll clear_weak() = 0; 3922a6b7db3Sskrll 3932a6b7db3Sskrll private: 3942a6b7db3Sskrll Version_base(const Version_base&); 3952a6b7db3Sskrll Version_base& operator=(const Version_base&); 3962a6b7db3Sskrll 3972a6b7db3Sskrll // The index of the version definition or reference. 3982a6b7db3Sskrll unsigned int index_; 3992a6b7db3Sskrll }; 4002a6b7db3Sskrll 4012a6b7db3Sskrll // This class handles a version being defined in the file we are 4022a6b7db3Sskrll // generating. 4032a6b7db3Sskrll 4042a6b7db3Sskrll class Verdef : public Version_base 4052a6b7db3Sskrll { 4062a6b7db3Sskrll public: Verdef(const char * name,const std::vector<std::string> & deps,bool is_base,bool is_weak,bool is_info,bool is_symbol_created)4072a6b7db3Sskrll Verdef(const char* name, const std::vector<std::string>& deps, 408b578a859Schristos bool is_base, bool is_weak, bool is_info, bool is_symbol_created) 4092a6b7db3Sskrll : name_(name), deps_(deps), is_base_(is_base), is_weak_(is_weak), 410b578a859Schristos is_info_(is_info), is_symbol_created_(is_symbol_created) 4112a6b7db3Sskrll { } 4122a6b7db3Sskrll 4132a6b7db3Sskrll // Return the version name. 4142a6b7db3Sskrll const char* name()4152a6b7db3Sskrll name() const 4162a6b7db3Sskrll { return this->name_; } 4172a6b7db3Sskrll 4182a6b7db3Sskrll // Return the number of dependencies. 4192a6b7db3Sskrll unsigned int count_dependencies()4202a6b7db3Sskrll count_dependencies() const 4212a6b7db3Sskrll { return this->deps_.size(); } 4222a6b7db3Sskrll 4232a6b7db3Sskrll // Add a dependency to this version. The NAME should be 4242a6b7db3Sskrll // canonicalized in the dynamic Stringpool. 4252a6b7db3Sskrll void add_dependency(const char * name)4262a6b7db3Sskrll add_dependency(const char* name) 4272a6b7db3Sskrll { this->deps_.push_back(name); } 4282a6b7db3Sskrll 4292a6b7db3Sskrll // Return whether this definition is weak. 4302a6b7db3Sskrll bool is_weak()4312a6b7db3Sskrll is_weak() const 4322a6b7db3Sskrll { return this->is_weak_; } 4332a6b7db3Sskrll 4342a6b7db3Sskrll // Clear the weak flag. 4352a6b7db3Sskrll void clear_weak()4362a6b7db3Sskrll clear_weak() 4372a6b7db3Sskrll { this->is_weak_ = false; } 4382a6b7db3Sskrll 439b578a859Schristos // Return whether this definition is informational. 440b578a859Schristos bool is_info()441b578a859Schristos is_info() const 442b578a859Schristos { return this->is_info_; } 443b578a859Schristos 4442a6b7db3Sskrll // Return whether a version symbol has been created for this 4452a6b7db3Sskrll // definition. 4462a6b7db3Sskrll bool is_symbol_created()4472a6b7db3Sskrll is_symbol_created() const 4482a6b7db3Sskrll { return this->is_symbol_created_; } 4492a6b7db3Sskrll 4502a6b7db3Sskrll // Write contents to buffer. 4512a6b7db3Sskrll template<int size, bool big_endian> 4522a6b7db3Sskrll unsigned char* 4532a6b7db3Sskrll write(const Stringpool*, bool is_last, unsigned char*) const; 4542a6b7db3Sskrll 4552a6b7db3Sskrll private: 4562a6b7db3Sskrll Verdef(const Verdef&); 4572a6b7db3Sskrll Verdef& operator=(const Verdef&); 4582a6b7db3Sskrll 4592a6b7db3Sskrll // The type of the list of version dependencies. Each dependency 4602a6b7db3Sskrll // should be canonicalized in the dynamic Stringpool. 4612a6b7db3Sskrll typedef std::vector<std::string> Deps; 4622a6b7db3Sskrll 4632a6b7db3Sskrll // The name of this version. This should be canonicalized in the 4642a6b7db3Sskrll // dynamic Stringpool. 4652a6b7db3Sskrll const char* name_; 4662a6b7db3Sskrll // A list of other versions which this version depends upon. 4672a6b7db3Sskrll Deps deps_; 4682a6b7db3Sskrll // Whether this is the base version. 4692a6b7db3Sskrll bool is_base_; 4702a6b7db3Sskrll // Whether this version is weak. 4712a6b7db3Sskrll bool is_weak_; 472b578a859Schristos // Whether this version is informational. 473b578a859Schristos bool is_info_; 4742a6b7db3Sskrll // Whether a version symbol has been created. 4752a6b7db3Sskrll bool is_symbol_created_; 4762a6b7db3Sskrll }; 4772a6b7db3Sskrll 4782a6b7db3Sskrll // A referened version. This will be associated with a filename by 4792a6b7db3Sskrll // Verneed. 4802a6b7db3Sskrll 4812a6b7db3Sskrll class Verneed_version : public Version_base 4822a6b7db3Sskrll { 4832a6b7db3Sskrll public: Verneed_version(const char * version)4842a6b7db3Sskrll Verneed_version(const char* version) 4852a6b7db3Sskrll : version_(version) 4862a6b7db3Sskrll { } 4872a6b7db3Sskrll 4882a6b7db3Sskrll // Return the version name. 4892a6b7db3Sskrll const char* version()4902a6b7db3Sskrll version() const 4912a6b7db3Sskrll { return this->version_; } 4922a6b7db3Sskrll 4932a6b7db3Sskrll // Clear the weak flag. This is invalid for a reference. 4942a6b7db3Sskrll void clear_weak()4952a6b7db3Sskrll clear_weak() 4962a6b7db3Sskrll { gold_unreachable(); } 4972a6b7db3Sskrll 4982a6b7db3Sskrll private: 4992a6b7db3Sskrll Verneed_version(const Verneed_version&); 5002a6b7db3Sskrll Verneed_version& operator=(const Verneed_version&); 5012a6b7db3Sskrll 5022a6b7db3Sskrll const char* version_; 5032a6b7db3Sskrll }; 5042a6b7db3Sskrll 5052a6b7db3Sskrll // Version references in a single dynamic object. 5062a6b7db3Sskrll 5072a6b7db3Sskrll class Verneed 5082a6b7db3Sskrll { 5092a6b7db3Sskrll public: Verneed(const char * filename)5102a6b7db3Sskrll Verneed(const char* filename) 5112a6b7db3Sskrll : filename_(filename), need_versions_() 5122a6b7db3Sskrll { } 5132a6b7db3Sskrll 5142a6b7db3Sskrll ~Verneed(); 5152a6b7db3Sskrll 5162a6b7db3Sskrll // Return the file name. 5172a6b7db3Sskrll const char* filename()5182a6b7db3Sskrll filename() const 5192a6b7db3Sskrll { return this->filename_; } 5202a6b7db3Sskrll 5212a6b7db3Sskrll // Return the number of versions. 5222a6b7db3Sskrll unsigned int count_versions()5232a6b7db3Sskrll count_versions() const 5242a6b7db3Sskrll { return this->need_versions_.size(); } 5252a6b7db3Sskrll 5262a6b7db3Sskrll // Add a version name. The name should be canonicalized in the 5272a6b7db3Sskrll // dynamic Stringpool. If the name is already present, this does 5282a6b7db3Sskrll // nothing. 5292a6b7db3Sskrll Verneed_version* 5302a6b7db3Sskrll add_name(const char* name); 5312a6b7db3Sskrll 5322a6b7db3Sskrll // Set the version indexes, starting at INDEX. Return the updated 5332a6b7db3Sskrll // INDEX. 5342a6b7db3Sskrll unsigned int 5352a6b7db3Sskrll finalize(unsigned int index); 5362a6b7db3Sskrll 5372a6b7db3Sskrll // Write contents to buffer. 5382a6b7db3Sskrll template<int size, bool big_endian> 5392a6b7db3Sskrll unsigned char* 5402a6b7db3Sskrll write(const Stringpool*, bool is_last, unsigned char*) const; 5412a6b7db3Sskrll 5422a6b7db3Sskrll private: 5432a6b7db3Sskrll Verneed(const Verneed&); 5442a6b7db3Sskrll Verneed& operator=(const Verneed&); 5452a6b7db3Sskrll 5462a6b7db3Sskrll // The type of the list of version names. Each name should be 5472a6b7db3Sskrll // canonicalized in the dynamic Stringpool. 5482a6b7db3Sskrll typedef std::vector<Verneed_version*> Need_versions; 5492a6b7db3Sskrll 5502a6b7db3Sskrll // The filename of the dynamic object. This should be 5512a6b7db3Sskrll // canonicalized in the dynamic Stringpool. 5522a6b7db3Sskrll const char* filename_; 5532a6b7db3Sskrll // The list of version names. 5542a6b7db3Sskrll Need_versions need_versions_; 5552a6b7db3Sskrll }; 5562a6b7db3Sskrll 5572a6b7db3Sskrll // This class handles version definitions and references which go into 5582a6b7db3Sskrll // the output file. 5592a6b7db3Sskrll 5602a6b7db3Sskrll class Versions 5612a6b7db3Sskrll { 5622a6b7db3Sskrll public: 5632a6b7db3Sskrll Versions(const Version_script_info&, Stringpool*); 5642a6b7db3Sskrll 5652a6b7db3Sskrll ~Versions(); 5662a6b7db3Sskrll 5672a6b7db3Sskrll // SYM is going into the dynamic symbol table and has a version. 5682a6b7db3Sskrll // Record the appropriate version information. 5692a6b7db3Sskrll void 5702a6b7db3Sskrll record_version(const Symbol_table* symtab, Stringpool*, const Symbol* sym); 5712a6b7db3Sskrll 5722a6b7db3Sskrll // Set the version indexes. DYNSYM_INDEX is the index we should use 5732a6b7db3Sskrll // for the next dynamic symbol. We add new dynamic symbols to SYMS 5742a6b7db3Sskrll // and return an updated DYNSYM_INDEX. 5752a6b7db3Sskrll unsigned int 5762a6b7db3Sskrll finalize(Symbol_table* symtab, unsigned int dynsym_index, 5772a6b7db3Sskrll std::vector<Symbol*>* syms); 5782a6b7db3Sskrll 5792a6b7db3Sskrll // Return whether there are any version definitions. 5802a6b7db3Sskrll bool any_defs()5812a6b7db3Sskrll any_defs() const 5822a6b7db3Sskrll { return !this->defs_.empty(); } 5832a6b7db3Sskrll 5842a6b7db3Sskrll // Return whether there are any version references. 5852a6b7db3Sskrll bool any_needs()5862a6b7db3Sskrll any_needs() const 5872a6b7db3Sskrll { return !this->needs_.empty(); } 5882a6b7db3Sskrll 5892a6b7db3Sskrll // Build an allocated buffer holding the contents of the symbol 5902a6b7db3Sskrll // version section (.gnu.version). 5912a6b7db3Sskrll template<int size, bool big_endian> 5922a6b7db3Sskrll void 5932a6b7db3Sskrll symbol_section_contents(const Symbol_table*, const Stringpool*, 5942a6b7db3Sskrll unsigned int local_symcount, 5952a6b7db3Sskrll const std::vector<Symbol*>& syms, 5962a6b7db3Sskrll unsigned char**, unsigned int*) const; 5972a6b7db3Sskrll 5982a6b7db3Sskrll // Build an allocated buffer holding the contents of the version 5992a6b7db3Sskrll // definition section (.gnu.version_d). 6002a6b7db3Sskrll template<int size, bool big_endian> 6012a6b7db3Sskrll void 6022a6b7db3Sskrll def_section_contents(const Stringpool*, unsigned char**, 6032a6b7db3Sskrll unsigned int* psize, unsigned int* pentries) const; 6042a6b7db3Sskrll 6052a6b7db3Sskrll // Build an allocated buffer holding the contents of the version 6062a6b7db3Sskrll // reference section (.gnu.version_r). 6072a6b7db3Sskrll template<int size, bool big_endian> 6082a6b7db3Sskrll void 6092a6b7db3Sskrll need_section_contents(const Stringpool*, unsigned char**, 6102a6b7db3Sskrll unsigned int* psize, unsigned int* pentries) const; 6112a6b7db3Sskrll 6122a6b7db3Sskrll const Version_script_info& version_script()6132a6b7db3Sskrll version_script() const 6142a6b7db3Sskrll { return this->version_script_; } 6152a6b7db3Sskrll 6162a6b7db3Sskrll private: 6172a6b7db3Sskrll Versions(const Versions&); 6182a6b7db3Sskrll Versions& operator=(const Versions&); 6192a6b7db3Sskrll 6202a6b7db3Sskrll // The type of the list of version definitions. 6212a6b7db3Sskrll typedef std::vector<Verdef*> Defs; 6222a6b7db3Sskrll 6232a6b7db3Sskrll // The type of the list of version references. 6242a6b7db3Sskrll typedef std::vector<Verneed*> Needs; 6252a6b7db3Sskrll 6262a6b7db3Sskrll // Handle a symbol SYM defined with version VERSION. 6272a6b7db3Sskrll void 62805caefcfSchristos add_def(Stringpool*, const Symbol* sym, const char* version, 62905caefcfSchristos Stringpool::Key); 6302a6b7db3Sskrll 6312a6b7db3Sskrll // Add a reference to version NAME in file FILENAME. 6322a6b7db3Sskrll void 6332a6b7db3Sskrll add_need(Stringpool*, const char* filename, const char* name, 6342a6b7db3Sskrll Stringpool::Key); 6352a6b7db3Sskrll 6362a6b7db3Sskrll // Get the dynamic object to use for SYM. 6372a6b7db3Sskrll Dynobj* 6382a6b7db3Sskrll get_dynobj_for_sym(const Symbol_table*, const Symbol* sym) const; 6392a6b7db3Sskrll 6402a6b7db3Sskrll // Return the version index to use for SYM. 6412a6b7db3Sskrll unsigned int 6422a6b7db3Sskrll version_index(const Symbol_table*, const Stringpool*, 6432a6b7db3Sskrll const Symbol* sym) const; 6442a6b7db3Sskrll 645b578a859Schristos // Define the base version of a shared library. 646b578a859Schristos void 647b578a859Schristos define_base_version(Stringpool* dynpool); 648b578a859Schristos 6492a6b7db3Sskrll // We keep a hash table mapping canonicalized name/version pairs to 6502a6b7db3Sskrll // a version base. 6512a6b7db3Sskrll typedef std::pair<Stringpool::Key, Stringpool::Key> Key; 6522a6b7db3Sskrll 6532a6b7db3Sskrll struct Version_table_hash 6542a6b7db3Sskrll { 6552a6b7db3Sskrll size_t operatorVersion_table_hash6562a6b7db3Sskrll operator()(const Key& k) const 6572a6b7db3Sskrll { return k.first + k.second; } 6582a6b7db3Sskrll }; 6592a6b7db3Sskrll 6602a6b7db3Sskrll struct Version_table_eq 6612a6b7db3Sskrll { 6622a6b7db3Sskrll bool operatorVersion_table_eq6632a6b7db3Sskrll operator()(const Key& k1, const Key& k2) const 6642a6b7db3Sskrll { return k1.first == k2.first && k1.second == k2.second; } 6652a6b7db3Sskrll }; 6662a6b7db3Sskrll 6672a6b7db3Sskrll typedef Unordered_map<Key, Version_base*, Version_table_hash, 6682a6b7db3Sskrll Version_table_eq> Version_table; 6692a6b7db3Sskrll 6702a6b7db3Sskrll // The version definitions. 6712a6b7db3Sskrll Defs defs_; 6722a6b7db3Sskrll // The version references. 6732a6b7db3Sskrll Needs needs_; 6742a6b7db3Sskrll // The mapping from a canonicalized version/filename pair to a 6752a6b7db3Sskrll // version index. The filename may be NULL. 6762a6b7db3Sskrll Version_table version_table_; 6772a6b7db3Sskrll // Whether the version indexes have been set. 6782a6b7db3Sskrll bool is_finalized_; 6792a6b7db3Sskrll // Contents of --version-script, if passed, or NULL. 6802a6b7db3Sskrll const Version_script_info& version_script_; 681b578a859Schristos // Whether we need to insert a base version. This is only used for 68205caefcfSchristos // shared libraries and is cleared when the base version is defined. 683b578a859Schristos bool needs_base_version_; 6842a6b7db3Sskrll }; 6852a6b7db3Sskrll 6862a6b7db3Sskrll } // End namespace gold. 6872a6b7db3Sskrll 6882a6b7db3Sskrll #endif // !defined(GOLD_DYNOBJ_H) 689