1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
25 *
26 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
27 */
28
29 /*
30 * Symbol table resolution
31 */
32 #define ELF_TARGET_AMD64
33
34 #include <stdio.h>
35 #include <debug.h>
36 #include "msg.h"
37 #include "_libld.h"
38
39
40 /*
41 * Categorize the symbol types that are applicable to the resolution process.
42 */
43 typedef enum {
44 SYM_DEFINED, /* Defined symbol (SHN_ABS or shndx != 0) */
45 SYM_UNDEFINED, /* Undefined symbol (SHN_UNDEF) */
46 SYM_TENTATIVE, /* Tentative symbol (SHN_COMMON) */
47 SYM_NUM /* the number of symbol types */
48 } Symtype;
49
50 /*
51 * Do nothing.
52 */
53 /* ARGSUSED0 */
54 static void
sym_null(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)55 sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
56 int ndx, Word nshndx, sd_flag_t nsdflags)
57 {
58 }
59
60 static void
sym_visibility_diag(Error err,Sym_desc * sdp,Sym * osym,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl)61 sym_visibility_diag(Error err, Sym_desc *sdp, Sym *osym, Sym *nsym,
62 Ifl_desc *ifl, Ofl_desc *ofl)
63 {
64 Conv_inv_buf_t inv_obuf, inv_nbuf;
65
66 /* Warnings are only issued when -z verbose is specified */
67 if (!(ofl->ofl_flags & FLG_OF_VERBOSE) && (err != ERR_FATAL))
68 return;
69
70 ld_eprintf(ofl, err, MSG_INTL(MSG_SYM_CONFVIS), demangle(sdp->sd_name));
71 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES),
72 sdp->sd_file->ifl_name, conv_sym_other(osym->st_other, &inv_obuf),
73 ifl->ifl_name, conv_sym_other(nsym->st_other, &inv_nbuf));
74
75 if (err != ERR_FATAL)
76 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
77 ifl->ifl_name);
78 }
79
80 /*
81 * STV_VISIBILITY rules for STV_DEFAULT/INTERNAL/HIDDEN/PROTECTED say that the
82 * most restrictive visibility value should be taken. The precedence is:
83 *
84 * (most restrictive) INTERNAL -> HIDDEN -> PROTECTED -> DEFAULT (least)
85 *
86 * The STV_EXPORT and STV_SINGLETON visibilities are slightly different, in that
87 * the visibility must remain global and can not be reduced in any way.
88 *
89 * Resolution of different visibilities between two relocatable objects can
90 * take the following actions:
91 *
92 * i. if applicable, the most restrictive action is silently taken.
93 * ii. if a mapfile visibility definition competes with a more restrictive
94 * relocatable object definition, then a warning is generated, but the
95 * the more restrictive visibility is taken.
96 * iii. in the case of conflicts with an EXPORTED or SINGLETON symbol with
97 * any type of visibility between relocatable objects, the combination
98 * is deemed fatal.
99 *
100 * new visibility
101 * D I H P X S
102 * ------------------------------------------------------------
103 * D | D I(mw) H(mw) P X S
104 * original I | I I I I X(mw/of) S(mw/of)
105 * visibility H | H I(mw) H H X(mw/of) S(mw/of)
106 * P | P I(mw) H(mw) P X(mw/of) S(mw/of)
107 * X | X I(mw/of) H(mw/of) P(mw/of) X S
108 * S | S I(mw/of) H(mw/of) P(mw/of) S S
109 * where:
110 *
111 * mw - mapfile warning: if the original symbol originates from a mapfile
112 * then warn the user that their scope definition is being overridden.
113 * of - object definitions are fatal: any combination of relocatable object
114 * visibilities that conflict with a SINGLETON and EXPORTED are fatal.
115 *
116 * Note, an eliminate symbol (STV_ELIMINATE) is treated as hidden (STV_HIDDEN)
117 * for processing through this state table.
118 */
119 static Half
sym_visibility(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl)120 sym_visibility(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl)
121 {
122 Sym *osym = sdp->sd_sym;
123 uchar_t wovis, ovis;
124 uchar_t wnvis, nvis;
125
126 wovis = ovis = ELF_ST_VISIBILITY(osym->st_other);
127 wnvis = nvis = ELF_ST_VISIBILITY(nsym->st_other);
128
129 /*
130 * If the original visibilities are eliminate, assign them hidden for
131 * the state table processing. The original visibility, rather than
132 * the working visibility, will be returned to the caller.
133 */
134 if (wovis == STV_ELIMINATE)
135 wovis = STV_HIDDEN;
136 if (wnvis == STV_ELIMINATE)
137 wnvis = STV_HIDDEN;
138
139 /*
140 * The most complex visibility resolution is between two relocatable
141 * objects. However, in the case of SINGLETONS we also want to catch
142 * any singleton definitions within shared objects. Relocatable objects
143 * that bind to these symbols inherit the singleton visibility as this
144 * efficiently triggers ld.so.1 into carrying out the appropriate
145 * runtime symbol search. Any other resolution between a relocatable
146 * object and a shared object will retain the relocatable objects
147 * visibility.
148 */
149 if ((sdp->sd_ref == REF_REL_NEED) &&
150 (ifl->ifl_ehdr->e_type == ET_DYN)) {
151 if ((sdp->sd_sym->st_shndx == SHN_UNDEF) &&
152 (nsym->st_shndx != SHN_UNDEF) && (wnvis == STV_SINGLETON))
153 return (STV_SINGLETON);
154 else
155 return (ovis);
156 }
157 if ((sdp->sd_ref != REF_REL_NEED) &&
158 (ifl->ifl_ehdr->e_type == ET_REL)) {
159 if ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
160 (nsym->st_shndx == SHN_UNDEF) && (wovis == STV_SINGLETON))
161 return (STV_SINGLETON);
162 else
163 return (nvis);
164 }
165
166 /*
167 * If the visibilities are the same, we're done. If the working
168 * visibilities differ from the original, then one must have been
169 * STV_HIDDEN and the other STV_ELIMINATE.
170 */
171 if (wovis == wnvis) {
172 if (ovis == nvis)
173 return (nvis);
174 else
175 return (STV_ELIMINATE);
176 }
177
178 /*
179 * An EXPORTED symbol or SINGLETON symbol can not be demoted, any
180 * conflicting visibility from another object is fatal. A conflicting
181 * visibility from a mapfile produces a warning, as the mapfile
182 * definition can be overridden.
183 */
184 if ((wnvis == STV_EXPORTED) || (wnvis == STV_SINGLETON)) {
185 if ((wovis != STV_DEFAULT) && (wovis != STV_EXPORTED) &&
186 (wovis != STV_SINGLETON)) {
187 if (sdp->sd_flags & FLG_SY_MAPFILE) {
188 sym_visibility_diag(ERR_WARNING, sdp, osym,
189 nsym, ifl, ofl);
190 } else {
191 sym_visibility_diag(ERR_FATAL, sdp, osym,
192 nsym, ifl, ofl);
193 }
194 }
195 return (nvis);
196 }
197 if (wovis == STV_SINGLETON) {
198 if ((wnvis == STV_EXPORTED) || (wnvis == STV_DEFAULT))
199 return (STV_SINGLETON);
200 if (sdp->sd_flags & FLG_SY_MAPFILE) {
201 sym_visibility_diag(ERR_WARNING, sdp, osym,
202 nsym, ifl, ofl);
203 } else {
204 sym_visibility_diag(ERR_FATAL, sdp, osym,
205 nsym, ifl, ofl);
206 }
207 return (nvis);
208 }
209 if (wovis == STV_EXPORTED) {
210 if (wnvis == STV_SINGLETON)
211 return (STV_SINGLETON);
212 if (wnvis == STV_DEFAULT)
213 return (STV_EXPORTED);
214 if (sdp->sd_flags & FLG_SY_MAPFILE) {
215 sym_visibility_diag(ERR_WARNING, sdp, osym,
216 nsym, ifl, ofl);
217 } else {
218 sym_visibility_diag(ERR_FATAL, sdp, osym,
219 nsym, ifl, ofl);
220 }
221 return (nvis);
222 }
223
224 /*
225 * Now that symbols with the same visibility, and all instances of
226 * SINGLETON's have been dealt with, we're left with visibilities that
227 * differ, but can be dealt with in the order of how restrictive the
228 * visibilities are. When a differing visibility originates from a
229 * mapfile definition, produces a warning, as the mapfile definition
230 * can be overridden by the relocatable object.
231 */
232 if ((wnvis == STV_INTERNAL) || (wovis == STV_INTERNAL)) {
233 if ((wnvis == STV_INTERNAL) &&
234 (sdp->sd_flags & FLG_SY_MAPFILE)) {
235 sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
236 ifl, ofl);
237 }
238 return (STV_INTERNAL);
239
240 } else if ((wnvis == STV_HIDDEN) || (wovis == STV_HIDDEN)) {
241 if ((wnvis == STV_HIDDEN) &&
242 (sdp->sd_flags & FLG_SY_MAPFILE)) {
243 sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
244 ifl, ofl);
245 }
246
247 /*
248 * In the case of STV_ELIMINATE and STV_HIDDEN, the working
249 * visibility can differ from the original visibility, so make
250 * sure to return the original visibility.
251 */
252 if ((ovis == STV_ELIMINATE) || (nvis == STV_ELIMINATE))
253 return (STV_ELIMINATE);
254 else
255 return (STV_HIDDEN);
256
257 } else if ((wnvis == STV_PROTECTED) || (wovis == STV_PROTECTED))
258 return (STV_PROTECTED);
259
260 return (STV_DEFAULT);
261 }
262
263 /*
264 * Check if two symbols types are compatible
265 */
266 /*ARGSUSED4*/
267 static void
sym_typecheck(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)268 sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
269 int ndx, Word nshndx, sd_flag_t nsdflags)
270 {
271 uchar_t otype = ELF_ST_TYPE(sdp->sd_sym->st_info);
272 uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
273 Conv_inv_buf_t inv_buf1, inv_buf2;
274
275 /*
276 * Perform any machine specific type checking.
277 */
278 if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
279 (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
280 return;
281
282 /*
283 * NOTYPE's can be combined with other types, only give an error if
284 * combining two differing types without NOTYPE.
285 */
286 if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE))
287 return;
288
289 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
290 demangle(sdp->sd_name));
291 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
292 sdp->sd_file->ifl_name,
293 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 0, &inv_buf1),
294 ifl->ifl_name,
295 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 0, &inv_buf2));
296 }
297
298 /*ARGSUSED4*/
299 static void
sym_mach_check(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)300 sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
301 int ndx, Word nshndx, sd_flag_t nsdflags)
302 {
303 /*
304 * Perform any machine specific type checking.
305 */
306 if (ld_targ.t_ms.ms_mach_sym_typecheck != NULL)
307 (void) (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym,
308 ifl, ofl);
309 }
310
311 /*
312 * Promote the symbols reference.
313 */
314 static void
315 /* ARGSUSED4 */
sym_promote(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)316 sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
317 int ndx, Word nshndx, sd_flag_t nsdflags)
318 {
319 Word shndx = nsym->st_shndx;
320
321 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
322
323 /*
324 * If the old symbol is from a shared object and the new symbol is a
325 * reference from a relocatable object, promote the old symbols
326 * reference.
327 */
328 if ((sdp->sd_ref == REF_DYN_SEEN) &&
329 (ifl->ifl_ehdr->e_type == ET_REL)) {
330 sdp->sd_ref = REF_DYN_NEED;
331
332 /*
333 * If this is an undefined symbol it must be a relocatable
334 * object overriding a shared object. In this case also
335 * override the reference name so that any undefined symbol
336 * diagnostics will refer to the relocatable object name.
337 */
338 if (shndx == SHN_UNDEF)
339 sdp->sd_aux->sa_rfile = ifl->ifl_name;
340
341 /*
342 * If this symbol is an undefined, or common, determine whether
343 * it is a global or weak reference (see build_osym(), where
344 * REF_DYN_NEED definitions are returned back to undefines).
345 */
346 if (((shndx == SHN_UNDEF) || ((nsdflags & FLG_SY_SPECSEC) &&
347 (shndx == SHN_COMMON))) &&
348 (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
349 sdp->sd_flags |= FLG_SY_GLOBREF;
350
351 }
352 }
353
354 /*
355 * Override a symbol.
356 */
357 static void
sym_override(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)358 sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
359 int ndx, Word nshndx, sd_flag_t nsdflags)
360 {
361 Sym *osym = sdp->sd_sym;
362 Word link;
363
364 /*
365 * In the case of a WEAK UNDEF symbol don't let a symbol from an
366 * unavailable object override the symbol definition. This is because
367 * this symbol *may* not be present in a future object and by promoting
368 * this symbol we are actually causing bindings (PLTS) to be formed
369 * to this symbol. Instead let the 'generic' weak binding take place.
370 */
371 if ((ELF_ST_BIND(osym->st_info) == STB_WEAK) &&
372 (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
373 ((ifl->ifl_flags & FLG_IF_NEEDED) == 0))
374 return;
375
376 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
377
378 /*
379 * This symbol has already been compared to an SO definition,
380 * as per the runtime behavior, ignore extra definitions.
381 */
382 if ((sdp->sd_flags & FLG_SY_SOFOUND) &&
383 (ifl->ifl_ehdr->e_type == ET_DYN))
384 return;
385
386 /*
387 * Mark the symbol as available and copy the new symbols contents.
388 */
389 sdp->sd_flags &= ~FLG_SY_NOTAVAIL;
390 *osym = *nsym;
391 sdp->sd_shndx = nshndx;
392 sdp->sd_flags &= ~FLG_SY_SPECSEC;
393 sdp->sd_flags |= (nsdflags & (FLG_SY_SPECSEC | FLG_SY_TENTSYM));
394
395 /*
396 * If the new symbol has PROTECTED visibility, mark it. If a PROTECTED
397 * symbol is copy relocated, a warning message will be printed. See
398 * reloc_exec().
399 */
400 if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED)
401 sdp->sd_flags |= FLG_SY_PROT;
402 else
403 sdp->sd_flags &= ~FLG_SY_PROT;
404
405 /*
406 * Establish the symbols reference. If the new symbol originates from a
407 * relocatable object then this reference becomes needed, otherwise
408 * the new symbol must be from a shared object. In this case only
409 * promote the symbol to needed if we presently have a reference from a
410 * relocatable object.
411 */
412 if (ifl->ifl_ehdr->e_type == ET_REL) {
413 sdp->sd_ref = REF_REL_NEED;
414
415 if (nsym->st_shndx == SHN_UNDEF) {
416 /*
417 * If this is an undefined symbol, then we can only be
418 * attempting to override an existing undefined symbol.
419 * The original symbol is either:
420 *
421 * - a mapfile definition
422 * - a previous relocatable object whose visibility
423 * or type should be overridden by this new symbol
424 * - a previous shared object
425 *
426 * If the original undefined symbol stems from a mapfile
427 * then don't alter the reference file name. Should we
428 * end up with some form of 'undefined' symbol error,
429 * the characteristics of that error are most likely to
430 * have originated from a mapfile.
431 *
432 * Otherwise, update the reference file name to indicate
433 * this symbol.
434 */
435 if ((sdp->sd_flags & FLG_SY_MAPREF) == 0)
436 sdp->sd_aux->sa_rfile = ifl->ifl_name;
437 } else {
438 /*
439 * Under -Bnodirect, all exported interfaces that have
440 * not explicitly been defined protected or directly
441 * bound to, are tagged to prevent direct binding.
442 */
443 if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) &&
444 ((sdp->sd_flags &
445 (FLG_SY_PROTECT | FLG_SY_DIR)) == 0))
446 sdp->sd_flags |= FLG_SY_NDIR;
447 }
448
449 /*
450 * If this symbol is an undefined, or common, determine whether
451 * it is a global or weak reference (see build_osym(), where
452 * REF_DYN_NEED definitions are returned back to undefines).
453 */
454 if (((nsym->st_shndx == SHN_UNDEF) ||
455 ((nsdflags & FLG_SY_SPECSEC) &&
456 (nsym->st_shndx == SHN_COMMON))) &&
457 (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
458 sdp->sd_flags |= FLG_SY_GLOBREF;
459 else
460 sdp->sd_flags &= ~FLG_SY_GLOBREF;
461 } else {
462 if (sdp->sd_ref == REF_REL_NEED)
463 sdp->sd_ref = REF_DYN_NEED;
464
465 /*
466 * Determine the symbols availability. A symbol is determined
467 * to be unavailable if it belongs to a version of a shared
468 * object that this user does not wish to use, or if it belongs
469 * to an implicit shared object.
470 */
471 if (ifl->ifl_vercnt) {
472 Ver_index *vip;
473 Half vndx = ifl->ifl_versym[ndx];
474
475 sdp->sd_aux->sa_dverndx = vndx;
476 vip = &ifl->ifl_verndx[vndx];
477 if (!(vip->vi_flags & FLG_VER_AVAIL)) {
478 sdp->sd_flags |= FLG_SY_NOTAVAIL;
479 /*
480 * If this is the first occurrence of an
481 * unavailable symbol record it for possible
482 * use in later error diagnostics
483 * (see sym_undef).
484 */
485 if (!(sdp->sd_aux->sa_vfile))
486 sdp->sd_aux->sa_vfile = ifl->ifl_name;
487 }
488 }
489 if (!(ifl->ifl_flags & FLG_IF_NEEDED))
490 sdp->sd_flags |= FLG_SY_NOTAVAIL;
491 }
492
493 /*
494 * Make sure any symbol association maintained by the original symbol
495 * is cleared and then update the symbols file reference.
496 */
497 if ((link = sdp->sd_aux->sa_linkndx) != 0) {
498 Sym_desc * _sdp;
499
500 _sdp = sdp->sd_file->ifl_oldndx[link];
501 _sdp->sd_aux->sa_linkndx = 0;
502 sdp->sd_aux->sa_linkndx = 0;
503 }
504 sdp->sd_file = ifl;
505
506 /*
507 * Update the input section descriptor to that of the new input file
508 */
509 if (((nsdflags & FLG_SY_SPECSEC) == 0) &&
510 (nsym->st_shndx != SHN_UNDEF) &&
511 ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == NULL))
512 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_NOSECDEF),
513 demangle(sdp->sd_name), ifl->ifl_name);
514 }
515
516 /*
517 * Resolve two undefines (only called for two relocatable objects).
518 */
519 static void
sym_twoundefs(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)520 sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
521 int ndx, Word nshndx, sd_flag_t nsdflags)
522 {
523 Sym *osym = sdp->sd_sym;
524 uchar_t obind = ELF_ST_BIND(osym->st_info);
525 uchar_t otype = ELF_ST_TYPE(osym->st_info);
526 uchar_t nbind = ELF_ST_BIND(nsym->st_info);
527 uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
528
529 /*
530 * If two relocatable objects define a weak and non-weak undefined
531 * reference, take the non-weak definition.
532 *
533 * -- or --
534 *
535 * If two relocatable objects define a NOTYPE & another, then
536 * take the other.
537 */
538 if (((obind == STB_WEAK) && (nbind != STB_WEAK)) ||
539 (otype == STT_NOTYPE) && (ntype != STT_NOTYPE)) {
540 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
541 return;
542 }
543 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
544 }
545
546 /*
547 * Resolve two real definitions.
548 */
549 static void
sym_tworeals(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)550 sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
551 int ndx, Word nshndx, sd_flag_t nsdflags)
552 {
553 Conv_inv_buf_t inv_buf1, inv_buf2;
554 Sym *osym = sdp->sd_sym;
555 uchar_t otype = ELF_ST_TYPE(osym->st_info);
556 uchar_t obind = ELF_ST_BIND(osym->st_info);
557 uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
558 uchar_t nbind = ELF_ST_BIND(nsym->st_info);
559 Half ofile = sdp->sd_file->ifl_ehdr->e_type;
560 Half nfile = ifl->ifl_ehdr->e_type;
561 int warn = 0;
562
563 /*
564 * If both definitions are from relocatable objects, and have non-weak
565 * binding then this is a fatal condition.
566 */
567 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) &&
568 (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) {
569 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
570 demangle(sdp->sd_name));
571 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
572 sdp->sd_file->ifl_name,
573 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
574 0, &inv_buf1), ifl->ifl_name,
575 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
576 0, &inv_buf2));
577 return;
578 }
579
580 /*
581 * Perform any machine specific type checking.
582 */
583 if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
584 (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
585 return;
586
587 /*
588 * Check the symbols type and size.
589 */
590 if (otype != ntype) {
591 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
592 demangle(sdp->sd_name));
593 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
594 sdp->sd_file->ifl_name,
595 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
596 0, &inv_buf1), ifl->ifl_name,
597 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
598 0, &inv_buf2));
599 warn++;
600 } else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) {
601 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
602 ld_eprintf(ofl, ERR_WARNING,
603 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
604 MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
605 EC_XWORD(osym->st_size), ifl->ifl_name,
606 EC_XWORD(nsym->st_size));
607 warn++;
608 }
609 }
610
611 /*
612 * Having provided the user with any necessary warnings, take the
613 * appropriate symbol:
614 *
615 * - if one symbol is from a shared object and the other is from a
616 * relocatable object, take the relocatable objects symbol (the
617 * run-time linker is always going to find the relocatable object
618 * symbol regardless of the binding), else
619 *
620 * - if both symbols are from relocatable objects and one symbol is
621 * weak take the non-weak symbol (two non-weak symbols would have
622 * generated the fatal error condition above unless -z muldefs is
623 * in effect), else
624 *
625 * - take the first symbol definition encountered.
626 */
627 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
628 if (warn)
629 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
630 sdp->sd_file->ifl_name);
631 return;
632 } else if ((nfile == ET_REL) && ((ofile == ET_DYN) ||
633 ((obind == STB_WEAK) && (nbind != STB_WEAK)))) {
634 if (warn)
635 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
636 ifl->ifl_name);
637 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
638 return;
639 } else {
640 if (warn)
641 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
642 sdp->sd_file->ifl_name);
643 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
644 return;
645 }
646 }
647
648 /*
649 * Resolve a real and tentative definition.
650 */
651 static void
sym_realtent(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)652 sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
653 int ndx, Word nshndx, sd_flag_t nsdflags)
654 {
655 Conv_inv_buf_t inv_buf1, inv_buf2;
656 Sym *osym = sdp->sd_sym;
657 uchar_t otype = ELF_ST_TYPE(osym->st_info);
658 uchar_t obind = ELF_ST_BIND(osym->st_info);
659 uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
660 uchar_t nbind = ELF_ST_BIND(nsym->st_info);
661 Boolean otent = FALSE, ntent = FALSE;
662 Half ofile = sdp->sd_file->ifl_ehdr->e_type;
663 Half nfile = ifl->ifl_ehdr->e_type;
664 int warn = 0;
665 uchar_t ovis = ELF_ST_VISIBILITY(osym->st_other);
666 uchar_t nvis = ELF_ST_VISIBILITY(nsym->st_other);
667
668 /*
669 * Special rules for functions.
670 *
671 * - If both definitions are from relocatable objects, have the same
672 * binding (ie. two weaks or two non-weaks), and the real
673 * definition is a function (the other must be tentative), treat
674 * this as a multiply defined symbol error, else
675 *
676 * - if the real symbol definition is a function within a shared
677 * library and the tentative symbol is a relocatable object, and
678 * the tentative is not weak and the function real, then retain the
679 * tentative definition.
680 */
681 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) &&
682 ((otype == STT_FUNC) || (ntype == STT_FUNC))) {
683 if (ofl->ofl_flags & FLG_OF_MULDEFS) {
684 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
685 demangle(sdp->sd_name));
686 sym_promote(sdp, nsym, ifl, ofl, ndx,
687 nshndx, nsdflags);
688 } else {
689 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
690 demangle(sdp->sd_name));
691 }
692 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
693 sdp->sd_file->ifl_name,
694 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
695 0, &inv_buf1), ifl->ifl_name,
696 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
697 0, &inv_buf2));
698 return;
699 } else if (ofile != nfile) {
700
701
702 if ((ofile == ET_DYN) && (otype == STT_FUNC)) {
703 if ((otype != STB_WEAK) && (ntype == STB_WEAK))
704 return;
705 else {
706 sym_override(sdp, nsym, ifl, ofl, ndx,
707 nshndx, nsdflags);
708 return;
709 }
710 }
711 if ((nfile == ET_DYN) && (ntype == STT_FUNC)) {
712 if ((ntype != STB_WEAK) && (otype == STB_WEAK)) {
713 sym_override(sdp, nsym, ifl, ofl, ndx,
714 nshndx, nsdflags);
715 return;
716 } else
717 return;
718 }
719 }
720
721 if (sdp->sd_flags & FLG_SY_TENTSYM)
722 otent = TRUE;
723 if (nsdflags & FLG_SY_TENTSYM)
724 ntent = TRUE;
725
726
727 /*
728 * Check the symbols type and size.
729 */
730 if (otype != ntype) {
731 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
732 demangle(sdp->sd_name));
733 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
734 sdp->sd_file->ifl_name,
735 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
736 0, &inv_buf1), ifl->ifl_name,
737 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
738 0, &inv_buf2));
739 warn++;
740 } else if (osym->st_size != nsym->st_size) {
741 /*
742 * If both definitions are from relocatable objects we have a
743 * potential fatal error condition. If the tentative is larger
744 * than the real definition treat this as a multiple definition.
745 * Note that if only one symbol is weak, the non-weak will be
746 * taken.
747 */
748 if (((ofile == ET_REL) && (nfile == ET_REL) &&
749 (obind == nbind)) &&
750 ((otent && (osym->st_size > nsym->st_size)) ||
751 (ntent && (osym->st_size < nsym->st_size)))) {
752 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_DIFFATTR),
753 demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
754 sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
755 ifl->ifl_name, EC_XWORD(nsym->st_size));
756 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_TENTERR));
757 } else {
758 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
759 ld_eprintf(ofl, ERR_WARNING,
760 MSG_INTL(MSG_SYM_DIFFATTR),
761 demangle(sdp->sd_name),
762 MSG_INTL(MSG_STR_SIZES),
763 sdp->sd_file->ifl_name,
764 EC_XWORD(osym->st_size),
765 ifl->ifl_name, EC_XWORD(nsym->st_size));
766 warn++;
767 }
768 }
769 }
770
771 /*
772 * Having provided the user with any necessary warnings, take the
773 * appropriate symbol:
774 *
775 * - if the original symbol is from relocatable file and it is
776 * a protected tentative symbol, take the original one.
777 *
778 * - if the original symbol is from shared object and the new
779 * symbol is a protected tentative symbol from a relocatable file,
780 * take the new one.
781 *
782 * - if the original symbol is tentative, and providing the original
783 * symbol isn't strong and the new symbol weak, take the real
784 * symbol, else
785 *
786 * - if the original symbol is weak and the new tentative symbol is
787 * strong take the new symbol.
788 *
789 * Refer to the System V ABI Page 4-27 for a description of the binding
790 * requirements of tentative and weak symbols.
791 */
792 if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) &&
793 (ovis == STV_PROTECTED)) {
794 return;
795 }
796
797 if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) &&
798 (nvis == STV_PROTECTED)) {
799 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
800 return;
801 }
802
803 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
804 if (warn)
805 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
806 sdp->sd_file->ifl_name);
807 return;
808 }
809
810 if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) ||
811 ((obind == STB_WEAK) && (nbind != STB_WEAK))) {
812 if (warn)
813 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
814 ifl->ifl_name);
815 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
816 return;
817 } else {
818 if (warn)
819 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
820 sdp->sd_file->ifl_name);
821 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
822 return;
823 }
824 }
825
826 /*
827 * Resolve two tentative symbols.
828 */
829 static void
sym_twotent(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)830 sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
831 int ndx, Word nshndx, sd_flag_t nsdflags)
832 {
833 Sym *osym = sdp->sd_sym;
834 uchar_t obind = ELF_ST_BIND(osym->st_info);
835 uchar_t nbind = ELF_ST_BIND(nsym->st_info);
836 Half ofile = sdp->sd_file->ifl_ehdr->e_type;
837 Half nfile = ifl->ifl_ehdr->e_type;
838 size_t size = 0;
839 Xword value = 0;
840
841 #if defined(_ELF64)
842 if (ld_targ.t_m.m_mach == EM_AMD64) {
843 /*
844 * If the original and new symbols are both COMMON, but of
845 * a different size model, take the small one.
846 */
847 if ((sdp->sd_sym->st_shndx == SHN_COMMON) &&
848 (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
849 /*
850 * Take the original symbol.
851 */
852 return;
853
854 } else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
855 (nsym->st_shndx == SHN_COMMON)) {
856 /*
857 * Take the new symbol.
858 */
859 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx,
860 nsdflags);
861 return;
862 }
863 }
864 #endif
865
866 /*
867 * Check the alignment of the symbols. This can only be tested for if
868 * the symbols are not real definitions to a SHT_NOBITS section (ie.
869 * they were originally tentative), as in this case the symbol would
870 * have a displacement value rather than an alignment. In other words
871 * we can only test this for two relocatable objects.
872 */
873 /* BEGIN CSTYLED */
874 if ((osym->st_value != nsym->st_value) &&
875 ((sdp->sd_flags & FLG_SY_SPECSEC) &&
876 (sdp->sd_sym->st_shndx == SHN_COMMON) &&
877 (nsdflags & FLG_SY_SPECSEC) &&
878 #if defined(_ELF64)
879 (nsym->st_shndx == SHN_COMMON)) ||
880 ((ld_targ.t_m.m_mach == EM_AMD64) &&
881 (sdp->sd_flags & FLG_SY_SPECSEC) &&
882 (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
883 (nsdflags & FLG_SY_SPECSEC) &&
884 (nsym->st_shndx == SHN_X86_64_LCOMMON))) {
885 #else
886 (nsym->st_shndx == SHN_COMMON))) {
887 #endif
888 /* END CSTYLED */
889
890 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
891 const char *file;
892 Xword salign;
893 Xword balign;
894 uint_t alignscompliment;
895
896 if (osym->st_value < nsym->st_value) {
897 salign = osym->st_value;
898 balign = nsym->st_value;
899 } else {
900 salign = nsym->st_value;
901 balign = osym->st_value;
902 }
903
904 /*
905 * If the smaller alignment fits smoothly into the
906 * larger alignment - we take it with no warning.
907 */
908 if (S_ALIGN(balign, salign) == balign)
909 alignscompliment = 1;
910 else
911 alignscompliment = 0;
912
913 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
914 ld_eprintf(ofl, ERR_WARNING,
915 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
916 MSG_INTL(MSG_STR_ALIGNMENTS),
917 sdp->sd_file->ifl_name, EC_XWORD(osym->st_value),
918 ifl->ifl_name, EC_XWORD(nsym->st_value));
919
920 /*
921 * Having provided the necessary warning indicate which
922 * relocatable object we are going to take.
923 *
924 * - if one symbol is weak and the other is non-weak
925 * take the non-weak symbol, else
926 *
927 * - take the largest alignment (as we still have to check
928 * the symbols size simply save the largest value for
929 * updating later).
930 */
931 if ((obind == STB_WEAK) && (nbind != STB_WEAK))
932 file = ifl->ifl_name;
933 else if (obind != nbind)
934 file = sdp->sd_file->ifl_name;
935 else {
936 emsg = MSG_INTL(MSG_SYM_LARGER);
937 value = balign;
938 }
939 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
940 ld_eprintf(ofl, ERR_NONE, emsg, file);
941 }
942
943 /*
944 * Check the size of the symbols.
945 */
946 if (osym->st_size != nsym->st_size) {
947 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
948 const char *file;
949
950 if (!(ofl->ofl_flags & FLG_OF_NOWARN))
951 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR),
952 demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
953 sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
954 ifl->ifl_name, EC_XWORD(nsym->st_size));
955
956
957 /*
958 * This symbol has already been compared to an SO definition,
959 * as per the runtime behavior, ignore extra definitions.
960 */
961 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
962 if (!(ofl->ofl_flags & FLG_OF_NOWARN))
963 ld_eprintf(ofl, ERR_NONE, emsg,
964 sdp->sd_file->ifl_name);
965 return;
966 }
967
968 /*
969 * Having provided the necessary warning indicate what course
970 * of action we are going to take.
971 *
972 * - if the file types differ, take the relocatable object
973 * and apply the largest symbol size, else
974 * - if one symbol is weak and the other is non-weak, take
975 * the non-weak symbol, else
976 * - simply take the largest symbol reference.
977 */
978 if (nfile != ofile) {
979 if (nfile == ET_REL) {
980 file = ifl->ifl_name;
981 if (osym->st_size > nsym->st_size) {
982 size = (size_t)osym->st_size;
983 emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
984 }
985 sym_override(sdp, nsym, ifl, ofl, ndx,
986 nshndx, nsdflags);
987 } else {
988 file = sdp->sd_file->ifl_name;
989 if (osym->st_size < nsym->st_size) {
990 size = (size_t)nsym->st_size;
991 emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
992 }
993 sym_promote(sdp, nsym, ifl, ofl, ndx,
994 nshndx, nsdflags);
995 }
996 } else if (obind != nbind) {
997 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) {
998 sym_override(sdp, nsym, ifl, ofl, ndx,
999 nshndx, nsdflags);
1000 file = ifl->ifl_name;
1001 } else
1002 file = sdp->sd_file->ifl_name;
1003 } else {
1004 if (osym->st_size < nsym->st_size) {
1005 sym_override(sdp, nsym, ifl, ofl, ndx,
1006 nshndx, nsdflags);
1007 file = ifl->ifl_name;
1008 } else
1009 file = sdp->sd_file->ifl_name;
1010 }
1011 if (!(ofl->ofl_flags & FLG_OF_NOWARN))
1012 ld_eprintf(ofl, ERR_NONE, emsg, file);
1013 if (size)
1014 sdp->sd_sym->st_size = (Xword)size;
1015 } else {
1016 /*
1017 * If the sizes are the same
1018 *
1019 * - if the file types differ, take the relocatable object,
1020 * else
1021 *
1022 * - if one symbol is weak and the other is non-weak, take
1023 * the non-weak symbol, else
1024 *
1025 * - take the first reference.
1026 */
1027 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN))
1028 return;
1029 else if (((ofile != nfile) && (nfile == ET_REL)) ||
1030 (((obind == STB_WEAK) && (nbind != STB_WEAK)) &&
1031 (!((ofile != nfile) && (ofile == ET_REL)))))
1032 sym_override(sdp, nsym, ifl, ofl, ndx,
1033 nshndx, nsdflags);
1034 else
1035 sym_promote(sdp, nsym, ifl, ofl, ndx,
1036 nshndx, nsdflags);
1037 }
1038
1039 /*
1040 * Enforce the largest alignment if necessary.
1041 */
1042 if (value)
1043 sdp->sd_sym->st_value = value;
1044 }
1045
1046 /*
1047 * Symbol resolution state table. `Action' describes the required
1048 * procedure to be called (if any).
1049 */
1050 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *,
1051 Sym *, Ifl_desc *, Ofl_desc *, int, Word, sd_flag_t) = {
1052
1053 /* defined undef tent */
1054 /* ET_REL ET_REL ET_REL */
1055
1056 /* 0 defined REF_DYN_SEEN */ sym_tworeals, sym_promote, sym_realtent,
1057 /* 1 undef REF_DYN_SEEN */ sym_override, sym_override, sym_override,
1058 /* 2 tent REF_DYN_SEEN */ sym_realtent, sym_promote, sym_twotent,
1059 /* 3 defined REF_DYN_NEED */ sym_tworeals, sym_typecheck, sym_realtent,
1060 /* 4 undef REF_DYN_NEED */ sym_override, sym_override, sym_override,
1061 /* 5 tent REF_DYN_NEED */ sym_realtent, sym_typecheck, sym_twotent,
1062 /* 6 defined REF_REL_NEED */ sym_tworeals, sym_typecheck, sym_realtent,
1063 /* 7 undef REF_REL_NEED */ sym_override, sym_twoundefs, sym_override,
1064 /* 8 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent,
1065
1066 /* defined undef tent */
1067 /* ET_DYN ET_DYN ET_DYN */
1068
1069 /* 9 defined REF_DYN_SEEN */ sym_tworeals, sym_null, sym_realtent,
1070 /* 10 undef REF_DYN_SEEN */ sym_override, sym_mach_check, sym_override,
1071 /* 11 tent REF_DYN_SEEN */ sym_realtent, sym_null, sym_twotent,
1072 /* 12 defined REF_DYN_NEED */ sym_tworeals, sym_null, sym_realtent,
1073 /* 13 undef REF_DYN_NEED */ sym_override, sym_null, sym_override,
1074 /* 14 tent REF_DYN_NEED */ sym_realtent, sym_null, sym_twotent,
1075 /* 15 defined REF_REL_NEED */ sym_tworeals, sym_null, sym_realtent,
1076 /* 16 undef REF_REL_NEED */ sym_override, sym_mach_check, sym_override,
1077 /* 17 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent
1078
1079 };
1080
1081 uintptr_t
1082 ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx,
1083 Word nshndx, sd_flag_t nsdflags)
1084 {
1085 int row, column; /* State table coordinates */
1086 Sym *osym = sdp->sd_sym;
1087 sd_flag_t osdflags = sdp->sd_flags;
1088 Is_desc *isp;
1089 Half vis = 0, nfile = ifl->ifl_ehdr->e_type;
1090 Half oref = sdp->sd_ref;
1091
1092 /*
1093 * Determine the original symbols definition (defines row in Action[]).
1094 */
1095 if (osdflags & FLG_SY_TENTSYM)
1096 row = SYM_TENTATIVE;
1097 else if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
1098 (sdp->sd_sym->st_shndx == SHN_SUNW_IGNORE))
1099 row = SYM_UNDEFINED;
1100 else
1101 row = SYM_DEFINED;
1102
1103 /*
1104 * If the input file is an implicit shared object then we don't need
1105 * to bind to any symbols within it other than to verify that any
1106 * undefined references will be closed (implicit shared objects are only
1107 * processed when no undefined symbols are required as a result of the
1108 * link-edit (see process_dynamic())).
1109 */
1110 if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) &&
1111 (row != SYM_UNDEFINED))
1112 return (1);
1113
1114 /*
1115 * Finish computing the Action[] row by applying the symbols reference
1116 * together with the input files type.
1117 */
1118 row = row + (REF_NUM * sdp->sd_ref);
1119 if (nfile == ET_DYN)
1120 row += (REF_NUM * SYM_NUM);
1121
1122 /*
1123 * If either the original or new symbol originates from a relocatable
1124 * object, determine the appropriate visibility for the resolved symbol.
1125 */
1126 if ((oref == REF_REL_NEED) || (nfile == ET_REL))
1127 vis = sym_visibility(sdp, nsym, ifl, ofl);
1128
1129 /*
1130 * Determine the new symbols definition (defines column in Action[]).
1131 */
1132 if ((nsdflags & FLG_SY_SPECSEC) &&
1133 (nsym->st_shndx == SHN_COMMON)) {
1134 column = SYM_TENTATIVE;
1135 nsdflags |= FLG_SY_TENTSYM;
1136 #if defined(_ELF64)
1137 } else if ((ld_targ.t_m.m_mach == EM_AMD64) &&
1138 (nsdflags & FLG_SY_SPECSEC) &&
1139 (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
1140 column = SYM_TENTATIVE;
1141 nsdflags |= FLG_SY_TENTSYM;
1142 #endif
1143 } else if ((nsym->st_shndx == SHN_UNDEF) ||
1144 (nsym->st_shndx == SHN_SUNW_IGNORE)) {
1145 column = SYM_UNDEFINED;
1146 nshndx = SHN_UNDEF;
1147 } else {
1148 column = SYM_DEFINED;
1149 /*
1150 * If the new symbol is from a shared library and it is
1151 * associated with a SHT_NOBITS section then this symbol
1152 * originated from a tentative symbol.
1153 */
1154 if (((nsdflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) {
1155 isp = ifl->ifl_isdesc[nshndx];
1156 if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) {
1157 column = SYM_TENTATIVE;
1158 nsdflags |= FLG_SY_TENTSYM;
1159 }
1160 }
1161 }
1162
1163 DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column,
1164 osym, nsym, sdp, ifl));
1165
1166 /*
1167 * Record the input filename on the defined files list for possible
1168 * later diagnostics. The `sa_dfiles' list is used to maintain the list
1169 * of shared objects that define the same symbol. This list is only
1170 * generated when the -m option is in effect and is used to list
1171 * multiple (interposed) definitions of a symbol (refer to ldmap_out()).
1172 */
1173 if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nsym->st_shndx != SHN_UNDEF) &&
1174 ((nsdflags & FLG_SY_SPECSEC) == 0))
1175 if (aplist_append(&sdp->sd_aux->sa_dfiles, ifl->ifl_name,
1176 AL_CNT_SDP_DFILES) == NULL)
1177 return (S_ERROR);
1178
1179 /*
1180 * Perform the required resolution.
1181 */
1182 Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
1183
1184 /*
1185 * Apply any visibility requirements. If a SINGLETON has been
1186 * established, make sure no symbol reduction indicators remain
1187 * associated with the symbol, and indicate that the symbol can not
1188 * be directly bound to.
1189 */
1190 if ((oref == REF_REL_NEED) || (nfile == ET_REL)) {
1191 if ((vis == STV_EXPORTED) || (vis == STV_SINGLETON)) {
1192 sdp->sd_flags &= ~MSK_SY_LOCAL;
1193
1194 if (vis == STV_EXPORTED)
1195 sdp->sd_flags |= FLG_SY_EXPORT;
1196 else {
1197 sdp->sd_flags |= (FLG_SY_NDIR | FLG_SY_SINGLE);
1198
1199 if (sdp->sd_ref == REF_REL_NEED) {
1200 ofl->ofl_flags1 |=
1201 (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
1202 }
1203 }
1204 } else if (vis == STV_PROTECTED) {
1205 sdp->sd_flags |= FLG_SY_PROTECT;
1206 } else if ((vis == STV_INTERNAL) || (vis == STV_HIDDEN)) {
1207 sdp->sd_flags |= FLG_SY_HIDDEN;
1208 } else if (vis == STV_ELIMINATE) {
1209 sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
1210 }
1211
1212 sdp->sd_sym->st_other =
1213 (sdp->sd_sym->st_other & ~MSK_SYM_VISIBILITY) | vis;
1214 }
1215
1216 /*
1217 * If the symbol has been resolved to the new input file, and this is
1218 * a versioned relocatable object, then the version information of the
1219 * new symbol must be promoted to the versioning of the output file.
1220 */
1221 if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) &&
1222 (nsym->st_shndx != SHN_UNDEF))
1223 ld_vers_promote(sdp, ndx, ifl, ofl);
1224
1225 /*
1226 * Determine whether a mapfile reference has been satisfied. Mapfile
1227 * symbol references augment symbols that should be contributed from
1228 * the relocatable objects used to build the output image. If a
1229 * relocatable object doesn't provide one of the mapfile symbol
1230 * references then somethings amiss, and will be flagged during symbol
1231 * validation.
1232 */
1233 if ((nfile == ET_REL) && ((sdp->sd_flags &
1234 (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) {
1235 /*
1236 * Extern and parent references are satisfied by references from
1237 * a relocatable object. Note that we let *any* symbol type
1238 * satisfy this reference, to be as flexible as possible with
1239 * user written mapfiles. It could be questionable, for
1240 * example, if what a user expects to be an extern reference is
1241 * actually found to be a definition in a relocatable object.
1242 *
1243 * Any other mapfile reference (typically for versioning
1244 * information) simply augments a relocatables definition.
1245 */
1246 if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) ||
1247 ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
1248 (sdp->sd_ref == REF_REL_NEED)))
1249 sdp->sd_flags |= FLG_SY_MAPUSED;
1250 }
1251
1252 /*
1253 * Make sure any special symbol requirements are carried over.
1254 */
1255 if ((osdflags & FLG_SY_CAP) || (nsdflags & FLG_SY_CAP))
1256 sdp->sd_flags |= FLG_SY_CAP;
1257
1258 DBG_CALL(Dbg_syms_resolved(ofl, sdp));
1259
1260 return (1);
1261 }
1262