xref: /netbsd/external/gpl3/binutils/dist/gold/dynobj.h (revision f22f0ef4)
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