Commit | Line | Data |
---|---|---|
bae7f79e ILT |
1 | // symtab.h -- the gold symbol table -*- C++ -*- |
2 | ||
3 | // Symbol_table | |
4 | // The symbol table. | |
5 | ||
bae7f79e ILT |
6 | #include <string> |
7 | #include <utility> | |
8 | ||
9 | #include "elfcpp.h" | |
10 | #include "targetsize.h" | |
14bfc3f5 | 11 | #include "stringpool.h" |
bae7f79e ILT |
12 | |
13 | #ifndef GOLD_SYMTAB_H | |
14 | #define GOLD_SYMTAB_H | |
15 | ||
16 | namespace gold | |
17 | { | |
18 | ||
14bfc3f5 ILT |
19 | class Object; |
20 | ||
21 | template<int size, bool big_endian> | |
22 | class Sized_object; | |
23 | ||
24 | template<int size, bool big_endian> | |
25 | class Sized_target; | |
26 | ||
27 | // The base class of an entry in the symbol table. The symbol table | |
28 | // can have a lot of entries, so we don't want this class to big. | |
29 | // Size dependent fields can be found in the template class | |
30 | // Sized_symbol. Targets may support their own derived classes. | |
bae7f79e | 31 | |
bae7f79e ILT |
32 | class Symbol |
33 | { | |
34 | public: | |
14bfc3f5 ILT |
35 | virtual ~Symbol(); |
36 | ||
37 | // Return the symbol name. | |
38 | const char* | |
39 | name() const | |
40 | { return this->name_; } | |
41 | ||
42 | // Return the symbol version. This will return NULL for an | |
43 | // unversioned symbol. | |
44 | const char* | |
45 | version() const | |
46 | { return this->version_; } | |
47 | ||
48 | // Return whether this symbol is a forwarder. This will never be | |
49 | // true of a symbol found in the hash table, but may be true of | |
50 | // symbol pointers attached to object files. | |
51 | bool | |
52 | is_forwarder() const | |
53 | { return this->forwarder_; } | |
54 | ||
55 | // Mark this symbol as a forwarder. | |
56 | void | |
57 | set_forwarder() | |
58 | { this->forwarder_ = true; } | |
59 | ||
60 | // Return the object with which this symbol is associated. | |
61 | Object* | |
62 | object() const | |
63 | { return this->object_; } | |
64 | ||
65 | // Return the symbol binding. | |
66 | elfcpp::STB | |
67 | binding() const | |
68 | { return this->binding_; } | |
69 | ||
70 | // Return the section index. | |
71 | unsigned int | |
72 | shnum() const | |
73 | { return this->shnum_; } | |
74 | ||
75 | protected: | |
76 | // Instances of this class should always be created at a specific | |
77 | // size. | |
78 | Symbol() | |
79 | { } | |
80 | ||
81 | // Initialize fields from an ELF symbol in OBJECT. | |
82 | template<int size, bool big_endian> | |
83 | void | |
84 | init_base(const char *name, const char* version, Object* object, | |
85 | const elfcpp::Sym<size, big_endian>&); | |
bae7f79e ILT |
86 | |
87 | private: | |
14bfc3f5 ILT |
88 | Symbol(const Symbol&); |
89 | Symbol& operator=(const Symbol&); | |
90 | ||
91 | // Symbol name (expected to point into a Stringpool). | |
92 | const char* name_; | |
93 | // Symbol version (expected to point into a Stringpool). This may | |
94 | // be NULL. | |
bae7f79e | 95 | const char* version_; |
14bfc3f5 | 96 | // Object in which symbol is defined, or in which it was first seen. |
bae7f79e | 97 | Object* object_; |
14bfc3f5 | 98 | // Section number in object_ in which symbol is defined. |
bae7f79e | 99 | unsigned int shnum_; |
14bfc3f5 | 100 | // Symbol type. |
bae7f79e | 101 | elfcpp::STT type_ : 4; |
14bfc3f5 | 102 | // Symbol binding. |
bae7f79e | 103 | elfcpp::STB binding_ : 4; |
14bfc3f5 ILT |
104 | // Symbol visibility. |
105 | elfcpp::STV visibility_ : 2; | |
106 | // Rest of symbol st_other field. | |
bae7f79e | 107 | unsigned int other_ : 6; |
14bfc3f5 ILT |
108 | // True if this symbol always requires special target-specific |
109 | // handling. | |
110 | bool special_ : 1; | |
111 | // True if this is the default version of the symbol. | |
112 | bool def_ : 1; | |
113 | // True if this symbol really forwards to another symbol. This is | |
114 | // used when we discover after the fact that two different entries | |
115 | // in the hash table really refer to the same symbol. This will | |
116 | // never be set for a symbol found in the hash table, but may be set | |
117 | // for a symbol found in the list of symbols attached to an Object. | |
118 | // It forwards to the symbol found in the forwarders_ map of | |
119 | // Symbol_table. | |
120 | bool forwarder_ : 1; | |
bae7f79e ILT |
121 | }; |
122 | ||
14bfc3f5 ILT |
123 | // The parts of a symbol which are size specific. Using a template |
124 | // derived class like this helps us use less space on a 32-bit system. | |
bae7f79e ILT |
125 | |
126 | template<int size> | |
14bfc3f5 ILT |
127 | class Sized_symbol : public Symbol |
128 | { | |
129 | public: | |
130 | Sized_symbol() | |
131 | { } | |
132 | ||
133 | // Initialize fields from an ELF symbol in OBJECT. | |
134 | template<bool big_endian> | |
135 | void | |
136 | init(const char *name, const char* version, Object* object, | |
137 | const elfcpp::Sym<size, big_endian>&); | |
138 | ||
139 | private: | |
140 | Sized_symbol(const Sized_symbol&); | |
141 | Sized_symbol& operator=(const Sized_symbol&); | |
142 | ||
143 | // Symbol value. | |
144 | typename elfcpp::Elf_types<size>::Elf_Addr value_; | |
145 | // Symbol size. | |
146 | typename elfcpp::Elf_types<size>::Elf_WXword size_; | |
147 | }; | |
148 | ||
149 | // The main linker symbol table. | |
150 | ||
bae7f79e ILT |
151 | class Symbol_table |
152 | { | |
153 | public: | |
154 | Symbol_table(); | |
155 | ||
14bfc3f5 | 156 | virtual ~Symbol_table(); |
bae7f79e | 157 | |
14bfc3f5 ILT |
158 | // Add COUNT external symbols from OBJECT to the symbol table. SYMS |
159 | // is the symbols, SYM_NAMES is their names, SYM_NAME_SIZE is the | |
160 | // size of SYM_NAMES. This sets SYMPOINTERS to point to the symbols | |
161 | // in the symbol table. | |
162 | template<int size, bool big_endian> | |
163 | void | |
164 | add_from_object(Sized_object<size, big_endian>* object, | |
165 | const elfcpp::Sym<size, big_endian>* syms, | |
166 | size_t count, const char* sym_names, size_t sym_name_size, | |
167 | Symbol** sympointers); | |
168 | ||
169 | // Return the real symbol associated with the forwarder symbol FROM. | |
bae7f79e | 170 | Symbol* |
14bfc3f5 | 171 | resolve_forwards(Symbol* from) const; |
bae7f79e | 172 | |
14bfc3f5 ILT |
173 | // Return the size of the symbols in the table. |
174 | int | |
175 | get_size() const | |
176 | { return this->size_; } | |
bae7f79e ILT |
177 | |
178 | private: | |
179 | Symbol_table(const Symbol_table&); | |
180 | Symbol_table& operator=(const Symbol_table&); | |
181 | ||
14bfc3f5 ILT |
182 | // Set the size of the symbols in the table. |
183 | void | |
184 | set_size(int size) | |
185 | { this->size_ = size; } | |
186 | ||
187 | // Make FROM a forwarder symbol to TO. | |
188 | void | |
189 | make_forwarder(Symbol* from, Symbol* to); | |
190 | ||
191 | // Add a symbol. | |
192 | template<int size, bool big_endian> | |
193 | Symbol* | |
194 | add_from_object(Sized_object<size, big_endian>*, const char *name, | |
195 | const char *version, bool def, | |
196 | const elfcpp::Sym<size, big_endian>& sym); | |
197 | ||
198 | // Resolve symbols. | |
199 | template<int size, bool big_endian> | |
200 | static void | |
201 | resolve(Symbol* to, const elfcpp::Sym<size, big_endian>& sym, Object*); | |
202 | ||
203 | static void | |
204 | resolve(Symbol* to, const Symbol* from); | |
205 | ||
206 | typedef std::pair<const char*, const char*> Symbol_table_key; | |
207 | ||
208 | struct Symbol_table_hash | |
209 | { | |
210 | size_t | |
211 | operator()(const Symbol_table_key&) const; | |
212 | }; | |
213 | ||
214 | struct Symbol_table_eq | |
215 | { | |
216 | bool | |
217 | operator()(const Symbol_table_key&, const Symbol_table_key&) const; | |
218 | }; | |
219 | ||
220 | typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash, | |
221 | Symbol_table_eq> Symbol_table_type; | |
222 | ||
223 | // The size of the symbols in the symbol table (32 or 64). | |
224 | int size_; | |
225 | ||
226 | // The symbol table itself. | |
227 | Symbol_table_type table_; | |
228 | ||
229 | // A pool of symbol names. | |
230 | Stringpool namepool_; | |
bae7f79e | 231 | |
14bfc3f5 ILT |
232 | // Forwarding symbols. |
233 | Unordered_map<Symbol*, Symbol*> forwarders_; | |
bae7f79e ILT |
234 | }; |
235 | ||
236 | } // End namespace gold. | |
237 | ||
238 | #endif // !defined(GOLD_SYMTAB_H) |