1*fae548d3Szrj // dynobj.h -- dynamic object support for gold -*- C++ -*- 2*fae548d3Szrj 3*fae548d3Szrj // Copyright (C) 2006-2020 Free Software Foundation, Inc. 4*fae548d3Szrj // Written by Ian Lance Taylor <iant@google.com>. 5*fae548d3Szrj 6*fae548d3Szrj // This file is part of gold. 7*fae548d3Szrj 8*fae548d3Szrj // This program is free software; you can redistribute it and/or modify 9*fae548d3Szrj // it under the terms of the GNU General Public License as published by 10*fae548d3Szrj // the Free Software Foundation; either version 3 of the License, or 11*fae548d3Szrj // (at your option) any later version. 12*fae548d3Szrj 13*fae548d3Szrj // This program is distributed in the hope that it will be useful, 14*fae548d3Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*fae548d3Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*fae548d3Szrj // GNU General Public License for more details. 17*fae548d3Szrj 18*fae548d3Szrj // You should have received a copy of the GNU General Public License 19*fae548d3Szrj // along with this program; if not, write to the Free Software 20*fae548d3Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21*fae548d3Szrj // MA 02110-1301, USA. 22*fae548d3Szrj 23*fae548d3Szrj #ifndef GOLD_DYNOBJ_H 24*fae548d3Szrj #define GOLD_DYNOBJ_H 25*fae548d3Szrj 26*fae548d3Szrj #include <vector> 27*fae548d3Szrj 28*fae548d3Szrj #include "stringpool.h" 29*fae548d3Szrj #include "object.h" 30*fae548d3Szrj 31*fae548d3Szrj namespace gold 32*fae548d3Szrj { 33*fae548d3Szrj 34*fae548d3Szrj class Version_script_info; 35*fae548d3Szrj 36*fae548d3Szrj // A dynamic object (ET_DYN). This is an abstract base class itself. 37*fae548d3Szrj // The implementations is the template class Sized_dynobj. 38*fae548d3Szrj 39*fae548d3Szrj class Dynobj : public Object 40*fae548d3Szrj { 41*fae548d3Szrj public: 42*fae548d3Szrj // We keep a list of all the DT_NEEDED entries we find. 43*fae548d3Szrj typedef std::vector<std::string> Needed; 44*fae548d3Szrj 45*fae548d3Szrj Dynobj(const std::string& name, Input_file* input_file, off_t offset = 0); 46*fae548d3Szrj 47*fae548d3Szrj // Return the name to use in a DT_NEEDED entry for this object. 48*fae548d3Szrj const char* soname()49*fae548d3Szrj soname() const 50*fae548d3Szrj { return this->soname_.c_str(); } 51*fae548d3Szrj 52*fae548d3Szrj // Return the list of DT_NEEDED strings. 53*fae548d3Szrj const Needed& needed()54*fae548d3Szrj needed() const 55*fae548d3Szrj { return this->needed_; } 56*fae548d3Szrj 57*fae548d3Szrj // Return whether this dynamic object has any DT_NEEDED entries 58*fae548d3Szrj // which were not seen during the link. 59*fae548d3Szrj bool has_unknown_needed_entries()60*fae548d3Szrj has_unknown_needed_entries() const 61*fae548d3Szrj { 62*fae548d3Szrj gold_assert(this->unknown_needed_ != UNKNOWN_NEEDED_UNSET); 63*fae548d3Szrj return this->unknown_needed_ == UNKNOWN_NEEDED_TRUE; 64*fae548d3Szrj } 65*fae548d3Szrj 66*fae548d3Szrj // Set whether this dynamic object has any DT_NEEDED entries which 67*fae548d3Szrj // were not seen during the link. 68*fae548d3Szrj void set_has_unknown_needed_entries(bool set)69*fae548d3Szrj set_has_unknown_needed_entries(bool set) 70*fae548d3Szrj { 71*fae548d3Szrj gold_assert(this->unknown_needed_ == UNKNOWN_NEEDED_UNSET); 72*fae548d3Szrj this->unknown_needed_ = set ? UNKNOWN_NEEDED_TRUE : UNKNOWN_NEEDED_FALSE; 73*fae548d3Szrj } 74*fae548d3Szrj 75*fae548d3Szrj // Return the word size of the object file. 76*fae548d3Szrj int elfsize()77*fae548d3Szrj elfsize() const 78*fae548d3Szrj { gold_unreachable(); } 79*fae548d3Szrj 80*fae548d3Szrj // Return TRUE if this is a big-endian object file. 81*fae548d3Szrj bool is_big_endian()82*fae548d3Szrj is_big_endian() const 83*fae548d3Szrj { gold_unreachable(); } 84*fae548d3Szrj 85*fae548d3Szrj // Compute the ELF hash code for a string. 86*fae548d3Szrj static uint32_t 87*fae548d3Szrj elf_hash(const char*); 88*fae548d3Szrj 89*fae548d3Szrj // Create a standard ELF hash table, setting *PPHASH and *PHASHLEN. 90*fae548d3Szrj // DYNSYMS is the global dynamic symbols. LOCAL_DYNSYM_COUNT is the 91*fae548d3Szrj // number of local dynamic symbols, which is the index of the first 92*fae548d3Szrj // dynamic gobal symbol. 93*fae548d3Szrj static void 94*fae548d3Szrj create_elf_hash_table(const std::vector<Symbol*>& dynsyms, 95*fae548d3Szrj unsigned int local_dynsym_count, 96*fae548d3Szrj unsigned char** pphash, 97*fae548d3Szrj unsigned int* phashlen); 98*fae548d3Szrj 99*fae548d3Szrj // Create a GNU hash table, setting *PPHASH and *PHASHLEN. DYNSYMS 100*fae548d3Szrj // is the global dynamic symbols. LOCAL_DYNSYM_COUNT is the number 101*fae548d3Szrj // of local dynamic symbols, which is the index of the first dynamic 102*fae548d3Szrj // gobal symbol. 103*fae548d3Szrj static void 104*fae548d3Szrj create_gnu_hash_table(const std::vector<Symbol*>& dynsyms, 105*fae548d3Szrj unsigned int local_dynsym_count, 106*fae548d3Szrj unsigned char** pphash, unsigned int* phashlen); 107*fae548d3Szrj 108*fae548d3Szrj protected: 109*fae548d3Szrj // Return a pointer to this object. 110*fae548d3Szrj virtual Dynobj* do_dynobj()111*fae548d3Szrj do_dynobj() 112*fae548d3Szrj { return this; } 113*fae548d3Szrj 114*fae548d3Szrj // Set the DT_SONAME string. 115*fae548d3Szrj void set_soname_string(const char * s)116*fae548d3Szrj set_soname_string(const char* s) 117*fae548d3Szrj { this->soname_.assign(s); } 118*fae548d3Szrj 119*fae548d3Szrj // Add an entry to the list of DT_NEEDED strings. 120*fae548d3Szrj void add_needed(const char * s)121*fae548d3Szrj add_needed(const char* s) 122*fae548d3Szrj { this->needed_.push_back(std::string(s)); } 123*fae548d3Szrj 124*fae548d3Szrj private: 125*fae548d3Szrj // Compute the GNU hash code for a string. 126*fae548d3Szrj static uint32_t 127*fae548d3Szrj gnu_hash(const char*); 128*fae548d3Szrj 129*fae548d3Szrj // Compute the number of hash buckets to use. 130*fae548d3Szrj static unsigned int 131*fae548d3Szrj compute_bucket_count(const std::vector<uint32_t>& hashcodes, 132*fae548d3Szrj bool for_gnu_hash_table); 133*fae548d3Szrj 134*fae548d3Szrj // Sized version of create_elf_hash_table. 135*fae548d3Szrj template<int size, bool big_endian> 136*fae548d3Szrj static void 137*fae548d3Szrj sized_create_elf_hash_table(const std::vector<uint32_t>& bucket, 138*fae548d3Szrj const std::vector<uint32_t>& chain, 139*fae548d3Szrj unsigned char* phash, 140*fae548d3Szrj unsigned int hashlen); 141*fae548d3Szrj 142*fae548d3Szrj // Sized version of create_gnu_hash_table. 143*fae548d3Szrj template<int size, bool big_endian> 144*fae548d3Szrj static void 145*fae548d3Szrj sized_create_gnu_hash_table(const std::vector<Symbol*>& hashed_dynsyms, 146*fae548d3Szrj const std::vector<uint32_t>& dynsym_hashvals, 147*fae548d3Szrj unsigned int unhashed_dynsym_count, 148*fae548d3Szrj unsigned char** pphash, 149*fae548d3Szrj unsigned int* phashlen); 150*fae548d3Szrj 151*fae548d3Szrj // Values for the has_unknown_needed_entries_ field. 152*fae548d3Szrj enum Unknown_needed 153*fae548d3Szrj { 154*fae548d3Szrj UNKNOWN_NEEDED_UNSET, 155*fae548d3Szrj UNKNOWN_NEEDED_TRUE, 156*fae548d3Szrj UNKNOWN_NEEDED_FALSE 157*fae548d3Szrj }; 158*fae548d3Szrj 159*fae548d3Szrj // The DT_SONAME name, if any. 160*fae548d3Szrj std::string soname_; 161*fae548d3Szrj // The list of DT_NEEDED entries. 162*fae548d3Szrj Needed needed_; 163*fae548d3Szrj // Whether this dynamic object has any DT_NEEDED entries not seen 164*fae548d3Szrj // during the link. 165*fae548d3Szrj Unknown_needed unknown_needed_; 166*fae548d3Szrj }; 167*fae548d3Szrj 168*fae548d3Szrj // A dynamic object, size and endian specific version. 169*fae548d3Szrj 170*fae548d3Szrj template<int size, bool big_endian> 171*fae548d3Szrj class Sized_dynobj : public Dynobj 172*fae548d3Szrj { 173*fae548d3Szrj public: 174*fae548d3Szrj typedef typename Sized_relobj_file<size, big_endian>::Symbols Symbols; 175*fae548d3Szrj 176*fae548d3Szrj Sized_dynobj(const std::string& name, Input_file* input_file, off_t offset, 177*fae548d3Szrj const typename elfcpp::Ehdr<size, big_endian>&); 178*fae548d3Szrj 179*fae548d3Szrj // Set up the object file based on TARGET. 180*fae548d3Szrj void 181*fae548d3Szrj setup(); 182*fae548d3Szrj 183*fae548d3Szrj // Read the symbols. 184*fae548d3Szrj void 185*fae548d3Szrj do_read_symbols(Read_symbols_data*); 186*fae548d3Szrj 187*fae548d3Szrj // Lay out the input sections. 188*fae548d3Szrj void 189*fae548d3Szrj do_layout(Symbol_table*, Layout*, Read_symbols_data*); 190*fae548d3Szrj 191*fae548d3Szrj // Add the symbols to the symbol table. 192*fae548d3Szrj void 193*fae548d3Szrj do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); 194*fae548d3Szrj 195*fae548d3Szrj Archive::Should_include 196*fae548d3Szrj do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, 197*fae548d3Szrj std::string* why); 198*fae548d3Szrj 199*fae548d3Szrj // Iterate over global symbols, calling a visitor class V for each. 200*fae548d3Szrj void 201*fae548d3Szrj do_for_all_global_symbols(Read_symbols_data* sd, 202*fae548d3Szrj Library_base::Symbol_visitor_base* v); 203*fae548d3Szrj 204*fae548d3Szrj // Iterate over local symbols, calling a visitor class V for each GOT offset 205*fae548d3Szrj // associated with a local symbol. 206*fae548d3Szrj void 207*fae548d3Szrj do_for_all_local_got_entries(Got_offset_list::Visitor* v) const; 208*fae548d3Szrj 209*fae548d3Szrj // Get the size of a section. 210*fae548d3Szrj uint64_t do_section_size(unsigned int shndx)211*fae548d3Szrj do_section_size(unsigned int shndx) 212*fae548d3Szrj { return this->elf_file_.section_size(shndx); } 213*fae548d3Szrj 214*fae548d3Szrj // Get the name of a section. 215*fae548d3Szrj std::string do_section_name(unsigned int shndx)216*fae548d3Szrj do_section_name(unsigned int shndx) const 217*fae548d3Szrj { return this->elf_file_.section_name(shndx); } 218*fae548d3Szrj 219*fae548d3Szrj // Return a view of the contents of a section. Set *PLEN to the 220*fae548d3Szrj // size. 221*fae548d3Szrj const unsigned char* do_section_contents(unsigned int shndx,section_size_type * plen,bool cache)222*fae548d3Szrj do_section_contents(unsigned int shndx, section_size_type* plen, 223*fae548d3Szrj bool cache) 224*fae548d3Szrj { 225*fae548d3Szrj Location loc(this->elf_file_.section_contents(shndx)); 226*fae548d3Szrj *plen = convert_to_section_size_type(loc.data_size); 227*fae548d3Szrj if (*plen == 0) 228*fae548d3Szrj { 229*fae548d3Szrj static const unsigned char empty[1] = { '\0' }; 230*fae548d3Szrj return empty; 231*fae548d3Szrj } 232*fae548d3Szrj return this->get_view(loc.file_offset, *plen, true, cache); 233*fae548d3Szrj } 234*fae548d3Szrj 235*fae548d3Szrj // Return section flags. 236*fae548d3Szrj uint64_t do_section_flags(unsigned int shndx)237*fae548d3Szrj do_section_flags(unsigned int shndx) 238*fae548d3Szrj { return this->elf_file_.section_flags(shndx); } 239*fae548d3Szrj 240*fae548d3Szrj // Not used for dynobj. 241*fae548d3Szrj uint64_t do_section_entsize(unsigned int)242*fae548d3Szrj do_section_entsize(unsigned int ) 243*fae548d3Szrj { gold_unreachable(); } 244*fae548d3Szrj 245*fae548d3Szrj // Return section address. 246*fae548d3Szrj uint64_t do_section_address(unsigned int shndx)247*fae548d3Szrj do_section_address(unsigned int shndx) 248*fae548d3Szrj { return this->elf_file_.section_addr(shndx); } 249*fae548d3Szrj 250*fae548d3Szrj // Return section type. 251*fae548d3Szrj unsigned int do_section_type(unsigned int shndx)252*fae548d3Szrj do_section_type(unsigned int shndx) 253*fae548d3Szrj { return this->elf_file_.section_type(shndx); } 254*fae548d3Szrj 255*fae548d3Szrj // Return the section link field. 256*fae548d3Szrj unsigned int do_section_link(unsigned int shndx)257*fae548d3Szrj do_section_link(unsigned int shndx) 258*fae548d3Szrj { return this->elf_file_.section_link(shndx); } 259*fae548d3Szrj 260*fae548d3Szrj // Return the section link field. 261*fae548d3Szrj unsigned int do_section_info(unsigned int shndx)262*fae548d3Szrj do_section_info(unsigned int shndx) 263*fae548d3Szrj { return this->elf_file_.section_info(shndx); } 264*fae548d3Szrj 265*fae548d3Szrj // Return the section alignment. 266*fae548d3Szrj uint64_t do_section_addralign(unsigned int shndx)267*fae548d3Szrj do_section_addralign(unsigned int shndx) 268*fae548d3Szrj { return this->elf_file_.section_addralign(shndx); } 269*fae548d3Szrj 270*fae548d3Szrj // Return the Xindex structure to use. 271*fae548d3Szrj Xindex* 272*fae548d3Szrj do_initialize_xindex(); 273*fae548d3Szrj 274*fae548d3Szrj // Get symbol counts. 275*fae548d3Szrj void 276*fae548d3Szrj do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const; 277*fae548d3Szrj 278*fae548d3Szrj // Get the global symbols. 279*fae548d3Szrj const Symbols* do_get_global_symbols()280*fae548d3Szrj do_get_global_symbols() const 281*fae548d3Szrj { return this->symbols_; } 282*fae548d3Szrj 283*fae548d3Szrj protected: 284*fae548d3Szrj // Read the symbols. This is common code for all target-specific 285*fae548d3Szrj // overrides of do_read_symbols(). 286*fae548d3Szrj void 287*fae548d3Szrj base_read_symbols(Read_symbols_data*); 288*fae548d3Szrj 289*fae548d3Szrj private: 290*fae548d3Szrj // For convenience. 291*fae548d3Szrj typedef Sized_dynobj<size, big_endian> This; 292*fae548d3Szrj static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; 293*fae548d3Szrj static const int sym_size = elfcpp::Elf_sizes<size>::sym_size; 294*fae548d3Szrj static const int dyn_size = elfcpp::Elf_sizes<size>::dyn_size; 295*fae548d3Szrj typedef elfcpp::Shdr<size, big_endian> Shdr; 296*fae548d3Szrj typedef elfcpp::Dyn<size, big_endian> Dyn; 297*fae548d3Szrj 298*fae548d3Szrj // Adjust a section index if necessary. 299*fae548d3Szrj unsigned int adjust_shndx(unsigned int shndx)300*fae548d3Szrj adjust_shndx(unsigned int shndx) 301*fae548d3Szrj { 302*fae548d3Szrj if (shndx >= elfcpp::SHN_LORESERVE) 303*fae548d3Szrj shndx += this->elf_file_.large_shndx_offset(); 304*fae548d3Szrj return shndx; 305*fae548d3Szrj } 306*fae548d3Szrj 307*fae548d3Szrj // Find the dynamic symbol table and the version sections, given the 308*fae548d3Szrj // section headers. 309*fae548d3Szrj void 310*fae548d3Szrj find_dynsym_sections(const unsigned char* pshdrs, 311*fae548d3Szrj unsigned int* pversym_shndx, 312*fae548d3Szrj unsigned int* pverdef_shndx, 313*fae548d3Szrj unsigned int* pverneed_shndx, 314*fae548d3Szrj unsigned int* pdynamic_shndx); 315*fae548d3Szrj 316*fae548d3Szrj // Read the dynamic symbol section SHNDX. 317*fae548d3Szrj void 318*fae548d3Szrj read_dynsym_section(const unsigned char* pshdrs, unsigned int shndx, 319*fae548d3Szrj elfcpp::SHT type, unsigned int link, 320*fae548d3Szrj File_view** view, section_size_type* view_size, 321*fae548d3Szrj unsigned int* view_info); 322*fae548d3Szrj 323*fae548d3Szrj // Read the dynamic tags. 324*fae548d3Szrj void 325*fae548d3Szrj read_dynamic(const unsigned char* pshdrs, unsigned int dynamic_shndx, 326*fae548d3Szrj unsigned int strtab_shndx, const unsigned char* strtabu, 327*fae548d3Szrj off_t strtab_size); 328*fae548d3Szrj 329*fae548d3Szrj // Mapping from version number to version name. 330*fae548d3Szrj typedef std::vector<const char*> Version_map; 331*fae548d3Szrj 332*fae548d3Szrj // Create the version map. 333*fae548d3Szrj void 334*fae548d3Szrj make_version_map(Read_symbols_data* sd, Version_map*) const; 335*fae548d3Szrj 336*fae548d3Szrj // Add version definitions to the version map. 337*fae548d3Szrj void 338*fae548d3Szrj make_verdef_map(Read_symbols_data* sd, Version_map*) const; 339*fae548d3Szrj 340*fae548d3Szrj // Add version references to the version map. 341*fae548d3Szrj void 342*fae548d3Szrj make_verneed_map(Read_symbols_data* sd, Version_map*) const; 343*fae548d3Szrj 344*fae548d3Szrj // Add an entry to the version map. 345*fae548d3Szrj void 346*fae548d3Szrj set_version_map(Version_map*, unsigned int ndx, const char* name) const; 347*fae548d3Szrj 348*fae548d3Szrj // General access to the ELF file. 349*fae548d3Szrj elfcpp::Elf_file<size, big_endian, Object> elf_file_; 350*fae548d3Szrj // The section index of the dynamic symbol table. 351*fae548d3Szrj unsigned int dynsym_shndx_; 352*fae548d3Szrj // The entries in the symbol table for the symbols. We only keep 353*fae548d3Szrj // this if we need it to print symbol information. 354*fae548d3Szrj Symbols* symbols_; 355*fae548d3Szrj // Number of defined symbols. 356*fae548d3Szrj size_t defined_count_; 357*fae548d3Szrj }; 358*fae548d3Szrj 359*fae548d3Szrj // A base class for Verdef and Verneed_version which just handles the 360*fae548d3Szrj // version index which will be stored in the SHT_GNU_versym section. 361*fae548d3Szrj 362*fae548d3Szrj class Version_base 363*fae548d3Szrj { 364*fae548d3Szrj public: Version_base()365*fae548d3Szrj Version_base() 366*fae548d3Szrj : index_(-1U) 367*fae548d3Szrj { } 368*fae548d3Szrj 369*fae548d3Szrj virtual ~Version_base()370*fae548d3Szrj ~Version_base() 371*fae548d3Szrj { } 372*fae548d3Szrj 373*fae548d3Szrj // Return the version index. 374*fae548d3Szrj unsigned int index()375*fae548d3Szrj index() const 376*fae548d3Szrj { 377*fae548d3Szrj gold_assert(this->index_ != -1U); 378*fae548d3Szrj return this->index_; 379*fae548d3Szrj } 380*fae548d3Szrj 381*fae548d3Szrj // Set the version index. 382*fae548d3Szrj void set_index(unsigned int index)383*fae548d3Szrj set_index(unsigned int index) 384*fae548d3Szrj { 385*fae548d3Szrj gold_assert(this->index_ == -1U); 386*fae548d3Szrj this->index_ = index; 387*fae548d3Szrj } 388*fae548d3Szrj 389*fae548d3Szrj // Clear the weak flag in a version definition. 390*fae548d3Szrj virtual void 391*fae548d3Szrj clear_weak() = 0; 392*fae548d3Szrj 393*fae548d3Szrj private: 394*fae548d3Szrj Version_base(const Version_base&); 395*fae548d3Szrj Version_base& operator=(const Version_base&); 396*fae548d3Szrj 397*fae548d3Szrj // The index of the version definition or reference. 398*fae548d3Szrj unsigned int index_; 399*fae548d3Szrj }; 400*fae548d3Szrj 401*fae548d3Szrj // This class handles a version being defined in the file we are 402*fae548d3Szrj // generating. 403*fae548d3Szrj 404*fae548d3Szrj class Verdef : public Version_base 405*fae548d3Szrj { 406*fae548d3Szrj public: Verdef(const char * name,const std::vector<std::string> & deps,bool is_base,bool is_weak,bool is_info,bool is_symbol_created)407*fae548d3Szrj Verdef(const char* name, const std::vector<std::string>& deps, 408*fae548d3Szrj bool is_base, bool is_weak, bool is_info, bool is_symbol_created) 409*fae548d3Szrj : name_(name), deps_(deps), is_base_(is_base), is_weak_(is_weak), 410*fae548d3Szrj is_info_(is_info), is_symbol_created_(is_symbol_created) 411*fae548d3Szrj { } 412*fae548d3Szrj 413*fae548d3Szrj // Return the version name. 414*fae548d3Szrj const char* name()415*fae548d3Szrj name() const 416*fae548d3Szrj { return this->name_; } 417*fae548d3Szrj 418*fae548d3Szrj // Return the number of dependencies. 419*fae548d3Szrj unsigned int count_dependencies()420*fae548d3Szrj count_dependencies() const 421*fae548d3Szrj { return this->deps_.size(); } 422*fae548d3Szrj 423*fae548d3Szrj // Add a dependency to this version. The NAME should be 424*fae548d3Szrj // canonicalized in the dynamic Stringpool. 425*fae548d3Szrj void add_dependency(const char * name)426*fae548d3Szrj add_dependency(const char* name) 427*fae548d3Szrj { this->deps_.push_back(name); } 428*fae548d3Szrj 429*fae548d3Szrj // Return whether this definition is weak. 430*fae548d3Szrj bool is_weak()431*fae548d3Szrj is_weak() const 432*fae548d3Szrj { return this->is_weak_; } 433*fae548d3Szrj 434*fae548d3Szrj // Clear the weak flag. 435*fae548d3Szrj void clear_weak()436*fae548d3Szrj clear_weak() 437*fae548d3Szrj { this->is_weak_ = false; } 438*fae548d3Szrj 439*fae548d3Szrj // Return whether this definition is informational. 440*fae548d3Szrj bool is_info()441*fae548d3Szrj is_info() const 442*fae548d3Szrj { return this->is_info_; } 443*fae548d3Szrj 444*fae548d3Szrj // Return whether a version symbol has been created for this 445*fae548d3Szrj // definition. 446*fae548d3Szrj bool is_symbol_created()447*fae548d3Szrj is_symbol_created() const 448*fae548d3Szrj { return this->is_symbol_created_; } 449*fae548d3Szrj 450*fae548d3Szrj // Write contents to buffer. 451*fae548d3Szrj template<int size, bool big_endian> 452*fae548d3Szrj unsigned char* 453*fae548d3Szrj write(const Stringpool*, bool is_last, unsigned char*) const; 454*fae548d3Szrj 455*fae548d3Szrj private: 456*fae548d3Szrj Verdef(const Verdef&); 457*fae548d3Szrj Verdef& operator=(const Verdef&); 458*fae548d3Szrj 459*fae548d3Szrj // The type of the list of version dependencies. Each dependency 460*fae548d3Szrj // should be canonicalized in the dynamic Stringpool. 461*fae548d3Szrj typedef std::vector<std::string> Deps; 462*fae548d3Szrj 463*fae548d3Szrj // The name of this version. This should be canonicalized in the 464*fae548d3Szrj // dynamic Stringpool. 465*fae548d3Szrj const char* name_; 466*fae548d3Szrj // A list of other versions which this version depends upon. 467*fae548d3Szrj Deps deps_; 468*fae548d3Szrj // Whether this is the base version. 469*fae548d3Szrj bool is_base_; 470*fae548d3Szrj // Whether this version is weak. 471*fae548d3Szrj bool is_weak_; 472*fae548d3Szrj // Whether this version is informational. 473*fae548d3Szrj bool is_info_; 474*fae548d3Szrj // Whether a version symbol has been created. 475*fae548d3Szrj bool is_symbol_created_; 476*fae548d3Szrj }; 477*fae548d3Szrj 478*fae548d3Szrj // A referened version. This will be associated with a filename by 479*fae548d3Szrj // Verneed. 480*fae548d3Szrj 481*fae548d3Szrj class Verneed_version : public Version_base 482*fae548d3Szrj { 483*fae548d3Szrj public: Verneed_version(const char * version)484*fae548d3Szrj Verneed_version(const char* version) 485*fae548d3Szrj : version_(version) 486*fae548d3Szrj { } 487*fae548d3Szrj 488*fae548d3Szrj // Return the version name. 489*fae548d3Szrj const char* version()490*fae548d3Szrj version() const 491*fae548d3Szrj { return this->version_; } 492*fae548d3Szrj 493*fae548d3Szrj // Clear the weak flag. This is invalid for a reference. 494*fae548d3Szrj void clear_weak()495*fae548d3Szrj clear_weak() 496*fae548d3Szrj { gold_unreachable(); } 497*fae548d3Szrj 498*fae548d3Szrj private: 499*fae548d3Szrj Verneed_version(const Verneed_version&); 500*fae548d3Szrj Verneed_version& operator=(const Verneed_version&); 501*fae548d3Szrj 502*fae548d3Szrj const char* version_; 503*fae548d3Szrj }; 504*fae548d3Szrj 505*fae548d3Szrj // Version references in a single dynamic object. 506*fae548d3Szrj 507*fae548d3Szrj class Verneed 508*fae548d3Szrj { 509*fae548d3Szrj public: Verneed(const char * filename)510*fae548d3Szrj Verneed(const char* filename) 511*fae548d3Szrj : filename_(filename), need_versions_() 512*fae548d3Szrj { } 513*fae548d3Szrj 514*fae548d3Szrj ~Verneed(); 515*fae548d3Szrj 516*fae548d3Szrj // Return the file name. 517*fae548d3Szrj const char* filename()518*fae548d3Szrj filename() const 519*fae548d3Szrj { return this->filename_; } 520*fae548d3Szrj 521*fae548d3Szrj // Return the number of versions. 522*fae548d3Szrj unsigned int count_versions()523*fae548d3Szrj count_versions() const 524*fae548d3Szrj { return this->need_versions_.size(); } 525*fae548d3Szrj 526*fae548d3Szrj // Add a version name. The name should be canonicalized in the 527*fae548d3Szrj // dynamic Stringpool. If the name is already present, this does 528*fae548d3Szrj // nothing. 529*fae548d3Szrj Verneed_version* 530*fae548d3Szrj add_name(const char* name); 531*fae548d3Szrj 532*fae548d3Szrj // Set the version indexes, starting at INDEX. Return the updated 533*fae548d3Szrj // INDEX. 534*fae548d3Szrj unsigned int 535*fae548d3Szrj finalize(unsigned int index); 536*fae548d3Szrj 537*fae548d3Szrj // Write contents to buffer. 538*fae548d3Szrj template<int size, bool big_endian> 539*fae548d3Szrj unsigned char* 540*fae548d3Szrj write(const Stringpool*, bool is_last, unsigned char*) const; 541*fae548d3Szrj 542*fae548d3Szrj private: 543*fae548d3Szrj Verneed(const Verneed&); 544*fae548d3Szrj Verneed& operator=(const Verneed&); 545*fae548d3Szrj 546*fae548d3Szrj // The type of the list of version names. Each name should be 547*fae548d3Szrj // canonicalized in the dynamic Stringpool. 548*fae548d3Szrj typedef std::vector<Verneed_version*> Need_versions; 549*fae548d3Szrj 550*fae548d3Szrj // The filename of the dynamic object. This should be 551*fae548d3Szrj // canonicalized in the dynamic Stringpool. 552*fae548d3Szrj const char* filename_; 553*fae548d3Szrj // The list of version names. 554*fae548d3Szrj Need_versions need_versions_; 555*fae548d3Szrj }; 556*fae548d3Szrj 557*fae548d3Szrj // This class handles version definitions and references which go into 558*fae548d3Szrj // the output file. 559*fae548d3Szrj 560*fae548d3Szrj class Versions 561*fae548d3Szrj { 562*fae548d3Szrj public: 563*fae548d3Szrj Versions(const Version_script_info&, Stringpool*); 564*fae548d3Szrj 565*fae548d3Szrj ~Versions(); 566*fae548d3Szrj 567*fae548d3Szrj // SYM is going into the dynamic symbol table and has a version. 568*fae548d3Szrj // Record the appropriate version information. 569*fae548d3Szrj void 570*fae548d3Szrj record_version(const Symbol_table* symtab, Stringpool*, const Symbol* sym); 571*fae548d3Szrj 572*fae548d3Szrj // Set the version indexes. DYNSYM_INDEX is the index we should use 573*fae548d3Szrj // for the next dynamic symbol. We add new dynamic symbols to SYMS 574*fae548d3Szrj // and return an updated DYNSYM_INDEX. 575*fae548d3Szrj unsigned int 576*fae548d3Szrj finalize(Symbol_table* symtab, unsigned int dynsym_index, 577*fae548d3Szrj std::vector<Symbol*>* syms); 578*fae548d3Szrj 579*fae548d3Szrj // Return whether there are any version definitions. 580*fae548d3Szrj bool any_defs()581*fae548d3Szrj any_defs() const 582*fae548d3Szrj { return !this->defs_.empty(); } 583*fae548d3Szrj 584*fae548d3Szrj // Return whether there are any version references. 585*fae548d3Szrj bool any_needs()586*fae548d3Szrj any_needs() const 587*fae548d3Szrj { return !this->needs_.empty(); } 588*fae548d3Szrj 589*fae548d3Szrj // Build an allocated buffer holding the contents of the symbol 590*fae548d3Szrj // version section (.gnu.version). 591*fae548d3Szrj template<int size, bool big_endian> 592*fae548d3Szrj void 593*fae548d3Szrj symbol_section_contents(const Symbol_table*, const Stringpool*, 594*fae548d3Szrj unsigned int local_symcount, 595*fae548d3Szrj const std::vector<Symbol*>& syms, 596*fae548d3Szrj unsigned char**, unsigned int*) const; 597*fae548d3Szrj 598*fae548d3Szrj // Build an allocated buffer holding the contents of the version 599*fae548d3Szrj // definition section (.gnu.version_d). 600*fae548d3Szrj template<int size, bool big_endian> 601*fae548d3Szrj void 602*fae548d3Szrj def_section_contents(const Stringpool*, unsigned char**, 603*fae548d3Szrj unsigned int* psize, unsigned int* pentries) const; 604*fae548d3Szrj 605*fae548d3Szrj // Build an allocated buffer holding the contents of the version 606*fae548d3Szrj // reference section (.gnu.version_r). 607*fae548d3Szrj template<int size, bool big_endian> 608*fae548d3Szrj void 609*fae548d3Szrj need_section_contents(const Stringpool*, unsigned char**, 610*fae548d3Szrj unsigned int* psize, unsigned int* pentries) const; 611*fae548d3Szrj 612*fae548d3Szrj const Version_script_info& version_script()613*fae548d3Szrj version_script() const 614*fae548d3Szrj { return this->version_script_; } 615*fae548d3Szrj 616*fae548d3Szrj private: 617*fae548d3Szrj Versions(const Versions&); 618*fae548d3Szrj Versions& operator=(const Versions&); 619*fae548d3Szrj 620*fae548d3Szrj // The type of the list of version definitions. 621*fae548d3Szrj typedef std::vector<Verdef*> Defs; 622*fae548d3Szrj 623*fae548d3Szrj // The type of the list of version references. 624*fae548d3Szrj typedef std::vector<Verneed*> Needs; 625*fae548d3Szrj 626*fae548d3Szrj // Handle a symbol SYM defined with version VERSION. 627*fae548d3Szrj void 628*fae548d3Szrj add_def(Stringpool*, const Symbol* sym, const char* version, 629*fae548d3Szrj Stringpool::Key); 630*fae548d3Szrj 631*fae548d3Szrj // Add a reference to version NAME in file FILENAME. 632*fae548d3Szrj void 633*fae548d3Szrj add_need(Stringpool*, const char* filename, const char* name, 634*fae548d3Szrj Stringpool::Key); 635*fae548d3Szrj 636*fae548d3Szrj // Get the dynamic object to use for SYM. 637*fae548d3Szrj Dynobj* 638*fae548d3Szrj get_dynobj_for_sym(const Symbol_table*, const Symbol* sym) const; 639*fae548d3Szrj 640*fae548d3Szrj // Return the version index to use for SYM. 641*fae548d3Szrj unsigned int 642*fae548d3Szrj version_index(const Symbol_table*, const Stringpool*, 643*fae548d3Szrj const Symbol* sym) const; 644*fae548d3Szrj 645*fae548d3Szrj // Define the base version of a shared library. 646*fae548d3Szrj void 647*fae548d3Szrj define_base_version(Stringpool* dynpool); 648*fae548d3Szrj 649*fae548d3Szrj // We keep a hash table mapping canonicalized name/version pairs to 650*fae548d3Szrj // a version base. 651*fae548d3Szrj typedef std::pair<Stringpool::Key, Stringpool::Key> Key; 652*fae548d3Szrj 653*fae548d3Szrj struct Version_table_hash 654*fae548d3Szrj { 655*fae548d3Szrj size_t operatorVersion_table_hash656*fae548d3Szrj operator()(const Key& k) const 657*fae548d3Szrj { return k.first + k.second; } 658*fae548d3Szrj }; 659*fae548d3Szrj 660*fae548d3Szrj struct Version_table_eq 661*fae548d3Szrj { 662*fae548d3Szrj bool operatorVersion_table_eq663*fae548d3Szrj operator()(const Key& k1, const Key& k2) const 664*fae548d3Szrj { return k1.first == k2.first && k1.second == k2.second; } 665*fae548d3Szrj }; 666*fae548d3Szrj 667*fae548d3Szrj typedef Unordered_map<Key, Version_base*, Version_table_hash, 668*fae548d3Szrj Version_table_eq> Version_table; 669*fae548d3Szrj 670*fae548d3Szrj // The version definitions. 671*fae548d3Szrj Defs defs_; 672*fae548d3Szrj // The version references. 673*fae548d3Szrj Needs needs_; 674*fae548d3Szrj // The mapping from a canonicalized version/filename pair to a 675*fae548d3Szrj // version index. The filename may be NULL. 676*fae548d3Szrj Version_table version_table_; 677*fae548d3Szrj // Whether the version indexes have been set. 678*fae548d3Szrj bool is_finalized_; 679*fae548d3Szrj // Contents of --version-script, if passed, or NULL. 680*fae548d3Szrj const Version_script_info& version_script_; 681*fae548d3Szrj // Whether we need to insert a base version. This is only used for 682*fae548d3Szrj // shared libraries and is cleared when the base version is defined. 683*fae548d3Szrj bool needs_base_version_; 684*fae548d3Szrj }; 685*fae548d3Szrj 686*fae548d3Szrj } // End namespace gold. 687*fae548d3Szrj 688*fae548d3Szrj #endif // !defined(GOLD_DYNOBJ_H) 689