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