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