Commit | Line | Data |
---|---|---|
14bfc3f5 ILT |
1 | // resolve.cc -- symbol resolution for gold |
2 | ||
3 | #include "gold.h" | |
4 | ||
5 | #include "elfcpp.h" | |
6 | #include "target.h" | |
7 | #include "object.h" | |
8 | #include "symtab.h" | |
9 | ||
10 | namespace gold | |
11 | { | |
12 | ||
13 | // Resolve a symbol. This is called the second and subsequent times | |
14 | // we see a symbol. TO is the pre-existing symbol. SYM is the new | |
15 | // symbol, seen in OBJECT. | |
16 | ||
17 | template<int size, bool big_endian> | |
18 | void | |
19 | Symbol_table::resolve(Symbol* to, | |
20 | const elfcpp::Sym<size, big_endian>& sym, | |
21 | Object* object) | |
22 | { | |
23 | if (object->target()->has_resolve()) | |
24 | { | |
25 | object->sized_target<size, big_endian>()->resolve(to, sym, object); | |
26 | return; | |
27 | } | |
28 | ||
29 | // Build a little code for each symbol. | |
30 | // Bit 0: 0 for global, 1 for weak. | |
31 | // Bit 1: 0 for regular object, 1 for shared object | |
32 | // Bits 2-3: 0 for normal, 1 for undefined, 2 for common | |
33 | // This gives us values from 0 to 11: | |
34 | ||
35 | enum | |
36 | { | |
37 | DEF = 0, | |
38 | WEAK_DEF = 1, | |
39 | DYN_DEF = 2, | |
40 | DYN_WEAK_DEF = 3, | |
41 | UNDEF = 4, | |
42 | WEAK_UNDEF = 5, | |
43 | DYN_UNDEF = 6, | |
44 | DYN_WEAK_UNDEF = 7, | |
45 | COMMON = 8, | |
46 | WEAK_COMMON = 9, | |
47 | DYN_COMMON = 10, | |
48 | DYN_WEAK_COMMON = 11 | |
49 | }; | |
50 | ||
51 | int tobits; | |
52 | switch (to->binding()) | |
53 | { | |
54 | case elfcpp::STB_GLOBAL: | |
55 | tobits = 0; | |
56 | break; | |
57 | ||
58 | case elfcpp::STB_WEAK: | |
59 | tobits = 1; | |
60 | break; | |
61 | ||
62 | case elfcpp::STB_LOCAL: | |
63 | // We should only see externally visible symbols in the symbol | |
64 | // table. | |
65 | abort(); | |
66 | ||
67 | default: | |
68 | // Any target which wants to handle STB_LOOS, etc., needs to | |
69 | // define a resolve method. | |
70 | abort(); | |
71 | } | |
72 | ||
73 | if (to->object() != NULL && to->object()->is_dynamic()) | |
74 | tobits |= (1 << 1); | |
75 | ||
76 | switch (to->shnum()) | |
77 | { | |
78 | case elfcpp::SHN_UNDEF: | |
79 | tobits |= (1 << 2); | |
80 | break; | |
81 | ||
82 | case elfcpp::SHN_COMMON: | |
83 | tobits |= (2 << 2); | |
84 | break; | |
85 | ||
86 | default: | |
87 | break; | |
88 | } | |
89 | ||
90 | int frombits; | |
91 | switch (sym.get_st_bind()) | |
92 | { | |
93 | case elfcpp::STB_GLOBAL: | |
94 | frombits = 0; | |
95 | break; | |
96 | ||
97 | case elfcpp::STB_WEAK: | |
98 | frombits = 1; | |
99 | break; | |
100 | ||
101 | case elfcpp::STB_LOCAL: | |
102 | fprintf(stderr, | |
103 | _("%s: %s: invalid STB_LOCAL symbol %s in external symbols\n"), | |
104 | program_name, object->name().c_str(), to->name()); | |
105 | gold_exit(false); | |
106 | ||
107 | default: | |
108 | fprintf(stderr, | |
109 | _("%s: %s: unsupported symbol binding %d for symbol %s\n"), | |
110 | program_name, object->name().c_str(), | |
111 | static_cast<int>(sym.get_st_bind()), to->name()); | |
112 | gold_exit(false); | |
113 | } | |
114 | ||
115 | if (object->is_dynamic()) | |
116 | frombits |= (1 << 1); | |
117 | ||
118 | switch (sym.get_st_shndx()) | |
119 | { | |
120 | case elfcpp::SHN_UNDEF: | |
121 | frombits |= (1 << 2); | |
122 | break; | |
123 | ||
124 | case elfcpp::SHN_COMMON: | |
125 | frombits |= (2 << 2); | |
126 | break; | |
127 | ||
128 | default: | |
129 | break; | |
130 | } | |
131 | ||
132 | // We use a giant switch table for symbol resolution. This code is | |
133 | // unwieldy, but: 1) it is efficient; 2) we definitely handle all | |
134 | // cases; 3) it is easy to change the handling of a particular case. | |
135 | // The alternative would be a series of conditionals, but it is easy | |
136 | // to get the ordering wrong. This could also be done as a table, | |
137 | // but that is no easier to understand than this large switch | |
138 | // statement. | |
139 | ||
140 | switch (tobits * 16 + frombits) | |
141 | { | |
142 | case DEF * 16 + DEF: | |
143 | // Two definitions of the same symbol. | |
144 | fprintf(stderr, "%s: %s: multiple definition of %s\n", | |
145 | program_name, object->name().c_str(), to->name()); | |
146 | // FIXME: Report locations. Record that we have seen an error. | |
147 | return; | |
148 | ||
149 | case WEAK_DEF * 16 + DEF: | |
150 | // In the original SVR4 linker, a weak definition followed by a | |
151 | // regular definition was treated as a multiple definition | |
152 | // error. In the Solaris linker and the GNU linker, a weak | |
153 | // definition followed by a regular definition causes the | |
154 | // regular definition to be ignored. We are currently | |
155 | // compatible with the GNU linker. In the future we should add | |
156 | // a target specific option to change this. FIXME. | |
157 | return; | |
158 | ||
159 | case DYN_DEF * 16 + DEF: | |
160 | case DYN_WEAK_DEF * 16 + DEF: | |
161 | case UNDEF * 16 + DEF: | |
162 | case WEAK_UNDEF * 16 + DEF: | |
163 | case DYN_UNDEF * 16 + DEF: | |
164 | case DYN_WEAK_UNDEF * 16 + DEF: | |
165 | case COMMON * 16 + DEF: | |
166 | case WEAK_COMMON * 16 + DEF: | |
167 | case DYN_COMMON * 16 + DEF: | |
168 | case DYN_WEAK_COMMON * 16 + DEF: | |
169 | ||
170 | case DEF * 16 + WEAK_DEF: | |
171 | case WEAK_DEF * 16 + WEAK_DEF: | |
172 | case DYN_DEF * 16 + WEAK_DEF: | |
173 | case DYN_WEAK_DEF * 16 + WEAK_DEF: | |
174 | case UNDEF * 16 + WEAK_DEF: | |
175 | case WEAK_UNDEF * 16 + WEAK_DEF: | |
176 | case DYN_UNDEF * 16 + WEAK_DEF: | |
177 | case DYN_WEAK_UNDEF * 16 + WEAK_DEF: | |
178 | case COMMON * 16 + WEAK_DEF: | |
179 | case WEAK_COMMON * 16 + WEAK_DEF: | |
180 | case DYN_COMMON * 16 + WEAK_DEF: | |
181 | case DYN_WEAK_COMMON * 16 + WEAK_DEF: | |
182 | ||
183 | case DEF * 16 + DYN_DEF: | |
184 | case WEAK_DEF * 16 + DYN_DEF: | |
185 | case DYN_DEF * 16 + DYN_DEF: | |
186 | case DYN_WEAK_DEF * 16 + DYN_DEF: | |
187 | case UNDEF * 16 + DYN_DEF: | |
188 | case WEAK_UNDEF * 16 + DYN_DEF: | |
189 | case DYN_UNDEF * 16 + DYN_DEF: | |
190 | case DYN_WEAK_UNDEF * 16 + DYN_DEF: | |
191 | case COMMON * 16 + DYN_DEF: | |
192 | case WEAK_COMMON * 16 + DYN_DEF: | |
193 | case DYN_COMMON * 16 + DYN_DEF: | |
194 | case DYN_WEAK_COMMON * 16 + DYN_DEF: | |
195 | ||
196 | case DEF * 16 + DYN_WEAK_DEF: | |
197 | case WEAK_DEF * 16 + DYN_WEAK_DEF: | |
198 | case DYN_DEF * 16 + DYN_WEAK_DEF: | |
199 | case DYN_WEAK_DEF * 16 + DYN_WEAK_DEF: | |
200 | case UNDEF * 16 + DYN_WEAK_DEF: | |
201 | case WEAK_UNDEF * 16 + DYN_WEAK_DEF: | |
202 | case DYN_UNDEF * 16 + DYN_WEAK_DEF: | |
203 | case DYN_WEAK_UNDEF * 16 + DYN_WEAK_DEF: | |
204 | case COMMON * 16 + DYN_WEAK_DEF: | |
205 | case WEAK_COMMON * 16 + DYN_WEAK_DEF: | |
206 | case DYN_COMMON * 16 + DYN_WEAK_DEF: | |
207 | case DYN_WEAK_COMMON * 16 + DYN_WEAK_DEF: | |
208 | ||
209 | case DEF * 16 + UNDEF: | |
210 | case WEAK_DEF * 16 + UNDEF: | |
211 | case DYN_DEF * 16 + UNDEF: | |
212 | case DYN_WEAK_DEF * 16 + UNDEF: | |
213 | case UNDEF * 16 + UNDEF: | |
214 | case WEAK_UNDEF * 16 + UNDEF: | |
215 | case DYN_UNDEF * 16 + UNDEF: | |
216 | case DYN_WEAK_UNDEF * 16 + UNDEF: | |
217 | case COMMON * 16 + UNDEF: | |
218 | case WEAK_COMMON * 16 + UNDEF: | |
219 | case DYN_COMMON * 16 + UNDEF: | |
220 | case DYN_WEAK_COMMON * 16 + UNDEF: | |
221 | ||
222 | case DEF * 16 + WEAK_UNDEF: | |
223 | case WEAK_DEF * 16 + WEAK_UNDEF: | |
224 | case DYN_DEF * 16 + WEAK_UNDEF: | |
225 | case DYN_WEAK_DEF * 16 + WEAK_UNDEF: | |
226 | case UNDEF * 16 + WEAK_UNDEF: | |
227 | case WEAK_UNDEF * 16 + WEAK_UNDEF: | |
228 | case DYN_UNDEF * 16 + WEAK_UNDEF: | |
229 | case DYN_WEAK_UNDEF * 16 + WEAK_UNDEF: | |
230 | case COMMON * 16 + WEAK_UNDEF: | |
231 | case WEAK_COMMON * 16 + WEAK_UNDEF: | |
232 | case DYN_COMMON * 16 + WEAK_UNDEF: | |
233 | case DYN_WEAK_COMMON * 16 + WEAK_UNDEF: | |
234 | ||
235 | case DEF * 16 + DYN_UNDEF: | |
236 | case WEAK_DEF * 16 + DYN_UNDEF: | |
237 | case DYN_DEF * 16 + DYN_UNDEF: | |
238 | case DYN_WEAK_DEF * 16 + DYN_UNDEF: | |
239 | case UNDEF * 16 + DYN_UNDEF: | |
240 | case WEAK_UNDEF * 16 + DYN_UNDEF: | |
241 | case DYN_UNDEF * 16 + DYN_UNDEF: | |
242 | case DYN_WEAK_UNDEF * 16 + DYN_UNDEF: | |
243 | case COMMON * 16 + DYN_UNDEF: | |
244 | case WEAK_COMMON * 16 + DYN_UNDEF: | |
245 | case DYN_COMMON * 16 + DYN_UNDEF: | |
246 | case DYN_WEAK_COMMON * 16 + DYN_UNDEF: | |
247 | ||
248 | case DEF * 16 + DYN_WEAK_UNDEF: | |
249 | case WEAK_DEF * 16 + DYN_WEAK_UNDEF: | |
250 | case DYN_DEF * 16 + DYN_WEAK_UNDEF: | |
251 | case DYN_WEAK_DEF * 16 + DYN_WEAK_UNDEF: | |
252 | case UNDEF * 16 + DYN_WEAK_UNDEF: | |
253 | case WEAK_UNDEF * 16 + DYN_WEAK_UNDEF: | |
254 | case DYN_UNDEF * 16 + DYN_WEAK_UNDEF: | |
255 | case DYN_WEAK_UNDEF * 16 + DYN_WEAK_UNDEF: | |
256 | case COMMON * 16 + DYN_WEAK_UNDEF: | |
257 | case WEAK_COMMON * 16 + DYN_WEAK_UNDEF: | |
258 | case DYN_COMMON * 16 + DYN_WEAK_UNDEF: | |
259 | case DYN_WEAK_COMMON * 16 + DYN_WEAK_UNDEF: | |
260 | ||
261 | case DEF * 16 + COMMON: | |
262 | case WEAK_DEF * 16 + COMMON: | |
263 | case DYN_DEF * 16 + COMMON: | |
264 | case DYN_WEAK_DEF * 16 + COMMON: | |
265 | case UNDEF * 16 + COMMON: | |
266 | case WEAK_UNDEF * 16 + COMMON: | |
267 | case DYN_UNDEF * 16 + COMMON: | |
268 | case DYN_WEAK_UNDEF * 16 + COMMON: | |
269 | case COMMON * 16 + COMMON: | |
270 | case WEAK_COMMON * 16 + COMMON: | |
271 | case DYN_COMMON * 16 + COMMON: | |
272 | case DYN_WEAK_COMMON * 16 + COMMON: | |
273 | ||
274 | case DEF * 16 + WEAK_COMMON: | |
275 | case WEAK_DEF * 16 + WEAK_COMMON: | |
276 | case DYN_DEF * 16 + WEAK_COMMON: | |
277 | case DYN_WEAK_DEF * 16 + WEAK_COMMON: | |
278 | case UNDEF * 16 + WEAK_COMMON: | |
279 | case WEAK_UNDEF * 16 + WEAK_COMMON: | |
280 | case DYN_UNDEF * 16 + WEAK_COMMON: | |
281 | case DYN_WEAK_UNDEF * 16 + WEAK_COMMON: | |
282 | case COMMON * 16 + WEAK_COMMON: | |
283 | case WEAK_COMMON * 16 + WEAK_COMMON: | |
284 | case DYN_COMMON * 16 + WEAK_COMMON: | |
285 | case DYN_WEAK_COMMON * 16 + WEAK_COMMON: | |
286 | ||
287 | case DEF * 16 + DYN_COMMON: | |
288 | case WEAK_DEF * 16 + DYN_COMMON: | |
289 | case DYN_DEF * 16 + DYN_COMMON: | |
290 | case DYN_WEAK_DEF * 16 + DYN_COMMON: | |
291 | case UNDEF * 16 + DYN_COMMON: | |
292 | case WEAK_UNDEF * 16 + DYN_COMMON: | |
293 | case DYN_UNDEF * 16 + DYN_COMMON: | |
294 | case DYN_WEAK_UNDEF * 16 + DYN_COMMON: | |
295 | case COMMON * 16 + DYN_COMMON: | |
296 | case WEAK_COMMON * 16 + DYN_COMMON: | |
297 | case DYN_COMMON * 16 + DYN_COMMON: | |
298 | case DYN_WEAK_COMMON * 16 + DYN_COMMON: | |
299 | ||
300 | case DEF * 16 + DYN_WEAK_COMMON: | |
301 | case WEAK_DEF * 16 + DYN_WEAK_COMMON: | |
302 | case DYN_DEF * 16 + DYN_WEAK_COMMON: | |
303 | case DYN_WEAK_DEF * 16 + DYN_WEAK_COMMON: | |
304 | case UNDEF * 16 + DYN_WEAK_COMMON: | |
305 | case WEAK_UNDEF * 16 + DYN_WEAK_COMMON: | |
306 | case DYN_UNDEF * 16 + DYN_WEAK_COMMON: | |
307 | case DYN_WEAK_UNDEF * 16 + DYN_WEAK_COMMON: | |
308 | case COMMON * 16 + DYN_WEAK_COMMON: | |
309 | case WEAK_COMMON * 16 + DYN_WEAK_COMMON: | |
310 | case DYN_COMMON * 16 + DYN_WEAK_COMMON: | |
311 | case DYN_WEAK_COMMON * 16 + DYN_WEAK_COMMON: | |
312 | ||
313 | break; | |
314 | } | |
315 | } | |
316 | ||
317 | // Instantiate the templates we need. We could use the configure | |
318 | // script to restrict this to only the ones needed for implemented | |
319 | // targets. | |
320 | ||
321 | template | |
322 | void | |
323 | Symbol_table::resolve<32, true>( | |
324 | Symbol* to, | |
325 | const elfcpp::Sym<32, true>& sym, | |
326 | Object* object); | |
327 | ||
328 | template | |
329 | void | |
330 | Symbol_table::resolve<32, false>( | |
331 | Symbol* to, | |
332 | const elfcpp::Sym<32, false>& sym, | |
333 | Object* object); | |
334 | ||
335 | template | |
336 | void | |
337 | Symbol_table::resolve<64, true>( | |
338 | Symbol* to, | |
339 | const elfcpp::Sym<64, true>& sym, | |
340 | Object* object); | |
341 | ||
342 | template | |
343 | void | |
344 | Symbol_table::resolve<64, false>( | |
345 | Symbol* to, | |
346 | const elfcpp::Sym<64, false>& sym, | |
347 | Object* object); | |
348 | ||
349 | } // End namespace gold. |