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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 #pragma ident "%Z%%M% %I% %E% SMI" /* SVR4 6.2/18.2 */ 31 32 /* 33 * Symbol table resolution 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, Word nsymflags) 58 { 59 } 60 61 /* 62 * Check if two symbols types are compatible 63 */ 64 /*ARGSUSED4*/ 65 static void 66 sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 67 int ndx, Word nshndx, Word nsymflags) 68 { 69 unsigned char otype = ELF_ST_TYPE(sdp->sd_sym->st_info); 70 unsigned char ntype = ELF_ST_TYPE(nsym->st_info); 71 72 /* 73 * Perform any machine specific type checking. 74 */ 75 if (mach_sym_typecheck(sdp, nsym, ifl, ofl)) 76 return; 77 78 /* 79 * STV_VISIBILITY rules say that you must take the most restrictive 80 * value for a symbols reference. If we see a reference from two 81 * objects, even if a symbol isn't promoted/overridden, make sure that 82 * the more restrictive visibility is saved. 83 */ 84 if (ifl->ifl_ehdr->e_type == ET_REL) { 85 Sym * osym = sdp->sd_sym; 86 Half ovis = ELF_ST_VISIBILITY(osym->st_other); 87 Half nvis = ELF_ST_VISIBILITY(nsym->st_other); 88 89 if ((nvis > STV_DEFAULT) && 90 ((ovis == STV_DEFAULT) || (nvis < ovis))) { 91 osym->st_other = 92 (osym->st_other & ~MSK_SYM_VISIBILITY) | nvis; 93 } 94 } 95 96 /* 97 * NOTYPE's can be combind with other types, only give an error if 98 * combining two differing types without NOTYPE 99 */ 100 if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE)) 101 return; 102 103 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 104 demangle(sdp->sd_name)); 105 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), sdp->sd_file->ifl_name, 106 conv_info_type_str(ofl->ofl_e_machine, otype), ifl->ifl_name, 107 conv_info_type_str(ofl->ofl_e_machine, ntype)); 108 } 109 110 /*ARGSUSED4*/ 111 static void 112 sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 113 int ndx, Word nshndx, Word nsymflags) 114 { 115 /* 116 * Perform any machine specific type checking. 117 */ 118 (void) mach_sym_typecheck(sdp, nsym, ifl, ofl); 119 } 120 121 /* 122 * Promote the symbols reference. 123 */ 124 static void 125 /* ARGSUSED4 */ 126 sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 127 int ndx, Word nshndx, Word nsymflags) 128 { 129 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 130 131 /* 132 * If the old symbol is from a shared object and the new symbol is a 133 * reference from a relocatable object, promote the old symbols 134 * reference. 135 */ 136 if ((sdp->sd_ref == REF_DYN_SEEN) && 137 (ifl->ifl_ehdr->e_type == ET_REL)) { 138 sdp->sd_ref = REF_DYN_NEED; 139 140 /* 141 * If this is an undefined symbol it must be a relocatable 142 * object overriding a shared object. In this case also 143 * override the reference name so that any undefined symbol 144 * diagnostics will refer to the relocatable object name. 145 */ 146 if (nshndx == SHN_UNDEF) 147 sdp->sd_aux->sa_rfile = ifl->ifl_name; 148 149 /* 150 * If this symbol is an undefined, or common, determine whether 151 * it is a global or weak reference (see build_osym(), where 152 * REF_DYN_NEED definitions are returned back to undefines). 153 */ 154 if (((nshndx == SHN_UNDEF) || 155 ((nsymflags & FLG_SY_SPECSEC) && 156 (nshndx == SHN_COMMON))) && 157 (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL)) 158 sdp->sd_flags |= FLG_SY_GLOBREF; 159 160 } else if ((nshndx != SHN_UNDEF) && 161 (ofl->ofl_dtflags_1 & DF_1_TRANS) && 162 !sdp->sd_aux->sa_bindto && (sdp->sd_ref == REF_REL_NEED) && 163 (ifl->ifl_ehdr->e_type == ET_DYN)) { 164 /* 165 * If building a translator then record the symbol 166 * we would 'bindto' with direct bindings. 167 */ 168 sdp->sd_aux->sa_bindto = ifl; 169 } 170 } 171 172 /* 173 * Override a symbol. 174 */ 175 static void 176 sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 177 int ndx, Word nshndx, Word nsymflags) 178 { 179 Sym *osym = sdp->sd_sym; 180 Half ovis = ELF_ST_VISIBILITY(osym->st_other); 181 Half nvis = ELF_ST_VISIBILITY(nsym->st_other); 182 Word link; 183 184 /* 185 * In the case of a WEAK UNDEF symbol don't let a symbol from an 186 * unavailable object override the symbol definition. This is because 187 * this symbol *may* not be present in a future object and by promoting 188 * this symbol we are actually causing bindings (PLTS) to be formed 189 * to this symbol. Instead let the 'generic' weak binding take place. 190 */ 191 if ((ELF_ST_BIND(osym->st_info) == STB_WEAK) && 192 (sdp->sd_shndx == SHN_UNDEF) && !(ifl->ifl_flags & FLG_IF_NEEDED)) 193 return; 194 195 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 196 197 /* 198 * This symbol has already been compared to an SO definition, 199 * as per the runtime behavior, ignore extra definitions. 200 */ 201 if ((sdp->sd_flags & FLG_SY_SOFOUND) && 202 (ifl->ifl_ehdr->e_type == ET_DYN)) 203 return; 204 205 /* 206 * Mark the symbol as available and copy the new symbols contents. 207 */ 208 sdp->sd_flags &= ~FLG_SY_NOTAVAIL; 209 *osym = *nsym; 210 sdp->sd_shndx = nshndx; 211 sdp->sd_flags &= ~FLG_SY_SPECSEC; 212 sdp->sd_flags |= (nsymflags & (FLG_SY_SPECSEC | FLG_SY_TENTSYM)); 213 214 /* 215 * If the new symbol has PROTECTED visibility, mark it. If a PROTECTED 216 * symbol is copy relocated, a warning message will be printed. See 217 * reloc_exec(). 218 */ 219 if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED) 220 sdp->sd_flags |= FLG_SY_PROT; 221 else 222 sdp->sd_flags &= ~FLG_SY_PROT; 223 224 /* 225 * Establish the symbols reference. If the new symbol originates from a 226 * relocatable object then this reference becomes needed, otherwise 227 * the new symbol must be from a shared object. In this case only 228 * promote the symbol to needed if we presently have a reference from a 229 * relocatable object. 230 */ 231 if (ifl->ifl_ehdr->e_type == ET_REL) { 232 /* 233 * Maintain the more restrictive visiblity 234 */ 235 if ((ovis > STV_DEFAULT) && 236 ((nvis == STV_DEFAULT) || (ovis < nvis))) { 237 osym->st_other = 238 (osym->st_other & ~MSK_SYM_VISIBILITY) | ovis; 239 } 240 sdp->sd_ref = REF_REL_NEED; 241 242 if (nshndx == SHN_UNDEF) { 243 /* 244 * If this is an undefined symbol it must be a 245 * relocatable object overriding a shared object. In 246 * this case also override the reference name so that 247 * any undefined symbol diagnostics will refer to the 248 * relocatable object name. 249 */ 250 sdp->sd_aux->sa_rfile = ifl->ifl_name; 251 } else { 252 /* 253 * Under -Bnodirect, all exported interfaces are tagged 254 * to prevent direct binding to them. 255 */ 256 if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) && 257 ((sdp->sd_flags1 & FLG_SY1_DIR) == 0)) 258 sdp->sd_flags1 |= FLG_SY1_NDIR; 259 } 260 261 /* 262 * If this symbol is an undefined, or common, determine whether 263 * it is a global or weak reference (see build_osym(), where 264 * REF_DYN_NEED definitions are returned back to undefines). 265 */ 266 if (((nshndx == SHN_UNDEF) || 267 ((nsymflags & FLG_SY_SPECSEC) && (nshndx == SHN_COMMON))) && 268 (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL)) 269 sdp->sd_flags |= FLG_SY_GLOBREF; 270 else 271 sdp->sd_flags &= ~FLG_SY_GLOBREF; 272 } else { 273 if (sdp->sd_ref == REF_REL_NEED) 274 sdp->sd_ref = REF_DYN_NEED; 275 276 /* 277 * Visibility from a DYN symbol does not override 278 * previous symbol visibility. 279 */ 280 osym->st_other = (osym->st_other & ~MSK_SYM_VISIBILITY) | 281 ovis; 282 283 /* 284 * Determine the symbols availability. A symbol is determined 285 * to be unavailable if it belongs to a version of a shared 286 * object that this user does not wish to use, or if it belongs 287 * to an implicit shared object. 288 */ 289 if (ifl->ifl_vercnt) { 290 Ver_index * vip; 291 Half vndx = ifl->ifl_versym[ndx]; 292 293 sdp->sd_aux->sa_dverndx = vndx; 294 vip = &ifl->ifl_verndx[vndx]; 295 if (!(vip->vi_flags & FLG_VER_AVAIL)) { 296 sdp->sd_flags |= FLG_SY_NOTAVAIL; 297 /* 298 * If this is the first occurance of an 299 * unavailable symbol record it for possible 300 * use in later error diagnostics 301 * (see sym_undef). 302 */ 303 if (!(sdp->sd_aux->sa_vfile)) 304 sdp->sd_aux->sa_vfile = ifl->ifl_name; 305 } 306 } 307 if (!(ifl->ifl_flags & FLG_IF_NEEDED)) 308 sdp->sd_flags |= FLG_SY_NOTAVAIL; 309 } 310 311 /* 312 * Make sure any symbol association maintained by the original symbol 313 * is cleared and then update the symbols file reference. 314 */ 315 if ((link = sdp->sd_aux->sa_linkndx) != 0) { 316 Sym_desc * _sdp; 317 318 _sdp = sdp->sd_file->ifl_oldndx[link]; 319 _sdp->sd_aux->sa_linkndx = 0; 320 sdp->sd_aux->sa_linkndx = 0; 321 } 322 sdp->sd_file = ifl; 323 324 /* 325 * Update the input section descriptor to that of the new input file 326 */ 327 if (((nsymflags & FLG_SY_SPECSEC) == 0) && (nshndx != SHN_UNDEF)) 328 if ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == 0) { 329 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_NOSECDEF), 330 demangle(sdp->sd_name), ifl->ifl_name); 331 ofl->ofl_flags |= FLG_OF_FATAL; 332 } 333 } 334 335 336 /* 337 * Resolve two undefines (only called for two relocatable objects). 338 */ 339 static void 340 sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 341 int ndx, Word nshndx, Word nsymflags) 342 { 343 Sym *osym = sdp->sd_sym; 344 unsigned char obind = ELF_ST_BIND(osym->st_info); 345 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 346 347 /* 348 * If two relocatable objects define a weak and non-weak undefined 349 * reference, take the non-weak definition. 350 * 351 * -- or -- 352 * 353 * If two relocatable objects define a NOTYPE & another, then 354 * take the other. 355 */ 356 if (((obind == STB_WEAK) && (nbind != STB_WEAK)) || 357 (obind == STT_NOTYPE) && (nbind != STT_NOTYPE)) { 358 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 359 return; 360 } 361 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 362 } 363 364 /* 365 * Resolve two real definitions. 366 */ 367 static void 368 sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 369 int ndx, Word nshndx, Word nsymflags) 370 { 371 Sym *osym = sdp->sd_sym; 372 unsigned char otype = ELF_ST_TYPE(osym->st_info); 373 unsigned char obind = ELF_ST_BIND(osym->st_info); 374 unsigned char ntype = ELF_ST_TYPE(nsym->st_info); 375 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 376 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 377 Half nfile = ifl->ifl_ehdr->e_type; 378 int warn = 0; 379 380 /* 381 * If both definitions are from relocatable objects, and have non-weak 382 * binding then this is a fatal condition. 383 */ 384 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) && 385 (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) { 386 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF), 387 demangle(sdp->sd_name)); 388 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 389 sdp->sd_file->ifl_name, 390 conv_info_type_str(ofl->ofl_e_machine, otype), 391 ifl->ifl_name, 392 conv_info_type_str(ofl->ofl_e_machine, ntype)); 393 ofl->ofl_flags |= FLG_OF_FATAL; 394 return; 395 } 396 397 /* 398 * Perform any machine specific type checking. 399 */ 400 if (mach_sym_typecheck(sdp, nsym, ifl, ofl)) 401 return; 402 403 /* 404 * Check the symbols type and size. 405 */ 406 if (otype != ntype) { 407 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 408 demangle(sdp->sd_name)); 409 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 410 sdp->sd_file->ifl_name, 411 conv_info_type_str(ofl->ofl_e_machine, otype), 412 ifl->ifl_name, conv_info_type_str(ofl->ofl_e_machine, 413 ntype)); 414 warn++; 415 } else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) { 416 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 417 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR), 418 demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES), 419 sdp->sd_file->ifl_name, EC_XWORD(osym->st_size), 420 ifl->ifl_name, EC_XWORD(nsym->st_size)); 421 warn++; 422 } 423 } 424 425 /* 426 * Having provided the user with any necessary warnings, take the 427 * appropriate symbol: 428 * 429 * o if one symbol is from a shared object and the other is from a 430 * relocatable object, take the relocatable objects symbol (the 431 * run-time linker is always going to find the relocatable object 432 * symbol regardless of the binding), else 433 * 434 * o if both symbols are from relocatable objects and one symbol is 435 * weak take the non-weak symbol (two non-weak symbols would have 436 * generated the fatal error condition above unless -z muldefs is 437 * in effect), else 438 * 439 * o take the first symbol definition encountered. 440 */ 441 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 442 if (warn) 443 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 444 sdp->sd_file->ifl_name); 445 return; 446 } else if ((nfile == ET_REL) && ((ofile == ET_DYN) || 447 ((obind == STB_WEAK) && (nbind != STB_WEAK)))) { 448 if (warn) 449 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 450 ifl->ifl_name); 451 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 452 return; 453 } else { 454 if (warn) 455 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 456 sdp->sd_file->ifl_name); 457 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 458 return; 459 } 460 } 461 462 /* 463 * Resolve a real and tentative definition. 464 */ 465 static void 466 sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 467 int ndx, Word nshndx, Word nsymflags) 468 { 469 Sym *osym = sdp->sd_sym; 470 unsigned char otype = ELF_ST_TYPE(osym->st_info); 471 unsigned char obind = ELF_ST_BIND(osym->st_info); 472 unsigned char ntype = ELF_ST_TYPE(nsym->st_info); 473 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 474 Boolean otent = FALSE, ntent = FALSE; 475 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 476 Half nfile = ifl->ifl_ehdr->e_type; 477 int warn = 0; 478 Word osymvis = ELF_ST_VISIBILITY(osym->st_other); 479 Word nsymvis = ELF_ST_VISIBILITY(nsym->st_other); 480 481 /* 482 * Special rules for functions. 483 * 484 * o If both definitions are from relocatable objects, have the same 485 * binding (ie. two weaks or two non-weaks), and the real 486 * definition is a function (the other must be tentative), treat 487 * this as a multiply defined symbol error, else 488 * 489 * o if the real symbol definition is a function within a shared 490 * library and the tentative symbol is a relocatable object, and 491 * the tentative is not weak and the function real, then retain the 492 * tentative definition. 493 */ 494 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) && 495 ((otype == STT_FUNC) || (ntype == STT_FUNC))) { 496 if (ofl->ofl_flags & FLG_OF_MULDEFS) { 497 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 498 demangle(sdp->sd_name)); 499 sym_promote(sdp, nsym, ifl, ofl, ndx, 500 nshndx, nsymflags); 501 } else { 502 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF), 503 demangle(sdp->sd_name)); 504 ofl->ofl_flags |= FLG_OF_FATAL; 505 } 506 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 507 sdp->sd_file->ifl_name, 508 conv_info_type_str(ofl->ofl_e_machine, otype), 509 ifl->ifl_name, conv_info_type_str(ofl->ofl_e_machine, 510 ntype)); 511 return; 512 } else if (ofile != nfile) { 513 514 515 if ((ofile == ET_DYN) && (otype == STT_FUNC)) { 516 if ((otype != STB_WEAK) && (ntype == STB_WEAK)) 517 return; 518 else { 519 sym_override(sdp, nsym, ifl, ofl, ndx, 520 nshndx, nsymflags); 521 return; 522 } 523 } 524 if ((nfile == ET_DYN) && (ntype == STT_FUNC)) { 525 if ((ntype != STB_WEAK) && (otype == STB_WEAK)) { 526 sym_override(sdp, nsym, ifl, ofl, ndx, 527 nshndx, nsymflags); 528 return; 529 } else 530 return; 531 } 532 } 533 534 if (sdp->sd_flags & FLG_SY_TENTSYM) 535 otent = TRUE; 536 if (nsymflags & FLG_SY_TENTSYM) 537 ntent = TRUE; 538 539 540 /* 541 * Check the symbols type and size. 542 */ 543 if (otype != ntype) { 544 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 545 demangle(sdp->sd_name)); 546 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 547 sdp->sd_file->ifl_name, 548 conv_info_type_str(ofl->ofl_e_machine, otype), 549 ifl->ifl_name, conv_info_type_str(ofl->ofl_e_machine, 550 ntype)); 551 warn++; 552 } else if (osym->st_size != nsym->st_size) { 553 /* 554 * If both definitions are from relocatable objects we have a 555 * potential fatal error condition. If the tentative is larger 556 * than the real definition treat this as a multiple definition. 557 * Note that if only one symbol is weak, the non-weak will be 558 * taken. 559 */ 560 if (((ofile == ET_REL) && (nfile == ET_REL) && 561 (obind == nbind)) && 562 ((otent && (osym->st_size > nsym->st_size)) || 563 (ntent && (osym->st_size < nsym->st_size)))) { 564 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_DIFFATTR), 565 demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES), 566 sdp->sd_file->ifl_name, EC_XWORD(osym->st_size), 567 ifl->ifl_name, EC_XWORD(nsym->st_size)); 568 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_TENTERR)); 569 ofl->ofl_flags |= FLG_OF_FATAL; 570 } else { 571 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 572 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR), 573 demangle(sdp->sd_name), 574 MSG_INTL(MSG_STR_SIZES), 575 sdp->sd_file->ifl_name, 576 EC_XWORD(osym->st_size), 577 ifl->ifl_name, EC_XWORD(nsym->st_size)); 578 warn++; 579 } 580 } 581 } 582 583 /* 584 * Having provided the user with any necessary warnings, take the 585 * appropriate symbol: 586 * 587 * o if the original symbol is from relocatable file and it is 588 * a protected tentative symbol, take the original one. 589 * 590 * o if the original symbol is from shared object and the new 591 * symbol is a protected tentative symbol from a relocatable file, 592 * take the new one. 593 * 594 * o if the original symbol is tentative, and providing the original 595 * symbol isn't strong and the new symbol weak, take the real 596 * symbol, else 597 * 598 * o if the original symbol is weak and the new tentative symbol is 599 * strong take the new symbol. 600 * 601 * Refer to the System V ABI Page 4-27 for a description of the binding 602 * requirements of tentative and weak symbols. 603 */ 604 if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) && 605 (osymvis == STV_PROTECTED)) { 606 return; 607 } 608 609 if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) && 610 (nsymvis == STV_PROTECTED)) { 611 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 612 return; 613 } 614 615 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 616 if (warn) 617 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 618 sdp->sd_file->ifl_name); 619 return; 620 } 621 622 if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) || 623 ((obind == STB_WEAK) && (nbind != STB_WEAK))) { 624 if (warn) 625 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 626 ifl->ifl_name); 627 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 628 return; 629 } else { 630 if (warn) 631 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 632 sdp->sd_file->ifl_name); 633 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 634 return; 635 } 636 } 637 638 /* 639 * Resolve two tentative symbols. 640 */ 641 static void 642 sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 643 int ndx, Word nshndx, Word nsymflags) 644 { 645 Sym *osym = sdp->sd_sym; 646 unsigned char obind = ELF_ST_BIND(osym->st_info); 647 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 648 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 649 Half nfile = ifl->ifl_ehdr->e_type; 650 size_t size = 0; 651 Xword value = 0; 652 653 /* 654 * Check the alignment of the symbols. This can only be tested for if 655 * the symbols are not real definitions to a SHT_NOBITS section (ie. 656 * they were originally tentative), as in this case the symbol would 657 * have a displacement value rather than an alignment. In other words 658 * we can only test this for two relocatable objects. 659 */ 660 if ((osym->st_value != nsym->st_value) && 661 ((sdp->sd_flags & FLG_SY_SPECSEC) && 662 (sdp->sd_shndx == SHN_COMMON)) && 663 ((nsymflags & FLG_SY_SPECSEC) && 664 (nshndx == SHN_COMMON))) { 665 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 666 const char *file; 667 Xword salign; 668 Xword balign; 669 uint_t alignscompliment; 670 671 if (osym->st_value < nsym->st_value) { 672 salign = osym->st_value; 673 balign = nsym->st_value; 674 } else { 675 salign = nsym->st_value; 676 balign = osym->st_value; 677 } 678 679 /* 680 * If the smaller alignment fits smoothly into the 681 * larger alignment - we take it with no warning. 682 */ 683 if (S_ALIGN(balign, salign) == balign) 684 alignscompliment = 1; 685 else 686 alignscompliment = 0; 687 688 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 689 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR), 690 demangle(sdp->sd_name), 691 MSG_INTL(MSG_STR_ALIGNMENTS), 692 sdp->sd_file->ifl_name, EC_XWORD(osym->st_value), 693 ifl->ifl_name, EC_XWORD(nsym->st_value)); 694 695 /* 696 * Having provided the necessary warning indicate which 697 * relocatable object we are going to take. 698 * 699 * o if one symbol is weak and the other is non-weak 700 * take the non-weak symbol, else 701 * 702 * o take the largest alignment (as we still have to check 703 * the symbols size simply save the largest value for 704 * updating later). 705 */ 706 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) 707 file = ifl->ifl_name; 708 else if (obind != nbind) 709 file = sdp->sd_file->ifl_name; 710 else { 711 emsg = MSG_INTL(MSG_SYM_LARGER); 712 value = balign; 713 } 714 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 715 eprintf(ERR_NONE, emsg, file); 716 } 717 718 /* 719 * Check the size of the symbols. 720 */ 721 if (osym->st_size != nsym->st_size) { 722 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 723 const char *file; 724 725 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 726 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR), 727 demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES), 728 sdp->sd_file->ifl_name, EC_XWORD(osym->st_size), 729 ifl->ifl_name, EC_XWORD(nsym->st_size)); 730 731 732 /* 733 * This symbol has already been compared to an SO definition, 734 * as per the runtime behavior, ignore extra definitions. 735 */ 736 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 737 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 738 eprintf(ERR_NONE, emsg, 739 sdp->sd_file->ifl_name); 740 return; 741 } 742 743 /* 744 * Having provided the necessary warning indicate what course 745 * of action we are going to take. 746 * 747 * o if the file types differ, take the relocatable object 748 * and apply the largest symbol size, else 749 * o if one symbol is weak and the other is non-weak, take 750 * the non-weak symbol, else 751 * o simply take the largest symbol reference. 752 */ 753 if (nfile != ofile) { 754 if (nfile == ET_REL) { 755 file = ifl->ifl_name; 756 if (osym->st_size > nsym->st_size) { 757 size = (size_t)osym->st_size; 758 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 759 } 760 sym_override(sdp, nsym, ifl, ofl, ndx, 761 nshndx, nsymflags); 762 } else { 763 file = sdp->sd_file->ifl_name; 764 if (osym->st_size < nsym->st_size) { 765 size = (size_t)nsym->st_size; 766 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 767 } 768 sym_promote(sdp, nsym, ifl, ofl, ndx, 769 nshndx, nsymflags); 770 } 771 } else if (obind != nbind) { 772 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) { 773 sym_override(sdp, nsym, ifl, ofl, ndx, 774 nshndx, nsymflags); 775 file = ifl->ifl_name; 776 } else 777 file = sdp->sd_file->ifl_name; 778 } else { 779 if (osym->st_size < nsym->st_size) { 780 sym_override(sdp, nsym, ifl, ofl, ndx, 781 nshndx, nsymflags); 782 file = ifl->ifl_name; 783 } else 784 file = sdp->sd_file->ifl_name; 785 } 786 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 787 eprintf(ERR_NONE, emsg, file); 788 if (size) 789 sdp->sd_sym->st_size = (Xword)size; 790 } else { 791 /* 792 * If the sizes are the same 793 * 794 * o if the file types differ, take the relocatable object, 795 * else 796 * 797 * o if one symbol is weak and the other is non-weak, take 798 * the non-weak symbol, else 799 * 800 * o take the first reference. 801 */ 802 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) 803 return; 804 else if (((ofile != nfile) && (nfile == ET_REL)) || 805 (((obind == STB_WEAK) && (nbind != STB_WEAK)) && 806 (!((ofile != nfile) && (ofile == ET_REL))))) 807 sym_override(sdp, nsym, ifl, ofl, ndx, 808 nshndx, nsymflags); 809 else 810 sym_promote(sdp, nsym, ifl, ofl, ndx, 811 nshndx, nsymflags); 812 } 813 814 /* 815 * Enforce the largest alignment if necessary. 816 */ 817 if (value) 818 sdp->sd_sym->st_value = value; 819 } 820 821 /* 822 * Symbol resolution state table. `Action' describes the required 823 * procedure to be called (if any). 824 */ 825 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *, 826 Sym *, Ifl_desc *, Ofl_desc *, int, Word, Word) = { 827 828 /* defined undef tent */ 829 /* ET_REL ET_REL ET_REL */ 830 831 /* 0 defined REF_DYN_SEEN */ sym_tworeals, sym_promote, sym_realtent, 832 /* 1 undef REF_DYN_SEEN */ sym_override, sym_override, sym_override, 833 /* 2 tent REF_DYN_SEEN */ sym_realtent, sym_promote, sym_twotent, 834 /* 3 defined REF_DYN_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 835 /* 4 undef REF_DYN_NEED */ sym_override, sym_override, sym_override, 836 /* 5 tent REF_DYN_NEED */ sym_realtent, sym_typecheck, sym_twotent, 837 /* 6 defined REF_REL_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 838 /* 7 undef REF_REL_NEED */ sym_override, sym_twoundefs, sym_override, 839 /* 8 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent, 840 841 /* defined undef tent */ 842 /* ET_DYN ET_DYN ET_DYN */ 843 844 /* 9 defined REF_DYN_SEEN */ sym_tworeals, sym_null, sym_realtent, 845 /* 10 undef REF_DYN_SEEN */ sym_override, sym_mach_check, sym_override, 846 /* 11 tent REF_DYN_SEEN */ sym_realtent, sym_null, sym_twotent, 847 /* 12 defined REF_DYN_NEED */ sym_tworeals, sym_null, sym_realtent, 848 /* 13 undef REF_DYN_NEED */ sym_override, sym_null, sym_override, 849 /* 14 tent REF_DYN_NEED */ sym_realtent, sym_null, sym_twotent, 850 /* 15 defined REF_REL_NEED */ sym_tworeals, sym_null, sym_realtent, 851 /* 16 undef REF_REL_NEED */ sym_override, sym_mach_check, sym_override, 852 /* 17 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent 853 854 }; 855 856 uintptr_t 857 sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx, 858 Word nshndx, Word nsymflags) 859 { 860 int row, column; /* State table coordinates */ 861 Sym *osym = sdp->sd_sym; 862 Is_desc *isp; 863 Half nfile = ifl->ifl_ehdr->e_type; 864 865 /* 866 * Determine the original symbols definition (defines row in Action[]). 867 */ 868 if (sdp->sd_flags & FLG_SY_TENTSYM) 869 row = SYM_TENTATIVE; 870 else if (sdp->sd_shndx == SHN_UNDEF) 871 row = SYM_UNDEFINED; 872 else 873 row = SYM_DEFINED; 874 875 /* 876 * If the input file is an implicit shared object then we don't need 877 * to bind to any symbols within it other than to verify that any 878 * undefined references will be closed (implicit shared objects are only 879 * processed when no undefined symbols are required as a result of the 880 * link-edit (see process_dynamic())). 881 */ 882 if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) && 883 (row != SYM_UNDEFINED)) 884 return (1); 885 886 /* 887 * Finish computing the Action[] row by applying the symbols reference 888 * together with the input files type. 889 */ 890 row = row + (REF_NUM * sdp->sd_ref); 891 if (nfile == ET_DYN) 892 row += (REF_NUM * SYM_NUM); 893 894 /* 895 * Determine the new symbols definition (defines column in Action[]). 896 */ 897 if ((nsymflags & FLG_SY_SPECSEC) && 898 (nshndx == SHN_COMMON)) { 899 column = SYM_TENTATIVE; 900 nsymflags |= FLG_SY_TENTSYM; 901 } else if ((nshndx == SHN_UNDEF) || (nshndx == SHN_SUNW_IGNORE)) { 902 column = SYM_UNDEFINED; 903 nshndx = SHN_UNDEF; 904 } else { 905 column = SYM_DEFINED; 906 /* 907 * If the new symbol is from a shared library and it is 908 * associated with a SHT_NOBITS section then this symbol 909 * originated from a tentative symbol. 910 */ 911 if (((nsymflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) { 912 isp = ifl->ifl_isdesc[nshndx]; 913 if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) { 914 column = SYM_TENTATIVE; 915 nsymflags |= FLG_SY_TENTSYM; 916 } 917 } 918 } 919 920 DBG_CALL(Dbg_syms_resolving1(ndx, sdp->sd_name, row, column)); 921 DBG_CALL(Dbg_syms_resolving2(ifl->ifl_ehdr, osym, nsym, sdp, ifl)); 922 923 /* 924 * Record the input filename on the defined files list for possible 925 * later diagnostics. The `sa_dfiles' list is used to maintain the list 926 * of shared objects that define the same symbol. This list is only 927 * generated when the -m option is in effect and is used to list 928 * multiple (interposed) definitions of a symbol (refer to ldmap_out()). 929 */ 930 if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nshndx != SHN_UNDEF) && 931 ((nsymflags & FLG_SY_SPECSEC) == 0)) 932 if (list_appendc(&sdp->sd_aux->sa_dfiles, ifl->ifl_name) == 0) 933 return (S_ERROR); 934 935 /* 936 * Perform the required resolution. 937 */ 938 Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 939 940 /* 941 * If the symbol has been resolved to the new input file, and this is 942 * a versioned relocatable object, then the version information of the 943 * new symbol must be promoted to the versioning of the output file. 944 */ 945 if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) && 946 (nshndx != SHN_UNDEF)) 947 vers_promote(sdp, ndx, ifl, ofl); 948 949 /* 950 * Determine whether a mapfile reference has been satisfied. Mapfile 951 * symbol references augment symbols that should be contributed from 952 * the relocatable objects used to build the output image. If a 953 * relocatable object doesn't provide one of the mapfile symbol 954 * references then somethings amiss, and will be flagged during symbol 955 * validation. 956 */ 957 if ((nfile == ET_REL) && ((sdp->sd_flags & 958 (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) { 959 /* 960 * Extern and parent references are satisfied by references from 961 * a relocatable object. Note that we let *any* symbol type 962 * satisfy this reference, to be as flexible as possible with 963 * user written mapfiles. It could be questionable, for 964 * example, if what a user expects to be an extern reference is 965 * actually found to be a definition in a relocatable object. 966 * 967 * Any other mapfile reference (typically for versioning 968 * information) simply augments a relocatables definition. 969 */ 970 if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) || 971 ((sdp->sd_shndx != SHN_UNDEF) && 972 (sdp->sd_ref == REF_REL_NEED))) 973 sdp->sd_flags |= FLG_SY_MAPUSED; 974 } 975 976 DBG_CALL(Dbg_syms_resolved(ifl->ifl_ehdr, sdp)); 977 978 return (1); 979 } 980