xref: /dflybsd-src/contrib/binutils-2.34/gold/dynobj.h (revision b52ef7118d1621abed722c5bbbd542210290ecef)
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