1158115Sume// dynobj.h -- dynamic object support for gold   -*- C++ -*-
2158115Sume
3158115Sume// Copyright (C) 2006-2017 Free Software Foundation, Inc.
4158115Sume// Written by Ian Lance Taylor <iant@google.com>.
5158115Sume
6158115Sume// This file is part of gold.
7158115Sume
8158115Sume// This program is free software; you can redistribute it and/or modify
9158115Sume// it under the terms of the GNU General Public License as published by
10158115Sume// the Free Software Foundation; either version 3 of the License, or
11158115Sume// (at your option) any later version.
12158115Sume
13158115Sume// This program is distributed in the hope that it will be useful,
14158115Sume// but WITHOUT ANY WARRANTY; without even the implied warranty of
15158115Sume// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16158115Sume// GNU General Public License for more details.
17158115Sume
18158115Sume// You should have received a copy of the GNU General Public License
19158115Sume// along with this program; if not, write to the Free Software
20158115Sume// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21158115Sume// MA 02110-1301, USA.
22158115Sume
23158115Sume#ifndef GOLD_DYNOBJ_H
24158115Sume#define GOLD_DYNOBJ_H
25158115Sume
26158115Sume#include <vector>
27158115Sume
28158115Sume#include "stringpool.h"
29158115Sume#include "object.h"
30158115Sume
31194089Sdesnamespace gold
32194089Sdes{
33158115Sume
34158115Sumeclass Version_script_info;
35194089Sdes
36158115Sume// A dynamic object (ET_DYN).  This is an abstract base class itself.
37194089Sdes// The implementations is the template class Sized_dynobj.
38158115Sume
39158115Sumeclass Dynobj : public Object
40158115Sume{
41158115Sume public:
42158115Sume  // We keep a list of all the DT_NEEDED entries we find.
43158115Sume  typedef std::vector<std::string> Needed;
44158115Sume
45158115Sume  Dynobj(const std::string& name, Input_file* input_file, off_t offset = 0);
46158115Sume
47158115Sume  // Return the name to use in a DT_NEEDED entry for this object.
48158115Sume  const char*
49158115Sume  soname() const
50158115Sume  { return this->soname_.c_str(); }
51158115Sume
52158115Sume  // Return the list of DT_NEEDED strings.
53158115Sume  const Needed&
54158115Sume  needed() const
55158115Sume  { return this->needed_; }
56158115Sume
57158115Sume  // Return whether this dynamic object has any DT_NEEDED entries
58158115Sume  // which were not seen during the link.
59158115Sume  bool
60158115Sume  has_unknown_needed_entries() const
61158115Sume  {
62158115Sume    gold_assert(this->unknown_needed_ != UNKNOWN_NEEDED_UNSET);
63158115Sume    return this->unknown_needed_ == UNKNOWN_NEEDED_TRUE;
64158115Sume  }
65158115Sume
66158115Sume  // Set whether this dynamic object has any DT_NEEDED entries which
67158115Sume  // were not seen during the link.
68158115Sume  void
69158115Sume  set_has_unknown_needed_entries(bool set)
70158115Sume  {
71158115Sume    gold_assert(this->unknown_needed_ == UNKNOWN_NEEDED_UNSET);
72158115Sume    this->unknown_needed_ = set ? UNKNOWN_NEEDED_TRUE : UNKNOWN_NEEDED_FALSE;
73158115Sume  }
74158115Sume
75158115Sume  // Return the word size of the object file.
76158115Sume  int
77158115Sume  elfsize() const
78158115Sume  { gold_unreachable(); }
79158115Sume
80158115Sume  // Return TRUE if this is a big-endian object file.
81158115Sume  bool
82158115Sume  is_big_endian() const
83158115Sume  { gold_unreachable(); }
84158115Sume
85158115Sume  // Compute the ELF hash code for a string.
86158115Sume  static uint32_t
87158115Sume  elf_hash(const char*);
88158115Sume
89158115Sume  // Create a standard ELF hash table, setting *PPHASH and *PHASHLEN.
90158115Sume  // DYNSYMS is the global dynamic symbols.  LOCAL_DYNSYM_COUNT is the
91158115Sume  // number of local dynamic symbols, which is the index of the first
92158115Sume  // dynamic gobal symbol.
93158115Sume  static void
94158115Sume  create_elf_hash_table(const std::vector<Symbol*>& dynsyms,
95158115Sume			unsigned int local_dynsym_count,
96158115Sume			unsigned char** pphash,
97158115Sume			unsigned int* phashlen);
98158115Sume
99158115Sume  // Create a GNU hash table, setting *PPHASH and *PHASHLEN.  DYNSYMS
100158115Sume  // is the global dynamic symbols.  LOCAL_DYNSYM_COUNT is the number
101158115Sume  // of local dynamic symbols, which is the index of the first dynamic
102158115Sume  // gobal symbol.
103158115Sume  static void
104158115Sume  create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
105158115Sume			unsigned int local_dynsym_count,
106158115Sume			unsigned char** pphash, unsigned int* phashlen);
107158115Sume
108158115Sume protected:
109158115Sume  // Return a pointer to this object.
110158115Sume  virtual Dynobj*
111158115Sume  do_dynobj()
112158115Sume  { return this; }
113158115Sume
114158115Sume  // Set the DT_SONAME string.
115158115Sume  void
116158115Sume  set_soname_string(const char* s)
117158115Sume  { this->soname_.assign(s); }
118158115Sume
119158115Sume  // Add an entry to the list of DT_NEEDED strings.
120158115Sume  void
121158115Sume  add_needed(const char* s)
122158115Sume  { this->needed_.push_back(std::string(s)); }
123158115Sume
124158115Sume private:
125158115Sume  // Compute the GNU hash code for a string.
126158115Sume  static uint32_t
127158115Sume  gnu_hash(const char*);
128158115Sume
129158115Sume  // Compute the number of hash buckets to use.
130158115Sume  static unsigned int
131158115Sume  compute_bucket_count(const std::vector<uint32_t>& hashcodes,
132158115Sume		       bool for_gnu_hash_table);
133158115Sume
134158115Sume  // Sized version of create_elf_hash_table.
135158115Sume  template<int size, bool big_endian>
136158115Sume  static void
137158115Sume  sized_create_elf_hash_table(const std::vector<uint32_t>& bucket,
138158115Sume			      const std::vector<uint32_t>& chain,
139158115Sume			      unsigned char* phash,
140158115Sume			      unsigned int hashlen);
141158115Sume
142158115Sume  // Sized version of create_gnu_hash_table.
143158115Sume  template<int size, bool big_endian>
144158115Sume  static void
145158115Sume  sized_create_gnu_hash_table(const std::vector<Symbol*>& hashed_dynsyms,
146158115Sume			      const std::vector<uint32_t>& dynsym_hashvals,
147158115Sume			      unsigned int unhashed_dynsym_count,
148158115Sume			      unsigned char** pphash,
149158115Sume			      unsigned int* phashlen);
150158115Sume
151158115Sume  // Values for the has_unknown_needed_entries_ field.
152158115Sume  enum Unknown_needed
153158115Sume  {
154158115Sume    UNKNOWN_NEEDED_UNSET,
155158115Sume    UNKNOWN_NEEDED_TRUE,
156158115Sume    UNKNOWN_NEEDED_FALSE
157158115Sume  };
158158115Sume
159158115Sume  // The DT_SONAME name, if any.
160158115Sume  std::string soname_;
161158115Sume  // The list of DT_NEEDED entries.
162158115Sume  Needed needed_;
163158115Sume  // Whether this dynamic object has any DT_NEEDED entries not seen
164158115Sume  // during the link.
165158115Sume  Unknown_needed unknown_needed_;
166158115Sume};
167158115Sume
168158115Sume// A dynamic object, size and endian specific version.
169158115Sume
170238094Ssetemplate<int size, bool big_endian>
171238094Sseclass Sized_dynobj : public Dynobj
172238094Sse{
173238094Sse public:
174238094Sse  typedef typename Sized_relobj_file<size, big_endian>::Symbols Symbols;
175238094Sse
176238094Sse  Sized_dynobj(const std::string& name, Input_file* input_file, off_t offset,
177238094Sse	       const typename elfcpp::Ehdr<size, big_endian>&);
178238094Sse
179238094Sse  // Set up the object file based on TARGET.
180238094Sse  void
181238094Sse  setup();
182238094Sse
183238094Sse  // Read the symbols.
184238094Sse  void
185238094Sse  do_read_symbols(Read_symbols_data*);
186238094Sse
187238094Sse  // Lay out the input sections.
188238094Sse  void
189238094Sse  do_layout(Symbol_table*, Layout*, Read_symbols_data*);
190238094Sse
191238094Sse  // Add the symbols to the symbol table.
192238094Sse  void
193238094Sse  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
194238094Sse
195238094Sse  Archive::Should_include
196238094Sse  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
197238094Sse                           std::string* why);
198238094Sse
199238094Sse  // Iterate over global symbols, calling a visitor class V for each.
200238094Sse  void
201238094Sse  do_for_all_global_symbols(Read_symbols_data* sd,
202158115Sume			    Library_base::Symbol_visitor_base* v);
203158115Sume
204158115Sume  // Iterate over local symbols, calling a visitor class V for each GOT offset
205158115Sume  // associated with a local symbol.
206158115Sume  void
207158115Sume  do_for_all_local_got_entries(Got_offset_list::Visitor* v) const;
208158115Sume
209158115Sume  // Get the size of a section.
210158115Sume  uint64_t
211158115Sume  do_section_size(unsigned int shndx)
212158115Sume  { return this->elf_file_.section_size(shndx); }
213158115Sume
214158115Sume  // Get the name of a section.
215158115Sume  std::string
216158115Sume  do_section_name(unsigned int shndx) const
217158115Sume  { return this->elf_file_.section_name(shndx); }
218158115Sume
219158115Sume  // Return a view of the contents of a section.  Set *PLEN to the
220158115Sume  // size.
221158115Sume  const unsigned char*
222158115Sume  do_section_contents(unsigned int shndx, section_size_type* plen,
223158115Sume		      bool cache)
224158115Sume  {
225158115Sume    Location loc(this->elf_file_.section_contents(shndx));
226158115Sume    *plen = convert_to_section_size_type(loc.data_size);
227158115Sume    if (*plen == 0)
228158115Sume      {
229158115Sume	static const unsigned char empty[1] = { '\0' };
230158115Sume	return empty;
231158115Sume      }
232158115Sume    return this->get_view(loc.file_offset, *plen, true, cache);
233158115Sume  }
234158115Sume
235158115Sume  // Return section flags.
236158115Sume  uint64_t
237158115Sume  do_section_flags(unsigned int shndx)
238158115Sume  { return this->elf_file_.section_flags(shndx); }
239158115Sume
240158115Sume  // Not used for dynobj.
241158115Sume  uint64_t
242158115Sume  do_section_entsize(unsigned int )
243158115Sume  { gold_unreachable(); }
244158115Sume
245158115Sume  // Return section address.
246158115Sume  uint64_t
247158115Sume  do_section_address(unsigned int shndx)
248158115Sume  { return this->elf_file_.section_addr(shndx); }
249158115Sume
250158115Sume  // Return section type.
251158115Sume  unsigned int
252158115Sume  do_section_type(unsigned int shndx)
253158115Sume  { return this->elf_file_.section_type(shndx); }
254158115Sume
255158115Sume  // Return the section link field.
256158115Sume  unsigned int
257158115Sume  do_section_link(unsigned int shndx)
258158115Sume  { return this->elf_file_.section_link(shndx); }
259158115Sume
260158115Sume  // Return the section link field.
261158115Sume  unsigned int
262158115Sume  do_section_info(unsigned int shndx)
263158115Sume  { return this->elf_file_.section_info(shndx); }
264158115Sume
265158115Sume  // Return the section alignment.
266158115Sume  uint64_t
267158115Sume  do_section_addralign(unsigned int shndx)
268158115Sume  { return this->elf_file_.section_addralign(shndx); }
269158115Sume
270158115Sume  // Return the Xindex structure to use.
271158115Sume  Xindex*
272158115Sume  do_initialize_xindex();
273158115Sume
274158115Sume  // Get symbol counts.
275158115Sume  void
276158115Sume  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
277158115Sume
278158115Sume  // Get the global symbols.
279158115Sume  const Symbols*
280158115Sume  do_get_global_symbols() const
281158115Sume  { return this->symbols_; }
282158115Sume
283158115Sume protected:
284158115Sume  // Read the symbols.  This is common code for all target-specific
285158115Sume  // overrides of do_read_symbols().
286158115Sume  void
287158115Sume  base_read_symbols(Read_symbols_data*);
288158115Sume
289158115Sume private:
290158115Sume  // For convenience.
291158115Sume  typedef Sized_dynobj<size, big_endian> This;
292158115Sume  static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
293158115Sume  static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
294158115Sume  static const int dyn_size = elfcpp::Elf_sizes<size>::dyn_size;
295158115Sume  typedef elfcpp::Shdr<size, big_endian> Shdr;
296158115Sume  typedef elfcpp::Dyn<size, big_endian> Dyn;
297158115Sume
298158115Sume  // Adjust a section index if necessary.
299158115Sume  unsigned int
300158115Sume  adjust_shndx(unsigned int shndx)
301158115Sume  {
302158115Sume    if (shndx >= elfcpp::SHN_LORESERVE)
303158115Sume      shndx += this->elf_file_.large_shndx_offset();
304158115Sume    return shndx;
305158115Sume  }
306158115Sume
307158115Sume  // Find the dynamic symbol table and the version sections, given the
308158115Sume  // section headers.
309158115Sume  void
310158115Sume  find_dynsym_sections(const unsigned char* pshdrs,
311158115Sume		       unsigned int* pversym_shndx,
312158115Sume		       unsigned int* pverdef_shndx,
313158115Sume		       unsigned int* pverneed_shndx,
314158115Sume		       unsigned int* pdynamic_shndx);
315158115Sume
316158115Sume  // Read the dynamic symbol section SHNDX.
317158115Sume  void
318158115Sume  read_dynsym_section(const unsigned char* pshdrs, unsigned int shndx,
319158115Sume		      elfcpp::SHT type, unsigned int link,
320158115Sume		      File_view** view, section_size_type* view_size,
321158115Sume		      unsigned int* view_info);
322158115Sume
323158115Sume  // Read the dynamic tags.
324158115Sume  void
325158115Sume  read_dynamic(const unsigned char* pshdrs, unsigned int dynamic_shndx,
326158115Sume	       unsigned int strtab_shndx, const unsigned char* strtabu,
327158115Sume	       off_t strtab_size);
328158115Sume
329158115Sume  // Mapping from version number to version name.
330158115Sume  typedef std::vector<const char*> Version_map;
331158115Sume
332158115Sume  // Create the version map.
333158115Sume  void
334158115Sume  make_version_map(Read_symbols_data* sd, Version_map*) const;
335158115Sume
336158115Sume  // Add version definitions to the version map.
337158115Sume  void
338158115Sume  make_verdef_map(Read_symbols_data* sd, Version_map*) const;
339158115Sume
340158115Sume  // Add version references to the version map.
341158115Sume  void
342158115Sume  make_verneed_map(Read_symbols_data* sd, Version_map*) const;
343158115Sume
344158115Sume  // Add an entry to the version map.
345158115Sume  void
346158115Sume  set_version_map(Version_map*, unsigned int ndx, const char* name) const;
347158115Sume
348158115Sume  // General access to the ELF file.
349158115Sume  elfcpp::Elf_file<size, big_endian, Object> elf_file_;
350158115Sume  // The section index of the dynamic symbol table.
351158115Sume  unsigned int dynsym_shndx_;
352158115Sume  // The entries in the symbol table for the symbols.  We only keep
353158115Sume  // this if we need it to print symbol information.
354158115Sume  Symbols* symbols_;
355158115Sume  // Number of defined symbols.
356158115Sume  size_t defined_count_;
357158115Sume};
358158115Sume
359158115Sume// A base class for Verdef and Verneed_version which just handles the
360158115Sume// version index which will be stored in the SHT_GNU_versym section.
361158115Sume
362158115Sumeclass Version_base
363158115Sume{
364158115Sume public:
365158115Sume  Version_base()
366158115Sume    : index_(-1U)
367158115Sume  { }
368158115Sume
369158115Sume  virtual
370158115Sume  ~Version_base()
371158115Sume  { }
372158115Sume
373158115Sume  // Return the version index.
374158115Sume  unsigned int
375158115Sume  index() const
376158115Sume  {
377158115Sume    gold_assert(this->index_ != -1U);
378158115Sume    return this->index_;
379158115Sume  }
380158115Sume
381158115Sume  // Set the version index.
382158115Sume  void
383158115Sume  set_index(unsigned int index)
384158115Sume  {
385158115Sume    gold_assert(this->index_ == -1U);
386158115Sume    this->index_ = index;
387158115Sume  }
388158115Sume
389158115Sume  // Clear the weak flag in a version definition.
390158115Sume  virtual void
391158115Sume  clear_weak() = 0;
392158115Sume
393158115Sume private:
394158115Sume  Version_base(const Version_base&);
395158115Sume  Version_base& operator=(const Version_base&);
396158115Sume
397158115Sume  // The index of the version definition or reference.
398158115Sume  unsigned int index_;
399158115Sume};
400158115Sume
401158115Sume// This class handles a version being defined in the file we are
402158115Sume// generating.
403158115Sume
404158115Sumeclass Verdef : public Version_base
405158115Sume{
406158115Sume public:
407158115Sume  Verdef(const char* name, const std::vector<std::string>& deps,
408158115Sume         bool is_base, bool is_weak, bool is_info, bool is_symbol_created)
409158115Sume    : name_(name), deps_(deps), is_base_(is_base), is_weak_(is_weak),
410158115Sume      is_info_(is_info), is_symbol_created_(is_symbol_created)
411158115Sume  { }
412158115Sume
413158115Sume  // Return the version name.
414158115Sume  const char*
415158115Sume  name() const
416158115Sume  { return this->name_; }
417158115Sume
418158115Sume  // Return the number of dependencies.
419158115Sume  unsigned int
420158115Sume  count_dependencies() const
421158115Sume  { return this->deps_.size(); }
422158115Sume
423158115Sume  // Add a dependency to this version.  The NAME should be
424158115Sume  // canonicalized in the dynamic Stringpool.
425158115Sume  void
426158115Sume  add_dependency(const char* name)
427158115Sume  { this->deps_.push_back(name); }
428238094Sse
429238094Sse  // Return whether this definition is weak.
430238094Sse  bool
431238094Sse  is_weak() const
432238094Sse  { return this->is_weak_; }
433238094Sse
434158115Sume  // Clear the weak flag.
435158115Sume  void
436158115Sume  clear_weak()
437158115Sume  { this->is_weak_ = false; }
438158115Sume
439158115Sume  // Return whether this definition is informational.
440158115Sume  bool
441158115Sume  is_info() const
442158115Sume  { return this->is_info_; }
443158115Sume
444158115Sume  // Return whether a version symbol has been created for this
445158115Sume  // definition.
446158115Sume  bool
447158115Sume  is_symbol_created() const
448158115Sume  { return this->is_symbol_created_; }
449158115Sume
450158115Sume  // Write contents to buffer.
451158115Sume  template<int size, bool big_endian>
452158115Sume  unsigned char*
453158115Sume  write(const Stringpool*, bool is_last, unsigned char*) const;
454158115Sume
455158115Sume private:
456158115Sume  Verdef(const Verdef&);
457238094Sse  Verdef& operator=(const Verdef&);
458238094Sse
459238094Sse  // The type of the list of version dependencies.  Each dependency
460238094Sse  // should be canonicalized in the dynamic Stringpool.
461238094Sse  typedef std::vector<std::string> Deps;
462238094Sse
463158115Sume  // The name of this version.  This should be canonicalized in the
464158115Sume  // dynamic Stringpool.
465158115Sume  const char* name_;
466158115Sume  // A list of other versions which this version depends upon.
467158115Sume  Deps deps_;
468158115Sume  // Whether this is the base version.
469158115Sume  bool is_base_;
470158115Sume  // Whether this version is weak.
471158115Sume  bool is_weak_;
472158115Sume  // Whether this version is informational.
473158115Sume  bool is_info_;
474158115Sume  // Whether a version symbol has been created.
475158115Sume  bool is_symbol_created_;
476158115Sume};
477158115Sume
478158115Sume// A referened version.  This will be associated with a filename by
479158115Sume// Verneed.
480158115Sume
481158115Sumeclass Verneed_version : public Version_base
482158115Sume{
483158115Sume public:
484158115Sume  Verneed_version(const char* version)
485158115Sume    : version_(version)
486158115Sume  { }
487158115Sume
488158115Sume  // Return the version name.
489158115Sume  const char*
490158115Sume  version() const
491158115Sume  { return this->version_; }
492158115Sume
493158115Sume  // Clear the weak flag.  This is invalid for a reference.
494158115Sume  void
495158115Sume  clear_weak()
496158115Sume  { gold_unreachable(); }
497158115Sume
498158115Sume private:
499158115Sume  Verneed_version(const Verneed_version&);
500158115Sume  Verneed_version& operator=(const Verneed_version&);
501158115Sume
502158115Sume  const char* version_;
503158115Sume};
504158115Sume
505158115Sume// Version references in a single dynamic object.
506158115Sume
507158115Sumeclass Verneed
508158115Sume{
509158115Sume public:
510158115Sume  Verneed(const char* filename)
511158115Sume    : filename_(filename), need_versions_()
512158115Sume  { }
513158115Sume
514158115Sume  ~Verneed();
515158115Sume
516158115Sume  // Return the file name.
517158115Sume  const char*
518158115Sume  filename() const
519158115Sume  { return this->filename_; }
520158115Sume
521158115Sume  // Return the number of versions.
522158115Sume  unsigned int
523  count_versions() const
524  { return this->need_versions_.size(); }
525
526  // Add a version name.  The name should be canonicalized in the
527  // dynamic Stringpool.  If the name is already present, this does
528  // nothing.
529  Verneed_version*
530  add_name(const char* name);
531
532  // Set the version indexes, starting at INDEX.  Return the updated
533  // INDEX.
534  unsigned int
535  finalize(unsigned int index);
536
537  // Write contents to buffer.
538  template<int size, bool big_endian>
539  unsigned char*
540  write(const Stringpool*, bool is_last, unsigned char*) const;
541
542 private:
543  Verneed(const Verneed&);
544  Verneed& operator=(const Verneed&);
545
546  // The type of the list of version names.  Each name should be
547  // canonicalized in the dynamic Stringpool.
548  typedef std::vector<Verneed_version*> Need_versions;
549
550  // The filename of the dynamic object.  This should be
551  // canonicalized in the dynamic Stringpool.
552  const char* filename_;
553  // The list of version names.
554  Need_versions need_versions_;
555};
556
557// This class handles version definitions and references which go into
558// the output file.
559
560class Versions
561{
562 public:
563  Versions(const Version_script_info&, Stringpool*);
564
565  ~Versions();
566
567  // SYM is going into the dynamic symbol table and has a version.
568  // Record the appropriate version information.
569  void
570  record_version(const Symbol_table* symtab, Stringpool*, const Symbol* sym);
571
572  // Set the version indexes.  DYNSYM_INDEX is the index we should use
573  // for the next dynamic symbol.  We add new dynamic symbols to SYMS
574  // and return an updated DYNSYM_INDEX.
575  unsigned int
576  finalize(Symbol_table* symtab, unsigned int dynsym_index,
577	   std::vector<Symbol*>* syms);
578
579  // Return whether there are any version definitions.
580  bool
581  any_defs() const
582  { return !this->defs_.empty(); }
583
584  // Return whether there are any version references.
585  bool
586  any_needs() const
587  { return !this->needs_.empty(); }
588
589  // Build an allocated buffer holding the contents of the symbol
590  // version section (.gnu.version).
591  template<int size, bool big_endian>
592  void
593  symbol_section_contents(const Symbol_table*, const Stringpool*,
594			  unsigned int local_symcount,
595			  const std::vector<Symbol*>& syms,
596			  unsigned char**, unsigned int*) const;
597
598  // Build an allocated buffer holding the contents of the version
599  // definition section (.gnu.version_d).
600  template<int size, bool big_endian>
601  void
602  def_section_contents(const Stringpool*, unsigned char**,
603		       unsigned int* psize, unsigned int* pentries) const;
604
605  // Build an allocated buffer holding the contents of the version
606  // reference section (.gnu.version_r).
607  template<int size, bool big_endian>
608  void
609  need_section_contents(const Stringpool*, unsigned char**,
610			unsigned int* psize, unsigned int* pentries) const;
611
612  const Version_script_info&
613  version_script() const
614  { return this->version_script_; }
615
616 private:
617  Versions(const Versions&);
618  Versions& operator=(const Versions&);
619
620  // The type of the list of version definitions.
621  typedef std::vector<Verdef*> Defs;
622
623  // The type of the list of version references.
624  typedef std::vector<Verneed*> Needs;
625
626  // Handle a symbol SYM defined with version VERSION.
627  void
628  add_def(Stringpool*, const Symbol* sym, const char* version,
629	  Stringpool::Key);
630
631  // Add a reference to version NAME in file FILENAME.
632  void
633  add_need(Stringpool*, const char* filename, const char* name,
634	   Stringpool::Key);
635
636  // Get the dynamic object to use for SYM.
637  Dynobj*
638  get_dynobj_for_sym(const Symbol_table*, const Symbol* sym) const;
639
640  // Return the version index to use for SYM.
641  unsigned int
642  version_index(const Symbol_table*, const Stringpool*,
643		const Symbol* sym) const;
644
645  // Define the base version of a shared library.
646  void
647  define_base_version(Stringpool* dynpool);
648
649  // We keep a hash table mapping canonicalized name/version pairs to
650  // a version base.
651  typedef std::pair<Stringpool::Key, Stringpool::Key> Key;
652
653  struct Version_table_hash
654  {
655    size_t
656    operator()(const Key& k) const
657    { return k.first + k.second; }
658  };
659
660  struct Version_table_eq
661  {
662    bool
663    operator()(const Key& k1, const Key& k2) const
664    { return k1.first == k2.first && k1.second == k2.second; }
665  };
666
667  typedef Unordered_map<Key, Version_base*, Version_table_hash,
668			Version_table_eq> Version_table;
669
670  // The version definitions.
671  Defs defs_;
672  // The version references.
673  Needs needs_;
674  // The mapping from a canonicalized version/filename pair to a
675  // version index.  The filename may be NULL.
676  Version_table version_table_;
677  // Whether the version indexes have been set.
678  bool is_finalized_;
679  // Contents of --version-script, if passed, or NULL.
680  const Version_script_info& version_script_;
681  // Whether we need to insert a base version.  This is only used for
682  // shared libraries and is cleared when the base version is defined.
683  bool needs_base_version_;
684};
685
686} // End namespace gold.
687
688#endif // !defined(GOLD_DYNOBJ_H)
689