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 2006 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 unsigned char otype = ELF_ST_TYPE(sdp->sd_sym->st_info); 69 unsigned char 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), ifl->ifl_name, 107 conv_sym_info_type(ofl->ofl_dehdr->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) ld_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(ofl->ofl_lml, ERR_FATAL, 330 MSG_INTL(MSG_SYM_NOSECDEF), demangle(sdp->sd_name), 331 ifl->ifl_name); 332 ofl->ofl_flags |= FLG_OF_FATAL; 333 } 334 } 335 336 337 /* 338 * Resolve two undefines (only called for two relocatable objects). 339 */ 340 static void 341 sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 342 int ndx, Word nshndx, Word nsymflags) 343 { 344 Sym *osym = sdp->sd_sym; 345 unsigned char obind = ELF_ST_BIND(osym->st_info); 346 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 347 348 /* 349 * If two relocatable objects define a weak and non-weak undefined 350 * reference, take the non-weak definition. 351 * 352 * -- or -- 353 * 354 * If two relocatable objects define a NOTYPE & another, then 355 * take the other. 356 */ 357 if (((obind == STB_WEAK) && (nbind != STB_WEAK)) || 358 (obind == STT_NOTYPE) && (nbind != STT_NOTYPE)) { 359 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 360 return; 361 } 362 sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 363 } 364 365 /* 366 * Resolve two real definitions. 367 */ 368 static void 369 sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 370 int ndx, Word nshndx, Word nsymflags) 371 { 372 Sym *osym = sdp->sd_sym; 373 unsigned char otype = ELF_ST_TYPE(osym->st_info); 374 unsigned char obind = ELF_ST_BIND(osym->st_info); 375 unsigned char ntype = ELF_ST_TYPE(nsym->st_info); 376 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 377 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 378 Half nfile = ifl->ifl_ehdr->e_type; 379 int warn = 0; 380 381 /* 382 * If both definitions are from relocatable objects, and have non-weak 383 * binding then this is a fatal condition. 384 */ 385 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) && 386 (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) { 387 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF), 388 demangle(sdp->sd_name)); 389 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 390 sdp->sd_file->ifl_name, 391 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype), 392 ifl->ifl_name, 393 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype)); 394 ofl->ofl_flags |= FLG_OF_FATAL; 395 return; 396 } 397 398 /* 399 * Perform any machine specific type checking. 400 */ 401 if (ld_mach_sym_typecheck(sdp, nsym, ifl, ofl)) 402 return; 403 404 /* 405 * Check the symbols type and size. 406 */ 407 if (otype != ntype) { 408 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 409 demangle(sdp->sd_name)); 410 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 411 sdp->sd_file->ifl_name, 412 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype), 413 ifl->ifl_name, conv_sym_info_type(ofl->ofl_dehdr->e_machine, 414 ntype)); 415 warn++; 416 } else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) { 417 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 418 eprintf(ofl->ofl_lml, ERR_WARNING, 419 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 420 MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name, 421 EC_XWORD(osym->st_size), ifl->ifl_name, 422 EC_XWORD(nsym->st_size)); 423 warn++; 424 } 425 } 426 427 /* 428 * Having provided the user with any necessary warnings, take the 429 * appropriate symbol: 430 * 431 * o if one symbol is from a shared object and the other is from a 432 * relocatable object, take the relocatable objects symbol (the 433 * run-time linker is always going to find the relocatable object 434 * symbol regardless of the binding), else 435 * 436 * o if both symbols are from relocatable objects and one symbol is 437 * weak take the non-weak symbol (two non-weak symbols would have 438 * generated the fatal error condition above unless -z muldefs is 439 * in effect), else 440 * 441 * o take the first symbol definition encountered. 442 */ 443 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 444 if (warn) 445 eprintf(ofl->ofl_lml, ERR_NONE, 446 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 447 return; 448 } else if ((nfile == ET_REL) && ((ofile == ET_DYN) || 449 ((obind == STB_WEAK) && (nbind != STB_WEAK)))) { 450 if (warn) 451 eprintf(ofl->ofl_lml, ERR_NONE, 452 MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name); 453 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 454 return; 455 } else { 456 if (warn) 457 eprintf(ofl->ofl_lml, ERR_NONE, 458 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 459 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 460 return; 461 } 462 } 463 464 /* 465 * Resolve a real and tentative definition. 466 */ 467 static void 468 sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 469 int ndx, Word nshndx, Word nsymflags) 470 { 471 Sym *osym = sdp->sd_sym; 472 unsigned char otype = ELF_ST_TYPE(osym->st_info); 473 unsigned char obind = ELF_ST_BIND(osym->st_info); 474 unsigned char ntype = ELF_ST_TYPE(nsym->st_info); 475 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 476 Boolean otent = FALSE, ntent = FALSE; 477 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 478 Half nfile = ifl->ifl_ehdr->e_type; 479 int warn = 0; 480 Word osymvis = ELF_ST_VISIBILITY(osym->st_other); 481 Word nsymvis = ELF_ST_VISIBILITY(nsym->st_other); 482 483 /* 484 * Special rules for functions. 485 * 486 * o If both definitions are from relocatable objects, have the same 487 * binding (ie. two weaks or two non-weaks), and the real 488 * definition is a function (the other must be tentative), treat 489 * this as a multiply defined symbol error, else 490 * 491 * o if the real symbol definition is a function within a shared 492 * library and the tentative symbol is a relocatable object, and 493 * the tentative is not weak and the function real, then retain the 494 * tentative definition. 495 */ 496 if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) && 497 ((otype == STT_FUNC) || (ntype == STT_FUNC))) { 498 if (ofl->ofl_flags & FLG_OF_MULDEFS) { 499 eprintf(ofl->ofl_lml, ERR_WARNING, 500 MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name)); 501 sym_promote(sdp, nsym, ifl, ofl, ndx, 502 nshndx, nsymflags); 503 } else { 504 eprintf(ofl->ofl_lml, ERR_FATAL, 505 MSG_INTL(MSG_SYM_MULDEF), demangle(sdp->sd_name)); 506 ofl->ofl_flags |= FLG_OF_FATAL; 507 } 508 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 509 sdp->sd_file->ifl_name, 510 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype), 511 ifl->ifl_name, conv_sym_info_type(ofl->ofl_dehdr->e_machine, 512 ntype)); 513 return; 514 } else if (ofile != nfile) { 515 516 517 if ((ofile == ET_DYN) && (otype == STT_FUNC)) { 518 if ((otype != STB_WEAK) && (ntype == STB_WEAK)) 519 return; 520 else { 521 sym_override(sdp, nsym, ifl, ofl, ndx, 522 nshndx, nsymflags); 523 return; 524 } 525 } 526 if ((nfile == ET_DYN) && (ntype == STT_FUNC)) { 527 if ((ntype != STB_WEAK) && (otype == STB_WEAK)) { 528 sym_override(sdp, nsym, ifl, ofl, ndx, 529 nshndx, nsymflags); 530 return; 531 } else 532 return; 533 } 534 } 535 536 if (sdp->sd_flags & FLG_SY_TENTSYM) 537 otent = TRUE; 538 if (nsymflags & FLG_SY_TENTSYM) 539 ntent = TRUE; 540 541 542 /* 543 * Check the symbols type and size. 544 */ 545 if (otype != ntype) { 546 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 547 demangle(sdp->sd_name)); 548 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 549 sdp->sd_file->ifl_name, 550 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype), 551 ifl->ifl_name, conv_sym_info_type(ofl->ofl_dehdr->e_machine, 552 ntype)); 553 warn++; 554 } else if (osym->st_size != nsym->st_size) { 555 /* 556 * If both definitions are from relocatable objects we have a 557 * potential fatal error condition. If the tentative is larger 558 * than the real definition treat this as a multiple definition. 559 * Note that if only one symbol is weak, the non-weak will be 560 * taken. 561 */ 562 if (((ofile == ET_REL) && (nfile == ET_REL) && 563 (obind == nbind)) && 564 ((otent && (osym->st_size > nsym->st_size)) || 565 (ntent && (osym->st_size < nsym->st_size)))) { 566 eprintf(ofl->ofl_lml, ERR_FATAL, 567 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 568 MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name, 569 EC_XWORD(osym->st_size), ifl->ifl_name, 570 EC_XWORD(nsym->st_size)); 571 eprintf(ofl->ofl_lml, ERR_NONE, 572 MSG_INTL(MSG_SYM_TENTERR)); 573 ofl->ofl_flags |= FLG_OF_FATAL; 574 } else { 575 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 576 eprintf(ofl->ofl_lml, ERR_WARNING, 577 MSG_INTL(MSG_SYM_DIFFATTR), 578 demangle(sdp->sd_name), 579 MSG_INTL(MSG_STR_SIZES), 580 sdp->sd_file->ifl_name, 581 EC_XWORD(osym->st_size), 582 ifl->ifl_name, EC_XWORD(nsym->st_size)); 583 warn++; 584 } 585 } 586 } 587 588 /* 589 * Having provided the user with any necessary warnings, take the 590 * appropriate symbol: 591 * 592 * o if the original symbol is from relocatable file and it is 593 * a protected tentative symbol, take the original one. 594 * 595 * o if the original symbol is from shared object and the new 596 * symbol is a protected tentative symbol from a relocatable file, 597 * take the new one. 598 * 599 * o if the original symbol is tentative, and providing the original 600 * symbol isn't strong and the new symbol weak, take the real 601 * symbol, else 602 * 603 * o if the original symbol is weak and the new tentative symbol is 604 * strong take the new symbol. 605 * 606 * Refer to the System V ABI Page 4-27 for a description of the binding 607 * requirements of tentative and weak symbols. 608 */ 609 if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) && 610 (osymvis == STV_PROTECTED)) { 611 return; 612 } 613 614 if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) && 615 (nsymvis == STV_PROTECTED)) { 616 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 617 return; 618 } 619 620 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 621 if (warn) 622 eprintf(ofl->ofl_lml, ERR_NONE, 623 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 624 return; 625 } 626 627 if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) || 628 ((obind == STB_WEAK) && (nbind != STB_WEAK))) { 629 if (warn) 630 eprintf(ofl->ofl_lml, ERR_NONE, 631 MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name); 632 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 633 return; 634 } else { 635 if (warn) 636 eprintf(ofl->ofl_lml, ERR_NONE, 637 MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name); 638 sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 639 return; 640 } 641 } 642 643 /* 644 * Resolve two tentative symbols. 645 */ 646 static void 647 sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 648 int ndx, Word nshndx, Word nsymflags) 649 { 650 Sym *osym = sdp->sd_sym; 651 unsigned char obind = ELF_ST_BIND(osym->st_info); 652 unsigned char nbind = ELF_ST_BIND(nsym->st_info); 653 Half ofile = sdp->sd_file->ifl_ehdr->e_type; 654 Half nfile = ifl->ifl_ehdr->e_type; 655 size_t size = 0; 656 Xword value = 0; 657 658 #if (defined(__i386) || defined(__amd64)) && defined(_ELF64) 659 /* 660 * If original and new are both COMMON but 661 * different size model, take the small one. 662 */ 663 if ((sdp->sd_shndx == SHN_COMMON) && 664 (nshndx == SHN_X86_64_LCOMMON)) { 665 /* 666 * Take the original one. 667 */ 668 return; 669 } else if ((sdp->sd_shndx == SHN_X86_64_LCOMMON) && 670 (nshndx == SHN_COMMON)) { 671 /* 672 * Take the new symbol. 673 */ 674 sym_override(sdp, nsym, ifl, ofl, ndx, 675 nshndx, nsymflags); 676 return; 677 } 678 #endif 679 680 /* 681 * Check the alignment of the symbols. This can only be tested for if 682 * the symbols are not real definitions to a SHT_NOBITS section (ie. 683 * they were originally tentative), as in this case the symbol would 684 * have a displacement value rather than an alignment. In other words 685 * we can only test this for two relocatable objects. 686 */ 687 if ((osym->st_value != nsym->st_value) && 688 ((sdp->sd_flags & FLG_SY_SPECSEC) && 689 (sdp->sd_shndx == SHN_COMMON) && 690 (nsymflags & FLG_SY_SPECSEC) && 691 #if (defined(__i386) || defined(__amd64)) && defined(_ELF64) 692 (nshndx == SHN_COMMON)) || 693 ((sdp->sd_flags & FLG_SY_SPECSEC) && 694 (sdp->sd_shndx == SHN_X86_64_LCOMMON) && 695 (nsymflags & FLG_SY_SPECSEC) && 696 (nshndx == SHN_X86_64_LCOMMON))) { 697 #else 698 (nshndx == SHN_COMMON))) { 699 #endif 700 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 701 const char *file; 702 Xword salign; 703 Xword balign; 704 uint_t alignscompliment; 705 706 if (osym->st_value < nsym->st_value) { 707 salign = osym->st_value; 708 balign = nsym->st_value; 709 } else { 710 salign = nsym->st_value; 711 balign = osym->st_value; 712 } 713 714 /* 715 * If the smaller alignment fits smoothly into the 716 * larger alignment - we take it with no warning. 717 */ 718 if (S_ALIGN(balign, salign) == balign) 719 alignscompliment = 1; 720 else 721 alignscompliment = 0; 722 723 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 724 eprintf(ofl->ofl_lml, ERR_WARNING, 725 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 726 MSG_INTL(MSG_STR_ALIGNMENTS), 727 sdp->sd_file->ifl_name, EC_XWORD(osym->st_value), 728 ifl->ifl_name, EC_XWORD(nsym->st_value)); 729 730 /* 731 * Having provided the necessary warning indicate which 732 * relocatable object we are going to take. 733 * 734 * o if one symbol is weak and the other is non-weak 735 * take the non-weak symbol, else 736 * 737 * o take the largest alignment (as we still have to check 738 * the symbols size simply save the largest value for 739 * updating later). 740 */ 741 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) 742 file = ifl->ifl_name; 743 else if (obind != nbind) 744 file = sdp->sd_file->ifl_name; 745 else { 746 emsg = MSG_INTL(MSG_SYM_LARGER); 747 value = balign; 748 } 749 if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 750 eprintf(ofl->ofl_lml, ERR_NONE, emsg, file); 751 } 752 753 /* 754 * Check the size of the symbols. 755 */ 756 if (osym->st_size != nsym->st_size) { 757 const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 758 const char *file; 759 760 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 761 eprintf(ofl->ofl_lml, ERR_WARNING, 762 MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 763 MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name, 764 EC_XWORD(osym->st_size), ifl->ifl_name, 765 EC_XWORD(nsym->st_size)); 766 767 768 /* 769 * This symbol has already been compared to an SO definition, 770 * as per the runtime behavior, ignore extra definitions. 771 */ 772 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 773 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 774 eprintf(ofl->ofl_lml, ERR_NONE, emsg, 775 sdp->sd_file->ifl_name); 776 return; 777 } 778 779 /* 780 * Having provided the necessary warning indicate what course 781 * of action we are going to take. 782 * 783 * o if the file types differ, take the relocatable object 784 * and apply the largest symbol size, else 785 * o if one symbol is weak and the other is non-weak, take 786 * the non-weak symbol, else 787 * o simply take the largest symbol reference. 788 */ 789 if (nfile != ofile) { 790 if (nfile == ET_REL) { 791 file = ifl->ifl_name; 792 if (osym->st_size > nsym->st_size) { 793 size = (size_t)osym->st_size; 794 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 795 } 796 sym_override(sdp, nsym, ifl, ofl, ndx, 797 nshndx, nsymflags); 798 } else { 799 file = sdp->sd_file->ifl_name; 800 if (osym->st_size < nsym->st_size) { 801 size = (size_t)nsym->st_size; 802 emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 803 } 804 sym_promote(sdp, nsym, ifl, ofl, ndx, 805 nshndx, nsymflags); 806 } 807 } else if (obind != nbind) { 808 if ((obind == STB_WEAK) && (nbind != STB_WEAK)) { 809 sym_override(sdp, nsym, ifl, ofl, ndx, 810 nshndx, nsymflags); 811 file = ifl->ifl_name; 812 } else 813 file = sdp->sd_file->ifl_name; 814 } else { 815 if (osym->st_size < nsym->st_size) { 816 sym_override(sdp, nsym, ifl, ofl, ndx, 817 nshndx, nsymflags); 818 file = ifl->ifl_name; 819 } else 820 file = sdp->sd_file->ifl_name; 821 } 822 if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 823 eprintf(ofl->ofl_lml, ERR_NONE, emsg, file); 824 if (size) 825 sdp->sd_sym->st_size = (Xword)size; 826 } else { 827 /* 828 * If the sizes are the same 829 * 830 * o if the file types differ, take the relocatable object, 831 * else 832 * 833 * o if one symbol is weak and the other is non-weak, take 834 * the non-weak symbol, else 835 * 836 * o take the first reference. 837 */ 838 if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) 839 return; 840 else if (((ofile != nfile) && (nfile == ET_REL)) || 841 (((obind == STB_WEAK) && (nbind != STB_WEAK)) && 842 (!((ofile != nfile) && (ofile == ET_REL))))) 843 sym_override(sdp, nsym, ifl, ofl, ndx, 844 nshndx, nsymflags); 845 else 846 sym_promote(sdp, nsym, ifl, ofl, ndx, 847 nshndx, nsymflags); 848 } 849 850 /* 851 * Enforce the largest alignment if necessary. 852 */ 853 if (value) 854 sdp->sd_sym->st_value = value; 855 } 856 857 /* 858 * Symbol resolution state table. `Action' describes the required 859 * procedure to be called (if any). 860 */ 861 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *, 862 Sym *, Ifl_desc *, Ofl_desc *, int, Word, Word) = { 863 864 /* defined undef tent */ 865 /* ET_REL ET_REL ET_REL */ 866 867 /* 0 defined REF_DYN_SEEN */ sym_tworeals, sym_promote, sym_realtent, 868 /* 1 undef REF_DYN_SEEN */ sym_override, sym_override, sym_override, 869 /* 2 tent REF_DYN_SEEN */ sym_realtent, sym_promote, sym_twotent, 870 /* 3 defined REF_DYN_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 871 /* 4 undef REF_DYN_NEED */ sym_override, sym_override, sym_override, 872 /* 5 tent REF_DYN_NEED */ sym_realtent, sym_typecheck, sym_twotent, 873 /* 6 defined REF_REL_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 874 /* 7 undef REF_REL_NEED */ sym_override, sym_twoundefs, sym_override, 875 /* 8 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent, 876 877 /* defined undef tent */ 878 /* ET_DYN ET_DYN ET_DYN */ 879 880 /* 9 defined REF_DYN_SEEN */ sym_tworeals, sym_null, sym_realtent, 881 /* 10 undef REF_DYN_SEEN */ sym_override, sym_mach_check, sym_override, 882 /* 11 tent REF_DYN_SEEN */ sym_realtent, sym_null, sym_twotent, 883 /* 12 defined REF_DYN_NEED */ sym_tworeals, sym_null, sym_realtent, 884 /* 13 undef REF_DYN_NEED */ sym_override, sym_null, sym_override, 885 /* 14 tent REF_DYN_NEED */ sym_realtent, sym_null, sym_twotent, 886 /* 15 defined REF_REL_NEED */ sym_tworeals, sym_null, sym_realtent, 887 /* 16 undef REF_REL_NEED */ sym_override, sym_mach_check, sym_override, 888 /* 17 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent 889 890 }; 891 892 uintptr_t 893 ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx, 894 Word nshndx, Word nsymflags) 895 { 896 int row, column; /* State table coordinates */ 897 Sym *osym = sdp->sd_sym; 898 Is_desc *isp; 899 Half nfile = ifl->ifl_ehdr->e_type; 900 901 /* 902 * Determine the original symbols definition (defines row in Action[]). 903 */ 904 if (sdp->sd_flags & FLG_SY_TENTSYM) 905 row = SYM_TENTATIVE; 906 else if (sdp->sd_shndx == SHN_UNDEF) 907 row = SYM_UNDEFINED; 908 else 909 row = SYM_DEFINED; 910 911 /* 912 * If the input file is an implicit shared object then we don't need 913 * to bind to any symbols within it other than to verify that any 914 * undefined references will be closed (implicit shared objects are only 915 * processed when no undefined symbols are required as a result of the 916 * link-edit (see process_dynamic())). 917 */ 918 if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) && 919 (row != SYM_UNDEFINED)) 920 return (1); 921 922 /* 923 * Finish computing the Action[] row by applying the symbols reference 924 * together with the input files type. 925 */ 926 row = row + (REF_NUM * sdp->sd_ref); 927 if (nfile == ET_DYN) 928 row += (REF_NUM * SYM_NUM); 929 930 /* 931 * Determine the new symbols definition (defines column in Action[]). 932 */ 933 if ((nsymflags & FLG_SY_SPECSEC) && 934 (nshndx == SHN_COMMON)) { 935 column = SYM_TENTATIVE; 936 nsymflags |= FLG_SY_TENTSYM; 937 #if (defined(__i386) || defined(__amd64)) && defined(_ELF64) 938 } else if ((nsymflags & FLG_SY_SPECSEC) && 939 (nshndx == SHN_X86_64_LCOMMON)) { 940 column = SYM_TENTATIVE; 941 nsymflags |= FLG_SY_TENTSYM; 942 #endif 943 } else if ((nshndx == SHN_UNDEF) || (nshndx == SHN_SUNW_IGNORE)) { 944 column = SYM_UNDEFINED; 945 nshndx = SHN_UNDEF; 946 } else { 947 column = SYM_DEFINED; 948 /* 949 * If the new symbol is from a shared library and it is 950 * associated with a SHT_NOBITS section then this symbol 951 * originated from a tentative symbol. 952 */ 953 if (((nsymflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) { 954 isp = ifl->ifl_isdesc[nshndx]; 955 if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) { 956 column = SYM_TENTATIVE; 957 nsymflags |= FLG_SY_TENTSYM; 958 } 959 } 960 } 961 962 DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column, 963 osym, nsym, sdp, ifl)); 964 965 /* 966 * Record the input filename on the defined files list for possible 967 * later diagnostics. The `sa_dfiles' list is used to maintain the list 968 * of shared objects that define the same symbol. This list is only 969 * generated when the -m option is in effect and is used to list 970 * multiple (interposed) definitions of a symbol (refer to ldmap_out()). 971 */ 972 if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nshndx != SHN_UNDEF) && 973 ((nsymflags & FLG_SY_SPECSEC) == 0)) 974 if (list_appendc(&sdp->sd_aux->sa_dfiles, ifl->ifl_name) == 0) 975 return (S_ERROR); 976 977 /* 978 * Perform the required resolution. 979 */ 980 Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags); 981 982 /* 983 * If the symbol has been resolved to the new input file, and this is 984 * a versioned relocatable object, then the version information of the 985 * new symbol must be promoted to the versioning of the output file. 986 */ 987 if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) && 988 (nshndx != SHN_UNDEF)) 989 ld_vers_promote(sdp, ndx, ifl, ofl); 990 991 /* 992 * Determine whether a mapfile reference has been satisfied. Mapfile 993 * symbol references augment symbols that should be contributed from 994 * the relocatable objects used to build the output image. If a 995 * relocatable object doesn't provide one of the mapfile symbol 996 * references then somethings amiss, and will be flagged during symbol 997 * validation. 998 */ 999 if ((nfile == ET_REL) && ((sdp->sd_flags & 1000 (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) { 1001 /* 1002 * Extern and parent references are satisfied by references from 1003 * a relocatable object. Note that we let *any* symbol type 1004 * satisfy this reference, to be as flexible as possible with 1005 * user written mapfiles. It could be questionable, for 1006 * example, if what a user expects to be an extern reference is 1007 * actually found to be a definition in a relocatable object. 1008 * 1009 * Any other mapfile reference (typically for versioning 1010 * information) simply augments a relocatables definition. 1011 */ 1012 if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) || 1013 ((sdp->sd_shndx != SHN_UNDEF) && 1014 (sdp->sd_ref == REF_REL_NEED))) 1015 sdp->sd_flags |= FLG_SY_MAPUSED; 1016 } 1017 1018 DBG_CALL(Dbg_syms_resolved(ofl, sdp)); 1019 1020 return (1); 1021 } 1022