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