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 2010 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 /* 31 * Symbol table resolution 32 */ 33 #define ELF_TARGET_AMD64 34 35 #include <stdio.h> 36 #include <debug.h> 37 #include "msg.h" 38 #include "_libld.h" 39 40 41 /* 42 * Categorize the symbol types that are applicable to the resolution process. 43 */ 44 typedef enum { 45 SYM_DEFINED, /* Defined symbol (SHN_ABS or shndx != 0) */ 46 SYM_UNDEFINED, /* Undefined symbol (SHN_UNDEF) */ 47 SYM_TENTATIVE, /* Tentative symbol (SHN_COMMON) */ 48 SYM_NUM /* the number of symbol types */ 49 } Symtype; 50 51 /* 52 * Do nothing. 53 */ 54 /* ARGSUSED0 */ 55 static void 56 sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 57 int ndx, Word nshndx, sd_flag_t nsdflags) 58 { 59 } 60 61 static void 62 sym_visibility_diag(Error err, Sym_desc *sdp, Sym *osym, Sym *nsym, 63 Ifl_desc *ifl, Ofl_desc *ofl) 64 { 65 Conv_inv_buf_t inv_obuf, inv_nbuf; 66 67 eprintf(ofl->ofl_lml, err, MSG_INTL(MSG_SYM_CONFVIS), 68 demangle(sdp->sd_name)); 69 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES), 70 sdp->sd_file->ifl_name, conv_sym_other(osym->st_other, &inv_obuf), 71 ifl->ifl_name, conv_sym_other(nsym->st_other, &inv_nbuf)); 72 73 if (err == ERR_FATAL) 74 ofl->ofl_flags |= FLG_OF_FATAL; 75 else 76 eprintf(ofl->ofl_lml, 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 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 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 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 290 demangle(sdp->sd_name)); 291 eprintf(ofl->ofl_lml, 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 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 */ 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 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 if ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == 0) { 512 eprintf(ofl->ofl_lml, ERR_FATAL, 513 MSG_INTL(MSG_SYM_NOSECDEF), demangle(sdp->sd_name), 514 ifl->ifl_name); 515 ofl->ofl_flags |= FLG_OF_FATAL; 516 } 517 } 518 } 519 520 /* 521 * Resolve two undefines (only called for two relocatable objects). 522 */ 523 static void 524 sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 525 int ndx, Word nshndx, sd_flag_t nsdflags) 526 { 527 Sym *osym = sdp->sd_sym; 528 uchar_t obind = ELF_ST_BIND(osym->st_info); 529 uchar_t otype = ELF_ST_TYPE(osym->st_info); 530 uchar_t nbind = ELF_ST_BIND(nsym->st_info); 531 uchar_t ntype = ELF_ST_TYPE(nsym->st_info); 532 533 /* 534 * If two relocatable objects define a weak and non-weak undefined 535 * reference, take the non-weak definition. 536 * 537 * -- or -- 538 * 539 * If two relocatable objects define a NOTYPE & another, then 540 * take the other. 541 */ 542 if (((obind == STB_WEAK) && (nbind != STB_WEAK)) || 543 (otype == STT_NOTYPE) && (ntype != STT_NOTYPE)) { 544 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 545 return; 546 } 547 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 548 } 549 550 /* 551 * Resolve two real definitions. 552 */ 553 static void 554 sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 555 int ndx, Word nshndx, sd_flag_t nsdflags) 556 { 557 Conv_inv_buf_t inv_buf1, inv_buf2; 558 Sym *osym = sdp->sd_sym; 559 uchar_t otype = ELF_ST_TYPE(osym->st_info); 560 uchar_t obind = ELF_ST_BIND(osym->st_info); 561 uchar_t ntype = ELF_ST_TYPE(nsym->st_info); 562 uchar_t nbind = ELF_ST_BIND(nsym->st_info); 563 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 564 Half nfile = ifl->ifl_ehdr->e_type; 565 int warn = 0; 566 567 /* 568 * If both definitions are from relocatable objects, and have non-weak 569 * binding then this is a fatal condition. 570 */ 571 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) && 572 (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) { 573 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF), 574 demangle(sdp->sd_name)); 575 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 576 sdp->sd_file->ifl_name, 577 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 578 0, &inv_buf1), ifl->ifl_name, 579 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 580 0, &inv_buf2)); 581 ofl->ofl_flags |= FLG_OF_FATAL; 582 return; 583 } 584 585 /* 586 * Perform any machine specific type checking. 587 */ 588 if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) && 589 (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl)) 590 return; 591 592 /* 593 * Check the symbols type and size. 594 */ 595 if (otype != ntype) { 596 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 597 demangle(sdp->sd_name)); 598 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 599 sdp->sd_file->ifl_name, 600 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 601 0, &inv_buf1), ifl->ifl_name, 602 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 603 0, &inv_buf2)); 604 warn++; 605 } else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) { 606 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 607 eprintf(ofl->ofl_lml, ERR_WARNING, 608 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 609 MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name, 610 EC_XWORD(osym->st_size), ifl->ifl_name, 611 EC_XWORD(nsym->st_size)); 612 warn++; 613 } 614 } 615 616 /* 617 * Having provided the user with any necessary warnings, take the 618 * appropriate symbol: 619 * 620 * - if one symbol is from a shared object and the other is from a 621 * relocatable object, take the relocatable objects symbol (the 622 * run-time linker is always going to find the relocatable object 623 * symbol regardless of the binding), else 624 * 625 * - if both symbols are from relocatable objects and one symbol is 626 * weak take the non-weak symbol (two non-weak symbols would have 627 * generated the fatal error condition above unless -z muldefs is 628 * in effect), else 629 * 630 * - take the first symbol definition encountered. 631 */ 632 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 633 if (warn) 634 eprintf(ofl->ofl_lml, ERR_NONE, 635 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 636 return; 637 } else if ((nfile == ET_REL) && ((ofile == ET_DYN) || 638 ((obind == STB_WEAK) && (nbind != STB_WEAK)))) { 639 if (warn) 640 eprintf(ofl->ofl_lml, ERR_NONE, 641 MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name); 642 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 643 return; 644 } else { 645 if (warn) 646 eprintf(ofl->ofl_lml, ERR_NONE, 647 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 648 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 649 return; 650 } 651 } 652 653 /* 654 * Resolve a real and tentative definition. 655 */ 656 static void 657 sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 658 int ndx, Word nshndx, sd_flag_t nsdflags) 659 { 660 Conv_inv_buf_t inv_buf1, inv_buf2; 661 Sym *osym = sdp->sd_sym; 662 uchar_t otype = ELF_ST_TYPE(osym->st_info); 663 uchar_t obind = ELF_ST_BIND(osym->st_info); 664 uchar_t ntype = ELF_ST_TYPE(nsym->st_info); 665 uchar_t nbind = ELF_ST_BIND(nsym->st_info); 666 Boolean otent = FALSE, ntent = FALSE; 667 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 668 Half nfile = ifl->ifl_ehdr->e_type; 669 int warn = 0; 670 uchar_t ovis = ELF_ST_VISIBILITY(osym->st_other); 671 uchar_t nvis = ELF_ST_VISIBILITY(nsym->st_other); 672 673 /* 674 * Special rules for functions. 675 * 676 * - If both definitions are from relocatable objects, have the same 677 * binding (ie. two weaks or two non-weaks), and the real 678 * definition is a function (the other must be tentative), treat 679 * this as a multiply defined symbol error, else 680 * 681 * - if the real symbol definition is a function within a shared 682 * library and the tentative symbol is a relocatable object, and 683 * the tentative is not weak and the function real, then retain the 684 * tentative definition. 685 */ 686 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) && 687 ((otype == STT_FUNC) || (ntype == STT_FUNC))) { 688 if (ofl->ofl_flags & FLG_OF_MULDEFS) { 689 eprintf(ofl->ofl_lml, ERR_WARNING, 690 MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name)); 691 sym_promote(sdp, nsym, ifl, ofl, ndx, 692 nshndx, nsdflags); 693 } else { 694 eprintf(ofl->ofl_lml, ERR_FATAL, 695 MSG_INTL(MSG_SYM_MULDEF), demangle(sdp->sd_name)); 696 ofl->ofl_flags |= FLG_OF_FATAL; 697 } 698 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 699 sdp->sd_file->ifl_name, 700 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 701 0, &inv_buf1), ifl->ifl_name, 702 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 703 0, &inv_buf2)); 704 return; 705 } else if (ofile != nfile) { 706 707 708 if ((ofile == ET_DYN) && (otype == STT_FUNC)) { 709 if ((otype != STB_WEAK) && (ntype == STB_WEAK)) 710 return; 711 else { 712 sym_override(sdp, nsym, ifl, ofl, ndx, 713 nshndx, nsdflags); 714 return; 715 } 716 } 717 if ((nfile == ET_DYN) && (ntype == STT_FUNC)) { 718 if ((ntype != STB_WEAK) && (otype == STB_WEAK)) { 719 sym_override(sdp, nsym, ifl, ofl, ndx, 720 nshndx, nsdflags); 721 return; 722 } else 723 return; 724 } 725 } 726 727 if (sdp->sd_flags & FLG_SY_TENTSYM) 728 otent = TRUE; 729 if (nsdflags & FLG_SY_TENTSYM) 730 ntent = TRUE; 731 732 733 /* 734 * Check the symbols type and size. 735 */ 736 if (otype != ntype) { 737 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 738 demangle(sdp->sd_name)); 739 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 740 sdp->sd_file->ifl_name, 741 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 742 0, &inv_buf1), ifl->ifl_name, 743 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 744 0, &inv_buf2)); 745 warn++; 746 } else if (osym->st_size != nsym->st_size) { 747 /* 748 * If both definitions are from relocatable objects we have a 749 * potential fatal error condition. If the tentative is larger 750 * than the real definition treat this as a multiple definition. 751 * Note that if only one symbol is weak, the non-weak will be 752 * taken. 753 */ 754 if (((ofile == ET_REL) && (nfile == ET_REL) && 755 (obind == nbind)) && 756 ((otent && (osym->st_size > nsym->st_size)) || 757 (ntent && (osym->st_size < nsym->st_size)))) { 758 eprintf(ofl->ofl_lml, ERR_FATAL, 759 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 760 MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name, 761 EC_XWORD(osym->st_size), ifl->ifl_name, 762 EC_XWORD(nsym->st_size)); 763 eprintf(ofl->ofl_lml, ERR_NONE, 764 MSG_INTL(MSG_SYM_TENTERR)); 765 ofl->ofl_flags |= FLG_OF_FATAL; 766 } else { 767 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 768 eprintf(ofl->ofl_lml, ERR_WARNING, 769 MSG_INTL(MSG_SYM_DIFFATTR), 770 demangle(sdp->sd_name), 771 MSG_INTL(MSG_STR_SIZES), 772 sdp->sd_file->ifl_name, 773 EC_XWORD(osym->st_size), 774 ifl->ifl_name, EC_XWORD(nsym->st_size)); 775 warn++; 776 } 777 } 778 } 779 780 /* 781 * Having provided the user with any necessary warnings, take the 782 * appropriate symbol: 783 * 784 * - if the original symbol is from relocatable file and it is 785 * a protected tentative symbol, take the original one. 786 * 787 * - if the original symbol is from shared object and the new 788 * symbol is a protected tentative symbol from a relocatable file, 789 * take the new one. 790 * 791 * - if the original symbol is tentative, and providing the original 792 * symbol isn't strong and the new symbol weak, take the real 793 * symbol, else 794 * 795 * - if the original symbol is weak and the new tentative symbol is 796 * strong take the new symbol. 797 * 798 * Refer to the System V ABI Page 4-27 for a description of the binding 799 * requirements of tentative and weak symbols. 800 */ 801 if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) && 802 (ovis == STV_PROTECTED)) { 803 return; 804 } 805 806 if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) && 807 (nvis == STV_PROTECTED)) { 808 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 809 return; 810 } 811 812 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 813 if (warn) 814 eprintf(ofl->ofl_lml, ERR_NONE, 815 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 816 return; 817 } 818 819 if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) || 820 ((obind == STB_WEAK) && (nbind != STB_WEAK))) { 821 if (warn) 822 eprintf(ofl->ofl_lml, ERR_NONE, 823 MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name); 824 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 825 return; 826 } else { 827 if (warn) 828 eprintf(ofl->ofl_lml, ERR_NONE, 829 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 830 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 831 return; 832 } 833 } 834 835 /* 836 * Resolve two tentative symbols. 837 */ 838 static void 839 sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 840 int ndx, Word nshndx, sd_flag_t nsdflags) 841 { 842 Sym *osym = sdp->sd_sym; 843 uchar_t obind = ELF_ST_BIND(osym->st_info); 844 uchar_t nbind = ELF_ST_BIND(nsym->st_info); 845 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 846 Half nfile = ifl->ifl_ehdr->e_type; 847 size_t size = 0; 848 Xword value = 0; 849 850 #if defined(_ELF64) 851 if (ld_targ.t_m.m_mach == EM_AMD64) { 852 /* 853 * If the original and new symbols are both COMMON, but of 854 * a different size model, take the small one. 855 */ 856 if ((sdp->sd_sym->st_shndx == SHN_COMMON) && 857 (nsym->st_shndx == SHN_X86_64_LCOMMON)) { 858 /* 859 * Take the original symbol. 860 */ 861 return; 862 863 } else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) && 864 (nsym->st_shndx == SHN_COMMON)) { 865 /* 866 * Take the new symbol. 867 */ 868 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, 869 nsdflags); 870 return; 871 } 872 } 873 #endif 874 875 /* 876 * Check the alignment of the symbols. This can only be tested for if 877 * the symbols are not real definitions to a SHT_NOBITS section (ie. 878 * they were originally tentative), as in this case the symbol would 879 * have a displacement value rather than an alignment. In other words 880 * we can only test this for two relocatable objects. 881 */ 882 /* BEGIN CSTYLED */ 883 if ((osym->st_value != nsym->st_value) && 884 ((sdp->sd_flags & FLG_SY_SPECSEC) && 885 (sdp->sd_sym->st_shndx == SHN_COMMON) && 886 (nsdflags & FLG_SY_SPECSEC) && 887 #if defined(_ELF64) 888 (nsym->st_shndx == SHN_COMMON)) || 889 ((ld_targ.t_m.m_mach == EM_AMD64) && 890 (sdp->sd_flags & FLG_SY_SPECSEC) && 891 (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) && 892 (nsdflags & FLG_SY_SPECSEC) && 893 (nsym->st_shndx == SHN_X86_64_LCOMMON))) { 894 #else 895 (nsym->st_shndx == SHN_COMMON))) { 896 #endif 897 /* END CSTYLED */ 898 899 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 900 const char *file; 901 Xword salign; 902 Xword balign; 903 uint_t alignscompliment; 904 905 if (osym->st_value < nsym->st_value) { 906 salign = osym->st_value; 907 balign = nsym->st_value; 908 } else { 909 salign = nsym->st_value; 910 balign = osym->st_value; 911 } 912 913 /* 914 * If the smaller alignment fits smoothly into the 915 * larger alignment - we take it with no warning. 916 */ 917 if (S_ALIGN(balign, salign) == balign) 918 alignscompliment = 1; 919 else 920 alignscompliment = 0; 921 922 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 923 eprintf(ofl->ofl_lml, ERR_WARNING, 924 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 925 MSG_INTL(MSG_STR_ALIGNMENTS), 926 sdp->sd_file->ifl_name, EC_XWORD(osym->st_value), 927 ifl->ifl_name, EC_XWORD(nsym->st_value)); 928 929 /* 930 * Having provided the necessary warning indicate which 931 * relocatable object we are going to take. 932 * 933 * - if one symbol is weak and the other is non-weak 934 * take the non-weak symbol, else 935 * 936 * - take the largest alignment (as we still have to check 937 * the symbols size simply save the largest value for 938 * updating later). 939 */ 940 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) 941 file = ifl->ifl_name; 942 else if (obind != nbind) 943 file = sdp->sd_file->ifl_name; 944 else { 945 emsg = MSG_INTL(MSG_SYM_LARGER); 946 value = balign; 947 } 948 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 949 eprintf(ofl->ofl_lml, ERR_NONE, emsg, file); 950 } 951 952 /* 953 * Check the size of the symbols. 954 */ 955 if (osym->st_size != nsym->st_size) { 956 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 957 const char *file; 958 959 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 960 eprintf(ofl->ofl_lml, ERR_WARNING, 961 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 962 MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name, 963 EC_XWORD(osym->st_size), ifl->ifl_name, 964 EC_XWORD(nsym->st_size)); 965 966 967 /* 968 * This symbol has already been compared to an SO definition, 969 * as per the runtime behavior, ignore extra definitions. 970 */ 971 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 972 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 973 eprintf(ofl->ofl_lml, ERR_NONE, emsg, 974 sdp->sd_file->ifl_name); 975 return; 976 } 977 978 /* 979 * Having provided the necessary warning indicate what course 980 * of action we are going to take. 981 * 982 * - if the file types differ, take the relocatable object 983 * and apply the largest symbol size, else 984 * - if one symbol is weak and the other is non-weak, take 985 * the non-weak symbol, else 986 * - simply take the largest symbol reference. 987 */ 988 if (nfile != ofile) { 989 if (nfile == ET_REL) { 990 file = ifl->ifl_name; 991 if (osym->st_size > nsym->st_size) { 992 size = (size_t)osym->st_size; 993 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 994 } 995 sym_override(sdp, nsym, ifl, ofl, ndx, 996 nshndx, nsdflags); 997 } else { 998 file = sdp->sd_file->ifl_name; 999 if (osym->st_size < nsym->st_size) { 1000 size = (size_t)nsym->st_size; 1001 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 1002 } 1003 sym_promote(sdp, nsym, ifl, ofl, ndx, 1004 nshndx, nsdflags); 1005 } 1006 } else if (obind != nbind) { 1007 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) { 1008 sym_override(sdp, nsym, ifl, ofl, ndx, 1009 nshndx, nsdflags); 1010 file = ifl->ifl_name; 1011 } else 1012 file = sdp->sd_file->ifl_name; 1013 } else { 1014 if (osym->st_size < nsym->st_size) { 1015 sym_override(sdp, nsym, ifl, ofl, ndx, 1016 nshndx, nsdflags); 1017 file = ifl->ifl_name; 1018 } else 1019 file = sdp->sd_file->ifl_name; 1020 } 1021 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 1022 eprintf(ofl->ofl_lml, ERR_NONE, emsg, file); 1023 if (size) 1024 sdp->sd_sym->st_size = (Xword)size; 1025 } else { 1026 /* 1027 * If the sizes are the same 1028 * 1029 * - if the file types differ, take the relocatable object, 1030 * else 1031 * 1032 * - if one symbol is weak and the other is non-weak, take 1033 * the non-weak symbol, else 1034 * 1035 * - take the first reference. 1036 */ 1037 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) 1038 return; 1039 else if (((ofile != nfile) && (nfile == ET_REL)) || 1040 (((obind == STB_WEAK) && (nbind != STB_WEAK)) && 1041 (!((ofile != nfile) && (ofile == ET_REL))))) 1042 sym_override(sdp, nsym, ifl, ofl, ndx, 1043 nshndx, nsdflags); 1044 else 1045 sym_promote(sdp, nsym, ifl, ofl, ndx, 1046 nshndx, nsdflags); 1047 } 1048 1049 /* 1050 * Enforce the largest alignment if necessary. 1051 */ 1052 if (value) 1053 sdp->sd_sym->st_value = value; 1054 } 1055 1056 /* 1057 * Symbol resolution state table. `Action' describes the required 1058 * procedure to be called (if any). 1059 */ 1060 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *, 1061 Sym *, Ifl_desc *, Ofl_desc *, int, Word, sd_flag_t) = { 1062 1063 /* defined undef tent */ 1064 /* ET_REL ET_REL ET_REL */ 1065 1066 /* 0 defined REF_DYN_SEEN */ sym_tworeals, sym_promote, sym_realtent, 1067 /* 1 undef REF_DYN_SEEN */ sym_override, sym_override, sym_override, 1068 /* 2 tent REF_DYN_SEEN */ sym_realtent, sym_promote, sym_twotent, 1069 /* 3 defined REF_DYN_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 1070 /* 4 undef REF_DYN_NEED */ sym_override, sym_override, sym_override, 1071 /* 5 tent REF_DYN_NEED */ sym_realtent, sym_typecheck, sym_twotent, 1072 /* 6 defined REF_REL_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 1073 /* 7 undef REF_REL_NEED */ sym_override, sym_twoundefs, sym_override, 1074 /* 8 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent, 1075 1076 /* defined undef tent */ 1077 /* ET_DYN ET_DYN ET_DYN */ 1078 1079 /* 9 defined REF_DYN_SEEN */ sym_tworeals, sym_null, sym_realtent, 1080 /* 10 undef REF_DYN_SEEN */ sym_override, sym_mach_check, sym_override, 1081 /* 11 tent REF_DYN_SEEN */ sym_realtent, sym_null, sym_twotent, 1082 /* 12 defined REF_DYN_NEED */ sym_tworeals, sym_null, sym_realtent, 1083 /* 13 undef REF_DYN_NEED */ sym_override, sym_null, sym_override, 1084 /* 14 tent REF_DYN_NEED */ sym_realtent, sym_null, sym_twotent, 1085 /* 15 defined REF_REL_NEED */ sym_tworeals, sym_null, sym_realtent, 1086 /* 16 undef REF_REL_NEED */ sym_override, sym_mach_check, sym_override, 1087 /* 17 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent 1088 1089 }; 1090 1091 uintptr_t 1092 ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx, 1093 Word nshndx, sd_flag_t nsdflags) 1094 { 1095 int row, column; /* State table coordinates */ 1096 Sym *osym = sdp->sd_sym; 1097 sd_flag_t osdflags = sdp->sd_flags; 1098 Is_desc *isp; 1099 Half vis = 0, nfile = ifl->ifl_ehdr->e_type; 1100 Half oref = sdp->sd_ref; 1101 1102 /* 1103 * Determine the original symbols definition (defines row in Action[]). 1104 */ 1105 if (osdflags & FLG_SY_TENTSYM) 1106 row = SYM_TENTATIVE; 1107 else if ((sdp->sd_sym->st_shndx == SHN_UNDEF) || 1108 (sdp->sd_sym->st_shndx == SHN_SUNW_IGNORE)) 1109 row = SYM_UNDEFINED; 1110 else 1111 row = SYM_DEFINED; 1112 1113 /* 1114 * If the input file is an implicit shared object then we don't need 1115 * to bind to any symbols within it other than to verify that any 1116 * undefined references will be closed (implicit shared objects are only 1117 * processed when no undefined symbols are required as a result of the 1118 * link-edit (see process_dynamic())). 1119 */ 1120 if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) && 1121 (row != SYM_UNDEFINED)) 1122 return (1); 1123 1124 /* 1125 * Finish computing the Action[] row by applying the symbols reference 1126 * together with the input files type. 1127 */ 1128 row = row + (REF_NUM * sdp->sd_ref); 1129 if (nfile == ET_DYN) 1130 row += (REF_NUM * SYM_NUM); 1131 1132 /* 1133 * If either the original or new symbol originates from a relocatable 1134 * object, determine the appropriate visibility for the resolved symbol. 1135 */ 1136 if ((oref == REF_REL_NEED) || (nfile == ET_REL)) 1137 vis = sym_visibility(sdp, nsym, ifl, ofl); 1138 1139 /* 1140 * Determine the new symbols definition (defines column in Action[]). 1141 */ 1142 if ((nsdflags & FLG_SY_SPECSEC) && 1143 (nsym->st_shndx == SHN_COMMON)) { 1144 column = SYM_TENTATIVE; 1145 nsdflags |= FLG_SY_TENTSYM; 1146 #if defined(_ELF64) 1147 } else if ((ld_targ.t_m.m_mach == EM_AMD64) && 1148 (nsdflags & FLG_SY_SPECSEC) && 1149 (nsym->st_shndx == SHN_X86_64_LCOMMON)) { 1150 column = SYM_TENTATIVE; 1151 nsdflags |= FLG_SY_TENTSYM; 1152 #endif 1153 } else if ((nsym->st_shndx == SHN_UNDEF) || 1154 (nsym->st_shndx == SHN_SUNW_IGNORE)) { 1155 column = SYM_UNDEFINED; 1156 nshndx = SHN_UNDEF; 1157 } else { 1158 column = SYM_DEFINED; 1159 /* 1160 * If the new symbol is from a shared library and it is 1161 * associated with a SHT_NOBITS section then this symbol 1162 * originated from a tentative symbol. 1163 */ 1164 if (((nsdflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) { 1165 isp = ifl->ifl_isdesc[nshndx]; 1166 if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) { 1167 column = SYM_TENTATIVE; 1168 nsdflags |= FLG_SY_TENTSYM; 1169 } 1170 } 1171 } 1172 1173 DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column, 1174 osym, nsym, sdp, ifl)); 1175 1176 /* 1177 * Record the input filename on the defined files list for possible 1178 * later diagnostics. The `sa_dfiles' list is used to maintain the list 1179 * of shared objects that define the same symbol. This list is only 1180 * generated when the -m option is in effect and is used to list 1181 * multiple (interposed) definitions of a symbol (refer to ldmap_out()). 1182 */ 1183 if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nsym->st_shndx != SHN_UNDEF) && 1184 ((nsdflags & FLG_SY_SPECSEC) == 0)) 1185 if (aplist_append(&sdp->sd_aux->sa_dfiles, ifl->ifl_name, 1186 AL_CNT_SDP_DFILES) == NULL) 1187 return (S_ERROR); 1188 1189 /* 1190 * Perform the required resolution. 1191 */ 1192 Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 1193 1194 /* 1195 * Apply any visibility requirements. If a SINGLETON has been 1196 * established, make sure no symbol reduction indicators remain 1197 * associated with the symbol, and indicate that the symbol can not 1198 * be directly bound to. 1199 */ 1200 if ((oref == REF_REL_NEED) || (nfile == ET_REL)) { 1201 if ((vis == STV_EXPORTED) || (vis == STV_SINGLETON)) { 1202 sdp->sd_flags &= ~MSK_SY_LOCAL; 1203 1204 if (vis == STV_EXPORTED) 1205 sdp->sd_flags |= FLG_SY_EXPORT; 1206 else { 1207 sdp->sd_flags |= (FLG_SY_NDIR | FLG_SY_SINGLE); 1208 1209 if (sdp->sd_ref == REF_REL_NEED) { 1210 ofl->ofl_flags1 |= 1211 (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR); 1212 } 1213 } 1214 } else if (vis == STV_PROTECTED) { 1215 sdp->sd_flags |= FLG_SY_PROTECT; 1216 } else if ((vis == STV_INTERNAL) || (vis == STV_HIDDEN)) { 1217 sdp->sd_flags |= FLG_SY_HIDDEN; 1218 } else if (vis == STV_ELIMINATE) { 1219 sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM); 1220 } 1221 1222 sdp->sd_sym->st_other = 1223 (sdp->sd_sym->st_other & ~MSK_SYM_VISIBILITY) | vis; 1224 } 1225 1226 /* 1227 * If the symbol has been resolved to the new input file, and this is 1228 * a versioned relocatable object, then the version information of the 1229 * new symbol must be promoted to the versioning of the output file. 1230 */ 1231 if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) && 1232 (nsym->st_shndx != SHN_UNDEF)) 1233 ld_vers_promote(sdp, ndx, ifl, ofl); 1234 1235 /* 1236 * Determine whether a mapfile reference has been satisfied. Mapfile 1237 * symbol references augment symbols that should be contributed from 1238 * the relocatable objects used to build the output image. If a 1239 * relocatable object doesn't provide one of the mapfile symbol 1240 * references then somethings amiss, and will be flagged during symbol 1241 * validation. 1242 */ 1243 if ((nfile == ET_REL) && ((sdp->sd_flags & 1244 (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) { 1245 /* 1246 * Extern and parent references are satisfied by references from 1247 * a relocatable object. Note that we let *any* symbol type 1248 * satisfy this reference, to be as flexible as possible with 1249 * user written mapfiles. It could be questionable, for 1250 * example, if what a user expects to be an extern reference is 1251 * actually found to be a definition in a relocatable object. 1252 * 1253 * Any other mapfile reference (typically for versioning 1254 * information) simply augments a relocatables definition. 1255 */ 1256 if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) || 1257 ((sdp->sd_sym->st_shndx != SHN_UNDEF) && 1258 (sdp->sd_ref == REF_REL_NEED))) 1259 sdp->sd_flags |= FLG_SY_MAPUSED; 1260 } 1261 1262 /* 1263 * Make sure any special symbol requirements are carried over. 1264 */ 1265 if ((osdflags & FLG_SY_CAP) || (nsdflags & FLG_SY_CAP)) 1266 sdp->sd_flags |= FLG_SY_CAP; 1267 1268 DBG_CALL(Dbg_syms_resolved(ofl, sdp)); 1269 1270 return (1); 1271 } 1272