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