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 #if (defined(__i386) || defined(__amd64)) && defined(_ELF64) 654 /* 655 * If original and new are both COMMON but 656 * different size model, take the small one. 657 */ 658 if ((sdp->sd_shndx == SHN_COMMON) && 659 (nshndx == SHN_X86_64_LCOMMON)) { 660 /* 661 * Take the original one. 662 */ 663 return; 664 } else if ((sdp->sd_shndx == SHN_X86_64_LCOMMON) && 665 (nshndx == SHN_COMMON)) { 666 /* 667 * Take the new symbol. 668 */ 669 sym_override(sdp, nsym, ifl, ofl, ndx, 670 nshndx, nsymflags); 671 return; 672 } 673 #endif 674 675 /* 676 * Check the alignment of the symbols. This can only be tested for if 677 * the symbols are not real definitions to a SHT_NOBITS section (ie. 678 * they were originally tentative), as in this case the symbol would 679 * have a displacement value rather than an alignment. In other words 680 * we can only test this for two relocatable objects. 681 */ 682 if ((osym->st_value != nsym->st_value) && 683 ((sdp->sd_flags & FLG_SY_SPECSEC) && 684 (sdp->sd_shndx == SHN_COMMON) && 685 (nsymflags & FLG_SY_SPECSEC) && 686 #if (defined(__i386) || defined(__amd64)) && defined(_ELF64) 687 (nshndx == SHN_COMMON)) || 688 ((sdp->sd_flags & FLG_SY_SPECSEC) && 689 (sdp->sd_shndx == SHN_X86_64_LCOMMON) && 690 (nsymflags & FLG_SY_SPECSEC) && 691 (nshndx == SHN_X86_64_LCOMMON))) { 692 #else 693 (nshndx == SHN_COMMON))) { 694 #endif 695 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 696 const char *file; 697 Xword salign; 698 Xword balign; 699 uint_t alignscompliment; 700 701 if (osym->st_value < nsym->st_value) { 702 salign = osym->st_value; 703 balign = nsym->st_value; 704 } else { 705 salign = nsym->st_value; 706 balign = osym->st_value; 707 } 708 709 /* 710 * If the smaller alignment fits smoothly into the 711 * larger alignment - we take it with no warning. 712 */ 713 if (S_ALIGN(balign, salign) == balign) 714 alignscompliment = 1; 715 else 716 alignscompliment = 0; 717 718 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 719 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR), 720 demangle(sdp->sd_name), 721 MSG_INTL(MSG_STR_ALIGNMENTS), 722 sdp->sd_file->ifl_name, EC_XWORD(osym->st_value), 723 ifl->ifl_name, EC_XWORD(nsym->st_value)); 724 725 /* 726 * Having provided the necessary warning indicate which 727 * relocatable object we are going to take. 728 * 729 * o if one symbol is weak and the other is non-weak 730 * take the non-weak symbol, else 731 * 732 * o take the largest alignment (as we still have to check 733 * the symbols size simply save the largest value for 734 * updating later). 735 */ 736 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) 737 file = ifl->ifl_name; 738 else if (obind != nbind) 739 file = sdp->sd_file->ifl_name; 740 else { 741 emsg = MSG_INTL(MSG_SYM_LARGER); 742 value = balign; 743 } 744 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 745 eprintf(ERR_NONE, emsg, file); 746 } 747 748 /* 749 * Check the size of the symbols. 750 */ 751 if (osym->st_size != nsym->st_size) { 752 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 753 const char *file; 754 755 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 756 eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR), 757 demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES), 758 sdp->sd_file->ifl_name, EC_XWORD(osym->st_size), 759 ifl->ifl_name, EC_XWORD(nsym->st_size)); 760 761 762 /* 763 * This symbol has already been compared to an SO definition, 764 * as per the runtime behavior, ignore extra definitions. 765 */ 766 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 767 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 768 eprintf(ERR_NONE, emsg, 769 sdp->sd_file->ifl_name); 770 return; 771 } 772 773 /* 774 * Having provided the necessary warning indicate what course 775 * of action we are going to take. 776 * 777 * o if the file types differ, take the relocatable object 778 * and apply the largest symbol size, else 779 * o if one symbol is weak and the other is non-weak, take 780 * the non-weak symbol, else 781 * o simply take the largest symbol reference. 782 */ 783 if (nfile != ofile) { 784 if (nfile == ET_REL) { 785 file = ifl->ifl_name; 786 if (osym->st_size > nsym->st_size) { 787 size = (size_t)osym->st_size; 788 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 789 } 790 sym_override(sdp, nsym, ifl, ofl, ndx, 791 nshndx, nsymflags); 792 } else { 793 file = sdp->sd_file->ifl_name; 794 if (osym->st_size < nsym->st_size) { 795 size = (size_t)nsym->st_size; 796 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 797 } 798 sym_promote(sdp, nsym, ifl, ofl, ndx, 799 nshndx, nsymflags); 800 } 801 } else if (obind != nbind) { 802 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) { 803 sym_override(sdp, nsym, ifl, ofl, ndx, 804 nshndx, nsymflags); 805 file = ifl->ifl_name; 806 } else 807 file = sdp->sd_file->ifl_name; 808 } else { 809 if (osym->st_size < nsym->st_size) { 810 sym_override(sdp, nsym, ifl, ofl, ndx, 811 nshndx, nsymflags); 812 file = ifl->ifl_name; 813 } else 814 file = sdp->sd_file->ifl_name; 815 } 816 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 817 eprintf(ERR_NONE, emsg, file); 818 if (size) 819 sdp->sd_sym->st_size = (Xword)size; 820 } else { 821 /* 822 * If the sizes are the same 823 * 824 * o if the file types differ, take the relocatable object, 825 * else 826 * 827 * o if one symbol is weak and the other is non-weak, take 828 * the non-weak symbol, else 829 * 830 * o take the first reference. 831 */ 832 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) 833 return; 834 else if (((ofile != nfile) && (nfile == ET_REL)) || 835 (((obind == STB_WEAK) && (nbind != STB_WEAK)) && 836 (!((ofile != nfile) && (ofile == ET_REL))))) 837 sym_override(sdp, nsym, ifl, ofl, ndx, 838 nshndx, nsymflags); 839 else 840 sym_promote(sdp, nsym, ifl, ofl, ndx, 841 nshndx, nsymflags); 842 } 843 844 /* 845 * Enforce the largest alignment if necessary. 846 */ 847 if (value) 848 sdp->sd_sym->st_value = value; 849 } 850 851 /* 852 * Symbol resolution state table. `Action' describes the required 853 * procedure to be called (if any). 854 */ 855 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *, 856 Sym *, Ifl_desc *, Ofl_desc *, int, Word, Word) = { 857 858 /* defined undef tent */ 859 /* ET_REL ET_REL ET_REL */ 860 861 /* 0 defined REF_DYN_SEEN */ sym_tworeals, sym_promote, sym_realtent, 862 /* 1 undef REF_DYN_SEEN */ sym_override, sym_override, sym_override, 863 /* 2 tent REF_DYN_SEEN */ sym_realtent, sym_promote, sym_twotent, 864 /* 3 defined REF_DYN_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 865 /* 4 undef REF_DYN_NEED */ sym_override, sym_override, sym_override, 866 /* 5 tent REF_DYN_NEED */ sym_realtent, sym_typecheck, sym_twotent, 867 /* 6 defined REF_REL_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 868 /* 7 undef REF_REL_NEED */ sym_override, sym_twoundefs, sym_override, 869 /* 8 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent, 870 871 /* defined undef tent */ 872 /* ET_DYN ET_DYN ET_DYN */ 873 874 /* 9 defined REF_DYN_SEEN */ sym_tworeals, sym_null, sym_realtent, 875 /* 10 undef REF_DYN_SEEN */ sym_override, sym_mach_check, sym_override, 876 /* 11 tent REF_DYN_SEEN */ sym_realtent, sym_null, sym_twotent, 877 /* 12 defined REF_DYN_NEED */ sym_tworeals, sym_null, sym_realtent, 878 /* 13 undef REF_DYN_NEED */ sym_override, sym_null, sym_override, 879 /* 14 tent REF_DYN_NEED */ sym_realtent, sym_null, sym_twotent, 880 /* 15 defined REF_REL_NEED */ sym_tworeals, sym_null, sym_realtent, 881 /* 16 undef REF_REL_NEED */ sym_override, sym_mach_check, sym_override, 882 /* 17 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent 883 884 }; 885 886 uintptr_t 887 sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx, 888 Word nshndx, Word nsymflags) 889 { 890 int row, column; /* State table coordinates */ 891 Sym *osym = sdp->sd_sym; 892 Is_desc *isp; 893 Half nfile = ifl->ifl_ehdr->e_type; 894 895 /* 896 * Determine the original symbols definition (defines row in Action[]). 897 */ 898 if (sdp->sd_flags & FLG_SY_TENTSYM) 899 row = SYM_TENTATIVE; 900 else if (sdp->sd_shndx == SHN_UNDEF) 901 row = SYM_UNDEFINED; 902 else 903 row = SYM_DEFINED; 904 905 /* 906 * If the input file is an implicit shared object then we don't need 907 * to bind to any symbols within it other than to verify that any 908 * undefined references will be closed (implicit shared objects are only 909 * processed when no undefined symbols are required as a result of the 910 * link-edit (see process_dynamic())). 911 */ 912 if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) && 913 (row != SYM_UNDEFINED)) 914 return (1); 915 916 /* 917 * Finish computing the Action[] row by applying the symbols reference 918 * together with the input files type. 919 */ 920 row = row + (REF_NUM * sdp->sd_ref); 921 if (nfile == ET_DYN) 922 row += (REF_NUM * SYM_NUM); 923 924 /* 925 * Determine the new symbols definition (defines column in Action[]). 926 */ 927 if ((nsymflags & FLG_SY_SPECSEC) && 928 (nshndx == SHN_COMMON)) { 929 column = SYM_TENTATIVE; 930 nsymflags |= FLG_SY_TENTSYM; 931 #if (defined(__i386) || defined(__amd64)) && defined(_ELF64) 932 } else if ((nsymflags & FLG_SY_SPECSEC) && 933 (nshndx == SHN_X86_64_LCOMMON)) { 934 column = SYM_TENTATIVE; 935 nsymflags |= FLG_SY_TENTSYM; 936 #endif 937 } else if ((nshndx == SHN_UNDEF) || (nshndx == SHN_SUNW_IGNORE)) { 938 column = SYM_UNDEFINED; 939 nshndx = SHN_UNDEF; 940 } else { 941 column = SYM_DEFINED; 942 /* 943 * If the new symbol is from a shared library and it is 944 * associated with a SHT_NOBITS section then this symbol 945 * originated from a tentative symbol. 946 */ 947 if (((nsymflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) { 948 isp = ifl->ifl_isdesc[nshndx]; 949 if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) { 950 column = SYM_TENTATIVE; 951 nsymflags |= FLG_SY_TENTSYM; 952 } 953 } 954 } 955 956 DBG_CALL(Dbg_syms_resolving1(ndx, sdp->sd_name, row, column)); 957 DBG_CALL(Dbg_syms_resolving2(ifl->ifl_ehdr, osym, nsym, sdp, ifl)); 958 959 /* 960 * Record the input filename on the defined files list for possible 961 * later diagnostics. The `sa_dfiles' list is used to maintain the list 962 * of shared objects that define the same symbol. This list is only 963 * generated when the -m option is in effect and is used to list 964 * multiple (interposed) definitions of a symbol (refer to ldmap_out()). 965 */ 966 if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nshndx != SHN_UNDEF) && 967 ((nsymflags & FLG_SY_SPECSEC) == 0)) 968 if (list_appendc(&sdp->sd_aux->sa_dfiles, ifl->ifl_name) == 0) 969 return (S_ERROR); 970 971 /* 972 * Perform the required resolution. 973 */ 974 Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 975 976 /* 977 * If the symbol has been resolved to the new input file, and this is 978 * a versioned relocatable object, then the version information of the 979 * new symbol must be promoted to the versioning of the output file. 980 */ 981 if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) && 982 (nshndx != SHN_UNDEF)) 983 vers_promote(sdp, ndx, ifl, ofl); 984 985 /* 986 * Determine whether a mapfile reference has been satisfied. Mapfile 987 * symbol references augment symbols that should be contributed from 988 * the relocatable objects used to build the output image. If a 989 * relocatable object doesn't provide one of the mapfile symbol 990 * references then somethings amiss, and will be flagged during symbol 991 * validation. 992 */ 993 if ((nfile == ET_REL) && ((sdp->sd_flags & 994 (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) { 995 /* 996 * Extern and parent references are satisfied by references from 997 * a relocatable object. Note that we let *any* symbol type 998 * satisfy this reference, to be as flexible as possible with 999 * user written mapfiles. It could be questionable, for 1000 * example, if what a user expects to be an extern reference is 1001 * actually found to be a definition in a relocatable object. 1002 * 1003 * Any other mapfile reference (typically for versioning 1004 * information) simply augments a relocatables definition. 1005 */ 1006 if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) || 1007 ((sdp->sd_shndx != SHN_UNDEF) && 1008 (sdp->sd_ref == REF_REL_NEED))) 1009 sdp->sd_flags |= FLG_SY_MAPUSED; 1010 } 1011 1012 DBG_CALL(Dbg_syms_resolved(ifl->ifl_ehdr, sdp)); 1013 1014 return (1); 1015 } 1016