8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / cmd / sgs / libld / common / resolve.c
blob6303651249cadc810ff2354debd585870fd99ea9
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
26 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Symbol table resolution
32 #define ELF_TARGET_AMD64
34 #include <stdio.h>
35 #include <debug.h>
36 #include "msg.h"
37 #include "_libld.h"
41 * Categorize the symbol types that are applicable to the resolution process.
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;
51 * Do nothing.
53 /* ARGSUSED0 */
54 static void
55 sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
56 int ndx, Word nshndx, sd_flag_t nsdflags)
60 static void
61 sym_visibility_diag(Error err, Sym_desc *sdp, Sym *osym, Sym *nsym,
62 Ifl_desc *ifl, Ofl_desc *ofl)
64 Conv_inv_buf_t inv_obuf, inv_nbuf;
66 /* Warnings are only issued when -z verbose is specified */
67 if (!(ofl->ofl_flags & FLG_OF_VERBOSE) && (err != ERR_FATAL))
68 return;
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));
75 if (err != ERR_FATAL)
76 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
77 ifl->ifl_name);
81 * STV_VISIBILITY rules for STV_DEFAULT/INTERNAL/HIDDEN/PROTECTED say that the
82 * most restrictive visibility value should be taken. The precedence is:
84 * (most restrictive) INTERNAL -> HIDDEN -> PROTECTED -> DEFAULT (least)
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.
89 * Resolution of different visibilities between two relocatable objects can
90 * take the following actions:
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.
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:
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.
116 * Note, an eliminate symbol (STV_ELIMINATE) is treated as hidden (STV_HIDDEN)
117 * for processing through this state table.
119 static Half
120 sym_visibility(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl)
122 Sym *osym = sdp->sd_sym;
123 uchar_t wovis, ovis;
124 uchar_t wnvis, nvis;
126 wovis = ovis = ELF_ST_VISIBILITY(osym->st_other);
127 wnvis = nvis = ELF_ST_VISIBILITY(nsym->st_other);
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.
134 if (wovis == STV_ELIMINATE)
135 wovis = STV_HIDDEN;
136 if (wnvis == STV_ELIMINATE)
137 wnvis = STV_HIDDEN;
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.
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);
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);
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.
171 if (wovis == wnvis) {
172 if (ovis == nvis)
173 return (nvis);
174 else
175 return (STV_ELIMINATE);
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.
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);
195 return (nvis);
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);
207 return (nvis);
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);
221 return (nvis);
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.
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);
238 return (STV_INTERNAL);
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);
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.
252 if ((ovis == STV_ELIMINATE) || (nvis == STV_ELIMINATE))
253 return (STV_ELIMINATE);
254 else
255 return (STV_HIDDEN);
257 } else if ((wnvis == STV_PROTECTED) || (wovis == STV_PROTECTED))
258 return (STV_PROTECTED);
260 return (STV_DEFAULT);
264 * Check if two symbols types are compatible
266 /*ARGSUSED4*/
267 static void
268 sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
269 int ndx, Word nshndx, sd_flag_t nsdflags)
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;
276 * Perform any machine specific type checking.
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;
283 * NOTYPE's can be combined with other types, only give an error if
284 * combining two differing types without NOTYPE.
286 if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE))
287 return;
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));
298 /*ARGSUSED4*/
299 static void
300 sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
301 int ndx, Word nshndx, sd_flag_t nsdflags)
304 * Perform any machine specific type checking.
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);
312 * Promote the symbols reference.
314 static void
315 /* ARGSUSED4 */
316 sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
317 int ndx, Word nshndx, sd_flag_t nsdflags)
319 Word shndx = nsym->st_shndx;
321 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
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.
328 if ((sdp->sd_ref == REF_DYN_SEEN) &&
329 (ifl->ifl_ehdr->e_type == ET_REL)) {
330 sdp->sd_ref = REF_DYN_NEED;
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.
338 if (shndx == SHN_UNDEF)
339 sdp->sd_aux->sa_rfile = ifl->ifl_name;
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).
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;
355 * Override a symbol.
357 static void
358 sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
359 int ndx, Word nshndx, sd_flag_t nsdflags)
361 Sym *osym = sdp->sd_sym;
362 Word link;
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.
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;
376 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
379 * This symbol has already been compared to an SO definition,
380 * as per the runtime behavior, ignore extra definitions.
382 if ((sdp->sd_flags & FLG_SY_SOFOUND) &&
383 (ifl->ifl_ehdr->e_type == ET_DYN))
384 return;
387 * Mark the symbol as available and copy the new symbols contents.
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));
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().
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;
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.
412 if (ifl->ifl_ehdr->e_type == ET_REL) {
413 sdp->sd_ref = REF_REL_NEED;
415 if (nsym->st_shndx == SHN_UNDEF) {
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:
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
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.
432 * Otherwise, update the reference file name to indicate
433 * this symbol.
435 if ((sdp->sd_flags & FLG_SY_MAPREF) == 0)
436 sdp->sd_aux->sa_rfile = ifl->ifl_name;
437 } else {
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.
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;
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).
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;
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.
471 if (ifl->ifl_vercnt) {
472 Ver_index *vip;
473 Half vndx = ifl->ifl_versym[ndx];
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;
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).
485 if (!(sdp->sd_aux->sa_vfile))
486 sdp->sd_aux->sa_vfile = ifl->ifl_name;
489 if (!(ifl->ifl_flags & FLG_IF_NEEDED))
490 sdp->sd_flags |= FLG_SY_NOTAVAIL;
494 * Make sure any symbol association maintained by the original symbol
495 * is cleared and then update the symbols file reference.
497 if ((link = sdp->sd_aux->sa_linkndx) != 0) {
498 Sym_desc * _sdp;
500 _sdp = sdp->sd_file->ifl_oldndx[link];
501 _sdp->sd_aux->sa_linkndx = 0;
502 sdp->sd_aux->sa_linkndx = 0;
504 sdp->sd_file = ifl;
507 * Update the input section descriptor to that of the new input file
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);
517 * Resolve two undefines (only called for two relocatable objects).
519 static void
520 sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
521 int ndx, Word nshndx, sd_flag_t nsdflags)
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);
530 * If two relocatable objects define a weak and non-weak undefined
531 * reference, take the non-weak definition.
533 * -- or --
535 * If two relocatable objects define a NOTYPE & another, then
536 * take the other.
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;
543 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
547 * Resolve two real definitions.
549 static void
550 sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
551 int ndx, Word nshndx, sd_flag_t nsdflags)
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;
564 * If both definitions are from relocatable objects, and have non-weak
565 * binding then this is a fatal condition.
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;
581 * Perform any machine specific type checking.
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;
588 * Check the symbols type and size.
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++;
612 * Having provided the user with any necessary warnings, take the
613 * appropriate symbol:
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
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
625 * - take the first symbol definition encountered.
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;
649 * Resolve a real and tentative definition.
651 static void
652 sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
653 int ndx, Word nshndx, sd_flag_t nsdflags)
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);
669 * Special rules for functions.
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
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.
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));
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) {
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;
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;
721 if (sdp->sd_flags & FLG_SY_TENTSYM)
722 otent = TRUE;
723 if (nsdflags & FLG_SY_TENTSYM)
724 ntent = TRUE;
728 * Check the symbols type and size.
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) {
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.
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++;
772 * Having provided the user with any necessary warnings, take the
773 * appropriate symbol:
775 * - if the original symbol is from relocatable file and it is
776 * a protected tentative symbol, take the original one.
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.
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
786 * - if the original symbol is weak and the new tentative symbol is
787 * strong take the new symbol.
789 * Refer to the System V ABI Page 4-27 for a description of the binding
790 * requirements of tentative and weak symbols.
792 if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) &&
793 (ovis == STV_PROTECTED)) {
794 return;
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;
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;
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;
827 * Resolve two tentative symbols.
829 static void
830 sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
831 int ndx, Word nshndx, sd_flag_t nsdflags)
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;
841 #if defined(_ELF64)
842 if (ld_targ.t_m.m_mach == EM_AMD64) {
844 * If the original and new symbols are both COMMON, but of
845 * a different size model, take the small one.
847 if ((sdp->sd_sym->st_shndx == SHN_COMMON) &&
848 (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
850 * Take the original symbol.
852 return;
854 } else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
855 (nsym->st_shndx == SHN_COMMON)) {
857 * Take the new symbol.
859 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx,
860 nsdflags);
861 return;
864 #endif
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.
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 */
890 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
891 const char *file;
892 Xword salign;
893 Xword balign;
894 uint_t alignscompliment;
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;
905 * If the smaller alignment fits smoothly into the
906 * larger alignment - we take it with no warning.
908 if (S_ALIGN(balign, salign) == balign)
909 alignscompliment = 1;
910 else
911 alignscompliment = 0;
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));
921 * Having provided the necessary warning indicate which
922 * relocatable object we are going to take.
924 * - if one symbol is weak and the other is non-weak
925 * take the non-weak symbol, else
927 * - take the largest alignment (as we still have to check
928 * the symbols size simply save the largest value for
929 * updating later).
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;
939 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
940 ld_eprintf(ofl, ERR_NONE, emsg, file);
944 * Check the size of the symbols.
946 if (osym->st_size != nsym->st_size) {
947 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
948 const char *file;
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));
958 * This symbol has already been compared to an SO definition,
959 * as per the runtime behavior, ignore extra definitions.
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;
969 * Having provided the necessary warning indicate what course
970 * of action we are going to take.
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.
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);
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);
993 sym_promote(sdp, nsym, ifl, ofl, ndx,
994 nshndx, nsdflags);
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;
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 {
1017 * If the sizes are the same
1019 * - if the file types differ, take the relocatable object,
1020 * else
1022 * - if one symbol is weak and the other is non-weak, take
1023 * the non-weak symbol, else
1025 * - take the first reference.
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);
1040 * Enforce the largest alignment if necessary.
1042 if (value)
1043 sdp->sd_sym->st_value = value;
1047 * Symbol resolution state table. `Action' describes the required
1048 * procedure to be called (if any).
1050 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *,
1051 Sym *, Ifl_desc *, Ofl_desc *, int, Word, sd_flag_t) = {
1053 /* defined undef tent */
1054 /* ET_REL ET_REL ET_REL */
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,
1066 /* defined undef tent */
1067 /* ET_DYN ET_DYN ET_DYN */
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
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)
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;
1093 * Determine the original symbols definition (defines row in Action[]).
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;
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())).
1110 if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) &&
1111 (row != SYM_UNDEFINED))
1112 return (1);
1115 * Finish computing the Action[] row by applying the symbols reference
1116 * together with the input files type.
1118 row = row + (REF_NUM * sdp->sd_ref);
1119 if (nfile == ET_DYN)
1120 row += (REF_NUM * SYM_NUM);
1123 * If either the original or new symbol originates from a relocatable
1124 * object, determine the appropriate visibility for the resolved symbol.
1126 if ((oref == REF_REL_NEED) || (nfile == ET_REL))
1127 vis = sym_visibility(sdp, nsym, ifl, ofl);
1130 * Determine the new symbols definition (defines column in Action[]).
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;
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.
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;
1163 DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column,
1164 osym, nsym, sdp, ifl));
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()).
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);
1180 * Perform the required resolution.
1182 Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
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.
1190 if ((oref == REF_REL_NEED) || (nfile == ET_REL)) {
1191 if ((vis == STV_EXPORTED) || (vis == STV_SINGLETON)) {
1192 sdp->sd_flags &= ~MSK_SY_LOCAL;
1194 if (vis == STV_EXPORTED)
1195 sdp->sd_flags |= FLG_SY_EXPORT;
1196 else {
1197 sdp->sd_flags |= (FLG_SY_NDIR | FLG_SY_SINGLE);
1199 if (sdp->sd_ref == REF_REL_NEED) {
1200 ofl->ofl_flags1 |=
1201 (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
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);
1212 sdp->sd_sym->st_other =
1213 (sdp->sd_sym->st_other & ~MSK_SYM_VISIBILITY) | vis;
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.
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);
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.
1233 if ((nfile == ET_REL) && ((sdp->sd_flags &
1234 (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) {
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.
1243 * Any other mapfile reference (typically for versioning
1244 * information) simply augments a relocatables definition.
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;
1253 * Make sure any special symbol requirements are carried over.
1255 if ((osdflags & FLG_SY_CAP) || (nsdflags & FLG_SY_CAP))
1256 sdp->sd_flags |= FLG_SY_CAP;
1258 DBG_CALL(Dbg_syms_resolved(ofl, sdp));
1260 return (1);