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 2010 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 /* 31 * Map file parsing (Shared Support Code). 32 */ 33 #include <stdio.h> 34 #include <errno.h> 35 #include "msg.h" 36 #include "_libld.h" 37 #include "_map.h" 38 39 /* 40 * Given a NULL terminated array of structures of arbitrary type, where 41 * each struct contains (among other fields) a character pointer field 42 * giving that struct a unique name, return the address of the struct 43 * that matches the given name. 44 * 45 * entry: 46 * name - "Keyword" name to be found. 47 * array - Base address of array 48 * name_offset - Offset of the name field within the struct 49 * type used by this array, as generated via 50 * SGSOFFSETOF(). 51 * elt_size - sizeof the basic array element type 52 * 53 * exit: 54 * Using a case insensitive comparison, name is compared to the 55 * name of each element of the array. The address of the first 56 * match found is returned. If the desired name is not found, 57 * NULL is returned. 58 * 59 * note: 60 * This routine is completely type-unsafe. The upside is that this 61 * single routine is able to search arrays of arbitrary type, leaving 62 * the caller free to structure their array in any way that is convenient 63 * to solve the problem at hand. 64 */ 65 #ifndef _ELF64 66 void * 67 ld_map_kwfind(const char *name, void *array, size_t name_offset, 68 size_t elt_size) 69 { 70 for (; ; array = elt_size + (char *)array) { 71 /* LINTED E_BAD_PTR_CAST_ALIGN */ 72 const char *arr_name = *((const char **) 73 (name_offset + (const char *) array)); 74 75 if (arr_name == NULL) 76 return (NULL); 77 78 if (strcasecmp(name, arr_name) == 0) 79 return (array); 80 } 81 82 /*NOTREACHED*/ 83 assert(0); 84 return (NULL); 85 } 86 #endif 87 88 /* 89 * Given the same NULL terminated array accepted by ld_map_kwfind(), format 90 * the strings into a comma separated list of names. 91 * 92 * entry: 93 * array - Base address of array 94 * name_offset - Offset of the name field within the struct 95 * type used by this array, as generated via 96 * SGSOFFSETOF(). 97 * elt_size - sizeof the basic array element type 98 * buf - Buffer to receive output 99 * bufsize - sizeof(buf) 100 * 101 * exit: 102 * As many of the names as will fit are formatted into buf. If all the 103 * names do not fit, the remainder are quietly clipped. The caller must 104 * ensure that there is sufficient room. buf is returned, for convenience 105 * in using this function as an argument for printing. 106 */ 107 #ifndef _ELF64 108 char * 109 ld_map_kwnames(void *array, size_t name_offset, size_t elt_size, char *buf, 110 size_t bufsize) 111 { 112 size_t cnt = 0; 113 size_t len; 114 char *str = buf; 115 116 for (; bufsize > 1; array = elt_size + (char *)array, cnt++) { 117 /* LINTED E_BAD_PTR_CAST_ALIGN */ 118 const char *arr_name = *((const char **) 119 (name_offset + (const char *) array)); 120 121 if (arr_name == NULL) 122 break; 123 124 if (cnt > 0) { 125 if (bufsize < 3) 126 break; 127 *str++ = ','; 128 *str++ = ' '; 129 bufsize -= 2; 130 *(str + 1) = '\0'; 131 } 132 133 len = strlcpy(str, arr_name, bufsize); 134 if (len >= bufsize) 135 break; 136 str += len; 137 bufsize -= len; 138 } 139 140 return (buf); 141 } 142 #endif 143 144 /* 145 * Create a pseudo input file descriptor to represent the specified Mapfile. 146 * An input descriptor is required any time a symbol is generated. 147 * 148 * entry: 149 * mf - Mapfile descriptor. 150 * 151 * exit: 152 * If an input descriptor was already created for this mapfile 153 * by a previous call, it is returned. Otherwise, a new descriptor 154 * is created, entered into the mapfile descriptor, and returned. 155 * 156 * Success is indicated by a non-NULL return value, failure by NULL. 157 */ 158 Ifl_desc * 159 ld_map_ifl(Mapfile *mf) 160 { 161 Ifl_desc *ifl; 162 163 /* 164 * If we've already created a pseudo input descriptor for this 165 * mapfile, reuse it. 166 */ 167 if (mf->mf_ifl != NULL) 168 return (mf->mf_ifl); 169 170 if ((ifl = libld_calloc(sizeof (Ifl_desc), 1)) == NULL) 171 return (NULL); 172 ifl->ifl_name = mf->mf_name; 173 ifl->ifl_flags = (FLG_IF_MAPFILE | FLG_IF_NEEDED | FLG_IF_FILEREF); 174 if ((ifl->ifl_ehdr = libld_calloc(sizeof (Ehdr), 1)) == NULL) 175 return (NULL); 176 ifl->ifl_ehdr->e_type = ET_REL; 177 178 if (aplist_append(&mf->mf_ofl->ofl_objs, ifl, AL_CNT_OFL_OBJS) == NULL) 179 return (NULL); 180 181 mf->mf_ifl = ifl; 182 return (mf->mf_ifl); 183 } 184 185 /* 186 * Given a capability tag type, set the override bit in the output descriptor. 187 * This prevents the use of capability values of that type from the input 188 * objects. 189 */ 190 void 191 ld_map_cap_set_ovflag(Mapfile *mf, Word type) 192 { 193 /* 194 * Map capability tag to the corresponding output descriptor 195 * override flag. 196 */ 197 static ofl_flag_t override_flag[CA_SUNW_NUM] = { 198 0, /* CA_SUNW_NULL */ 199 FLG_OF1_OVHWCAP1, /* CA_SUNW_HW_1 */ 200 FLG_OF1_OVSFCAP1, /* CA_SUNW_SF_1 */ 201 FLG_OF1_OVHWCAP2, /* CA_SUNW_HW_2 */ 202 FLG_OF1_OVPLATCAP, /* CA_SUNW_PLAT */ 203 FLG_OF1_OVMACHCAP, /* CA_SUNW_MACH */ 204 FLG_OF1_OVIDCAP /* CA_SUNW_ID */ 205 }; 206 #if CA_SUNW_NUM != (CA_SUNW_ID + 1) 207 #error "CA_SUNW_NUM has grown" 208 #endif 209 mf->mf_ofl->ofl_flags1 |= override_flag[type]; 210 } 211 212 /* 213 * Sanity check the given capability bitmask. 214 */ 215 Boolean 216 ld_map_cap_sanitize(Mapfile *mf, Word type, Capmask *capmask) 217 { 218 elfcap_mask_t mask; 219 220 switch (type) { 221 case CA_SUNW_SF_1: 222 /* 223 * Unlike hardware capabilities, we do not allow setting 224 * software capability bits that do not have known definitions. 225 * Software capability tokens have to be validated as a unit 226 * as the bits can affect each others meaning (see sf1_cap() 227 * in files.c). 228 */ 229 if ((mask = (capmask->cm_val & ~SF1_SUNW_MASK)) != 0) { 230 mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1), 231 EC_XWORD(mask)); 232 capmask->cm_val &= SF1_SUNW_MASK; 233 } 234 if ((capmask->cm_val & 235 (SF1_SUNW_FPKNWN | SF1_SUNW_FPUSED)) == SF1_SUNW_FPUSED) { 236 mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1), 237 EC_XWORD(SF1_SUNW_FPUSED)); 238 capmask->cm_val &= ~SF1_SUNW_FPUSED; 239 } 240 #if !defined(_ELF64) 241 /* 242 * The SF1_SUNW_ADDR32 software capability is only meaningful 243 * when building a 64-bit object. Warn the user, and remove the 244 * setting, if we're building a 32-bit object. 245 */ 246 if (capmask->cm_val & SF1_SUNW_ADDR32) { 247 mf_warn0(mf, MSG_INTL(MSG_MAP_INADDR32SF1)); 248 capmask->cm_val &= ~SF1_SUNW_ADDR32; 249 } 250 #endif 251 } 252 253 return (TRUE); 254 } 255 256 /* 257 * Return the shared object control definition structure (ofl_socntl) 258 * for the specified object, creating one if necessary. 259 * 260 * entry: 261 * mf - Mapfile descriptor 262 * obj_name - Name of object 263 * 264 * exit: 265 * Returns the pointer to the definition structure, or NULL on error. 266 */ 267 Sdf_desc * 268 ld_map_dv(Mapfile *mf, const char *obj_name) 269 { 270 Sdf_desc *sdf; 271 272 /* 273 * If a shared object definition for this file already exists use it, 274 * otherwise allocate a new descriptor. 275 */ 276 if ((sdf = sdf_find(obj_name, mf->mf_ofl->ofl_socntl)) == NULL) { 277 if ((sdf = sdf_add(obj_name, &mf->mf_ofl->ofl_socntl)) == 278 (Sdf_desc *)S_ERROR) 279 return (NULL); 280 sdf->sdf_rfile = mf->mf_name; 281 } 282 283 DBG_CALL(Dbg_map_dv(mf->mf_ofl->ofl_lml, sdf->sdf_name, 284 mf->mf_lineno)); 285 return (sdf); 286 } 287 288 289 Boolean 290 ld_map_dv_entry(Mapfile *mf, Sdf_desc *sdf, Boolean require, 291 const char *version) 292 { 293 Sdv_desc sdv; 294 295 sdv.sdv_name = version; 296 sdv.sdv_ref = mf->mf_name; 297 sdv.sdv_flags = 0; 298 299 300 if (require) { 301 /* 302 * Add a VERNEED entry for the specified version 303 * from this object: 304 * 305 * MapfileVersion Syntax 306 * ---------------------------------------- 307 * 1 obj - $ADDVERS=version; 308 * 2 DEPENDENCY obj { REQUIRE=version }; 309 */ 310 sdf->sdf_flags |= FLG_SDF_ADDVER; 311 312 if (alist_append(&sdf->sdf_verneed, &sdv, sizeof (Sdv_desc), 313 AL_CNT_SDF_VERSIONS) == NULL) 314 return (FALSE); 315 } else { /* Allow */ 316 /* 317 * Allow linking to symbols found in this version, or 318 * from the versions it inherits from. 319 * 320 * MapfileVersion Syntax 321 * ---------------------------------------- 322 * 1 obj - version; 323 * 2 DEPENDENCY obj { ALLOW=version }; 324 */ 325 sdf->sdf_flags |= FLG_SDF_SELECT; 326 327 if (alist_append(&sdf->sdf_vers, &sdv, sizeof (Sdv_desc), 328 AL_CNT_SDF_VERSIONS) == NULL) 329 return (FALSE); 330 } 331 332 DBG_CALL(Dbg_map_dv_entry(mf->mf_ofl->ofl_lml, mf->mf_lineno, 333 require, version)); 334 335 return (TRUE); 336 } 337 338 /* 339 * Given a segment descriptor, return its index. 340 * 341 * entry: 342 * mf - Mapfile descriptor 343 * sgp - Segment for which index is desired 344 * 345 * exit: 346 * Index of segment is returned. 347 */ 348 Xword 349 ld_map_seg_index(Mapfile *mf, Sg_desc *sgp) 350 { 351 Aliste idx; 352 Sg_desc *sgp2; 353 Ofl_desc *ofl = mf->mf_ofl; 354 355 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2)) 356 if (sgp == sgp2) 357 break; 358 359 return (idx); 360 } 361 362 /* 363 * Add a section name to the output section sort list for the given 364 * segment. 365 * 366 * entry: 367 * mf - Mapfile descriptor 368 * sgp - Segment in question 369 * sec_name - Name of section to be added. 370 * 371 * exit: 372 * Returns TRUE for success, FALSE for failure. 373 */ 374 Boolean 375 ld_map_seg_os_order_add(Mapfile *mf, Sg_desc *sgp, const char *sec_name) 376 { 377 Aliste idx; 378 Sec_order *scop; 379 380 /* 381 * Make sure it's not already on the list 382 */ 383 for (ALIST_TRAVERSE(sgp->sg_os_order, idx, scop)) 384 if (strcmp(scop->sco_secname, sec_name) == 0) { 385 mf_fatal(mf, MSG_INTL(MSG_MAP_DUP_OS_ORD), sec_name); 386 return (FALSE); 387 } 388 389 390 scop = alist_append(&sgp->sg_os_order, NULL, sizeof (Sec_order), 391 AL_CNT_SG_SECORDER); 392 if (scop == NULL) 393 return (FALSE); 394 395 scop->sco_secname = sec_name; 396 397 DBG_CALL(Dbg_map_seg_os_order(mf->mf_ofl->ofl_lml, sgp, sec_name, 398 alist_nitems(sgp->sg_os_order), mf->mf_lineno)); 399 400 /* 401 * Output section ordering is a relatively expensive operation, 402 * and one that is generally not used. In order to avoid needless 403 * work, the FLG_OF_OS_ORDER must be set when it will be needed. 404 * The section we just added needs this flag to be set. However, 405 * it is possible that a subsequent mapfile directive may come 406 * along and clear the order list, making it unnecessary. 407 * 408 * Instead of setting it here, we do a final pass over the segments 409 * in ld_map_finalize() and set it there if a segment with sorting 410 * requirements is seen. 411 */ 412 413 return (TRUE); 414 } 415 416 /* 417 * Add a size symbol to a segment 418 * 419 * entry: 420 * mf - Mapfile descriptor 421 * sgp - Segment descriptor 422 * eq_tol - Type of assignment: TK_EQUAL, or TK_PLUSEQ 423 * symname - Name of symbol. Must be in stable static storage 424 * that can be retained. 425 * 426 * exit: 427 * On success, the symbol has been added and TRUE is returned. 428 * Otherwise an error is reported and FALSE is returned. 429 */ 430 Boolean 431 ld_map_seg_size_symbol(Mapfile *mf, Sg_desc *sgp, Token eq_tok, 432 const char *symname) 433 { 434 Sym *sym; /* New symbol pointer */ 435 Sym_desc *sdp; /* New symbol node pointer */ 436 Ifl_desc *ifl; /* Dummy input file structure */ 437 avl_index_t where; 438 Ofl_desc *ofl = mf->mf_ofl; 439 440 /* 441 * We don't allow resetting the list of size symbols, so if the 442 * operator is TK_EQUAL and the list is not empty, issue an error. 443 * 444 * If we want to lift this restriction, we would have to save the 445 * size symbols and enter them from ld_map_post_process(). Doing that 446 * well would require a significant overhead in saved error reporting 447 * state, and interactions with the same symbols created by symbol 448 * directives. As size symbols are of little practical use, and are 449 * maintained primarily for backward compatibility with SysV, we have 450 * decided not to do that, but to create the symbols as the mapfiles 451 * are processed, and to disallow later attempts to remove them. 452 */ 453 if ((eq_tok == TK_EQUAL) && (aplist_nitems(sgp->sg_sizesym) > 0)) { 454 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGSIZE), sgp->sg_name); 455 return (FALSE); 456 } 457 458 /* 459 * Make sure we have a pseudo file descriptor to associate to the 460 * symbol. 461 */ 462 if ((ifl = ld_map_ifl(mf)) == NULL) 463 return (FALSE); 464 465 /* 466 * Make sure the symbol doesn't already exist. It is possible that the 467 * symbol has been scoped or versioned, in which case it does exist 468 * but we can freely update it here. 469 */ 470 if ((sdp = ld_sym_find(symname, SYM_NOHASH, &where, ofl)) == NULL) { 471 Word hval; 472 473 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL) 474 return (FALSE); 475 sym->st_shndx = SHN_ABS; 476 sym->st_size = 0; 477 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 478 479 DBG_CALL(Dbg_map_size_new(ofl->ofl_lml, symname, 480 sgp->sg_name, mf->mf_lineno)); 481 /* LINTED */ 482 hval = (Word)elf_hash(symname); 483 if ((sdp = ld_sym_enter(symname, sym, hval, ifl, ofl, 0, 484 SHN_ABS, (FLG_SY_SPECSEC | FLG_SY_GLOBREF), &where)) == 485 (Sym_desc *)S_ERROR) 486 return (FALSE); 487 sdp->sd_flags &= ~FLG_SY_CLEAN; 488 DBG_CALL(Dbg_map_symbol(ofl, sdp)); 489 } else { 490 sym = sdp->sd_sym; 491 492 if (sym->st_shndx == SHN_UNDEF) { 493 sdp->sd_shndx = sym->st_shndx = SHN_ABS; 494 sdp->sd_flags |= FLG_SY_SPECSEC; 495 sym->st_size = 0; 496 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 497 498 sdp->sd_flags &= ~FLG_SY_MAPREF; 499 500 DBG_CALL(Dbg_map_size_old(ofl, sdp, 501 sgp->sg_name, mf->mf_lineno)); 502 } else { 503 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1), 504 demangle(sdp->sd_name), sdp->sd_file->ifl_name, 505 MSG_INTL(MSG_MAP_DIFF_SYMMUL)); 506 return (FALSE); 507 } 508 } 509 510 /* 511 * Assign the symbol to the segment. 512 */ 513 if (aplist_append(&sgp->sg_sizesym, sdp, AL_CNT_SG_SIZESYM) == NULL) 514 return (FALSE); 515 516 return (TRUE); 517 } 518 519 /* 520 * Allocate a zeroed segment descriptor. 521 * 522 * exit: 523 * Returns pointer to the descriptor on success, NULL on failure. 524 * The contents of the returned descriptor have been zeroed. 525 * The returned descriptor is not added to the segment list 526 * (ofl_segs). That is done using ld_map_seg_insert(). 527 */ 528 Sg_desc * 529 ld_map_seg_alloc(const char *name, Word p_type, sg_flags_t sg_flags) 530 { 531 Sg_desc *sgp; 532 533 if ((sgp = libld_calloc(sizeof (Sg_desc), 1)) == NULL) 534 return (NULL); 535 sgp->sg_phdr.p_type = p_type; 536 sgp->sg_name = name; 537 sgp->sg_flags = sg_flags; 538 539 return (sgp); 540 } 541 542 /* 543 * Return the PT_SUNWSTACK segment descriptor from the ofl_segs list. 544 * This segment is part of the default set and cannot be removed, so 545 * this routine will always succeed. 546 * 547 * exit: 548 * The descriptor is located, a DBG_STATE_MOD_BEFORE debug 549 * message issued, the FLG_SG_DISABLED flag is cleared, and the 550 * descriptor pointer returned. 551 */ 552 Sg_desc * 553 ld_map_seg_stack(Mapfile *mf) 554 { 555 Ofl_desc *ofl = mf->mf_ofl; 556 Sg_desc *sgp; 557 Aliste idx; 558 559 /* 560 * The stack is established by exec(), using the executable's program 561 * headers, before any sharable objects are loaded. If there is a 562 * PT_SUNWSTACK program header, exec() will act on it. As such, stack 563 * program headers are normally only applicable to executables. 564 * 565 * However, ELF allows a sharable object with an interpreter to 566 * be executed directly, and in this extremely rare case, the 567 * PT_SUNWSTACK program header would have meaning. Rather than 568 * second guess user intent, we simply create it on demand for any 569 * dynamic object, trusting that the user has a good reason for it. 570 */ 571 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp)) 572 if (sgp->sg_phdr.p_type == PT_SUNWSTACK) { 573 DBG_CALL(Dbg_map_seg(mf->mf_ofl, DBG_STATE_MOD_BEFORE, 574 idx, sgp, mf->mf_lineno)); 575 sgp->sg_flags &= ~FLG_SG_DISABLED; 576 return (sgp); 577 } 578 579 /*NOTREACHED*/ 580 return (NULL); 581 } 582 583 /* 584 * Finish the initialization of a new segment descriptor allocated by 585 * ld_map_seg_alloc(), and enter it into the segment list. 586 * 587 * entry: 588 * mf - Mapfile descriptor 589 * seg_type - One of DBG_SEG_NEW or DBG_SEG_NEW_IMPLICIT 590 * ins_head - If TRUE, the new segment goes at the front of 591 * others of its type. If FALSE, it goes at the end. 592 * sgp - Segment descriptor to enter. 593 * where - Insertion point, initialized by a previous (failed) call to 594 * ld_seg_lookup(). Ignored if the segment has a NULL sg_name. 595 * 596 * exit: 597 * On success, returns SEG_INS_OK. A non-fatal error is indicated with 598 * a return value of SEG_INS_SKIP, in which case the descriptor is 599 * not entered, but the user is expected to discard it and continue 600 * running. On failure, returns SEG_INS_FAIL. 601 * 602 * note: 603 * This routine will modify the contents of the descriptor referenced 604 * by sgp_tmpl before allocating the new descriptor. The caller must 605 * not expect it to be unmodified. 606 */ 607 ld_map_seg_ins_t 608 ld_map_seg_insert(Mapfile *mf, dbg_state_t dbg_state, Sg_desc *sgp, 609 avl_index_t where) 610 { 611 Ofl_desc *ofl = mf->mf_ofl; 612 Aliste idx; 613 Sg_desc *sgp2; /* temp segment descriptor pointer */ 614 int ins_head; 615 Xword sg_ndx; 616 617 /* 618 * If specific fields have not been supplied via 619 * map_equal(), make sure defaults are supplied. 620 */ 621 if (((sgp->sg_flags & FLG_SG_P_TYPE) == 0) && 622 (sgp->sg_phdr.p_type == PT_NULL)) { 623 /* 624 * Default to a loadable segment. 625 */ 626 sgp->sg_phdr.p_type = PT_LOAD; 627 sgp->sg_flags |= FLG_SG_P_TYPE; 628 } 629 if (sgp->sg_phdr.p_type == PT_LOAD) { 630 if ((sgp->sg_flags & FLG_SG_P_FLAGS) == 0) { 631 /* 632 * Default to read/write and execute. 633 */ 634 sgp->sg_phdr.p_flags = PF_R + PF_W + PF_X; 635 sgp->sg_flags |= FLG_SG_P_FLAGS; 636 } 637 if ((sgp->sg_flags & FLG_SG_P_ALIGN) == 0) { 638 /* 639 * Default to segment alignment 640 */ 641 sgp->sg_phdr.p_align = ld_targ.t_m.m_segm_align; 642 sgp->sg_flags |= FLG_SG_P_ALIGN; 643 } 644 } 645 646 /* 647 * Determine where the new item should be inserted in 648 * the segment descriptor list. 649 */ 650 switch (sgp->sg_phdr.p_type) { 651 case PT_LOAD: 652 if (sgp->sg_flags & FLG_SG_EMPTY) 653 sgp->sg_id = SGID_TEXT_EMPTY; 654 else 655 sgp->sg_id = SGID_TEXT; 656 break; 657 case PT_NULL: 658 if (sgp->sg_flags & FLG_SG_EMPTY) 659 sgp->sg_id = SGID_NULL_EMPTY; 660 else 661 sgp->sg_id = SGID_NULL; 662 break; 663 case PT_NOTE: 664 sgp->sg_id = SGID_NOTE; 665 break; 666 default: 667 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGTYP), 668 EC_WORD(sgp->sg_phdr.p_type)); 669 return (SEG_INS_FAIL); 670 } 671 672 /* 673 * Add the descriptor to the segment list. In the v1 syntax, 674 * new sections are added at the head of their type, while in 675 * the newer syntax, they go at the end of their type. 676 */ 677 sg_ndx = 0; 678 ins_head = (mf->mf_version == MFV_SYSV); 679 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2)) { 680 if (ins_head) { /* Insert before the others of its type */ 681 if (sgp->sg_id > sgp2->sg_id) { 682 sg_ndx++; 683 continue; 684 } 685 } else { /* Insert after the others of its type */ 686 if (sgp->sg_id >= sgp2->sg_id) { 687 sg_ndx++; 688 continue; 689 } 690 } 691 break; 692 } 693 if (aplist_insert(&ofl->ofl_segs, sgp, AL_CNT_SEGMENTS, idx) == NULL) 694 return (SEG_INS_FAIL); 695 if (sgp->sg_name != NULL) 696 avl_insert(&ofl->ofl_segs_avl, sgp, where); 697 698 DBG_CALL(Dbg_map_seg(ofl, dbg_state, sg_ndx, sgp, mf->mf_lineno)); 699 return (SEG_INS_OK); 700 } 701 702 /* 703 * Add an entrance criteria record for the specified segment 704 * 705 * entry: 706 * mf - Mapfile descriptor 707 * sgp - Segment for which a new entrance criteria record is needed 708 * name - NULL, or name by which the entrance criteria can be referenced. 709 * 710 * exit: 711 * On success, a pointer to the new entrace criteria record is 712 * returned, the contents of which have been zeroed. On failure, 713 * NULL is returned. 714 */ 715 Ent_desc * 716 ld_map_seg_ent_add(Mapfile *mf, Sg_desc *sgp, const char *name) 717 { 718 Ent_desc *enp; 719 avl_index_t where; 720 Ofl_desc *ofl = mf->mf_ofl; 721 722 if ((name != NULL) && 723 (ld_ent_lookup(mf->mf_ofl, name, &where) != NULL)) { 724 mf_fatal(mf, MSG_INTL(MSG_MAP_DUPNAMENT), name); 725 return (NULL); 726 } 727 728 /* Allocate and initialize the entrace criteria descriptor */ 729 if ((enp = libld_calloc(1, sizeof (*enp))) == NULL) 730 return (NULL); 731 enp->ec_name = name; 732 enp->ec_segment = sgp; /* Tie criteria to segment */ 733 734 735 /* 736 * Insert into the APlist. The mf_ec_insndx field for each mapfile 737 * starts at 0, and is incremented with each insertion. This means 738 * that the entrance criteria for each mapfile go to the head of 739 * the list, but that within a single mapfile, they are inserted in 740 * the order they are seen. 741 */ 742 if (aplist_insert(&ofl->ofl_ents, enp, AL_CNT_OFL_ENTRANCE, 743 mf->mf_ec_insndx) == NULL) 744 return (NULL); 745 mf->mf_ec_insndx++; 746 747 /* 748 * If the entrance criteria is named insert it into the AVL tree 749 * as well. This provides O(logN) lookups by name. 750 */ 751 if (name != NULL) 752 avl_insert(&ofl->ofl_ents_avl, enp, where); 753 754 return (enp); 755 } 756 757 Boolean 758 ld_map_seg_ent_files(Mapfile *mf, Ent_desc *enp, Word ecf_type, const char *str) 759 { 760 Ent_desc_file edf; 761 762 /* 763 * The v1 sysv syntax can let an empty string get in, consisting of 764 * just a '*' where the '*' is interpreted as 'basename'. 765 */ 766 if (str[0] == '\0') { 767 mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM)); 768 return (FALSE); 769 } 770 771 /* Basename or objname string must not contain a path separator (/) */ 772 if ((ecf_type != TYP_ECF_PATH) && (strchr(str, '/') != NULL)) { 773 const char *msg = (ecf_type == TYP_ECF_BASENAME) ? 774 MSG_INTL(MSG_MAP_BADBNAME) : MSG_INTL(MSG_MAP_BADONAME); 775 776 mf_fatal(mf, msg, str); 777 return (FALSE); 778 } 779 780 edf.edf_flags = ecf_type; 781 edf.edf_name = str; 782 edf.edf_name_len = strlen(edf.edf_name); 783 784 /* Does it have an archive member suffix? */ 785 if ((edf.edf_name[edf.edf_name_len - 1] == ')') && 786 (strrchr(edf.edf_name, '(') != NULL)) 787 edf.edf_flags |= FLG_ECF_ARMEMBER; 788 789 if (alist_append(&enp->ec_files, &edf, sizeof (edf), 790 AL_CNT_EC_FILES) == NULL) 791 return (FALSE); 792 793 /* 794 * Note that an entrance criteria requiring file name matching exists 795 * in the system. This is used by ld_place_path_info_init() to 796 * skip Place_pathinfo initialization in cases where there are 797 * no entrance criteria that will use the results. 798 */ 799 mf->mf_ofl->ofl_flags |= FLG_OF_EC_FILES; 800 801 return (TRUE); 802 } 803 804 /* 805 * Prepare an ld_map_ver_t structure for a new mapfile defined version. 806 * 807 * exit: 808 * Returns TRUE for success, FALSE for failure. 809 */ 810 Boolean 811 ld_map_sym_ver_init(Mapfile *mf, char *name, ld_map_ver_t *mv) 812 { 813 Word hash; 814 Ofl_desc *ofl = mf->mf_ofl; 815 816 mv->mv_name = name; 817 mv->mv_scope = FLG_SCOPE_DFLT; 818 mv->mv_errcnt = 0; 819 820 /* 821 * If we're generating segments within the image then any symbol 822 * reductions will be processed (ie. applied to relocations and symbol 823 * table entries). Otherwise (when creating a relocatable object) any 824 * versioning information is simply recorded for use in a later 825 * (segment generating) link-edit. 826 */ 827 if (ofl->ofl_flags & FLG_OF_RELOBJ) 828 ofl->ofl_flags |= FLG_OF_VERDEF; 829 830 /* 831 * If no version descriptors have yet been set up, initialize a base 832 * version to represent the output file itself. This `base' version 833 * catches any internally generated symbols (_end, _etext, etc.) and 834 * serves to initialize the output version descriptor count. 835 */ 836 if (ofl->ofl_vercnt == 0) { 837 if (ld_vers_base(ofl) == (Ver_desc *)S_ERROR) 838 return (FALSE); 839 } 840 841 /* 842 * If this definition has an associated version name then generate a 843 * new version descriptor and an associated version symbol index table. 844 */ 845 if (name) { 846 ofl->ofl_flags |= FLG_OF_VERDEF; 847 848 /* 849 * Traverse the present version descriptor list to see if there 850 * is already one of the same name, otherwise create a new one. 851 */ 852 /* LINTED */ 853 hash = (Word)elf_hash(name); 854 if (((mv->mv_vdp = ld_vers_find(name, hash, 855 ofl->ofl_verdesc)) == NULL) && 856 ((mv->mv_vdp = ld_vers_desc(name, hash, 857 &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR)) 858 return (FALSE); 859 860 /* 861 * Initialize any new version with an index, the file from 862 * which it was first referenced, and a WEAK flag (indicates 863 * that there are no symbols assigned to it yet). 864 */ 865 if (mv->mv_vdp->vd_ndx == 0) { 866 /* LINTED */ 867 mv->mv_vdp->vd_ndx = (Half)++ofl->ofl_vercnt; 868 mv->mv_vdp->vd_file = ld_map_ifl(mf); 869 mv->mv_vdp->vd_flags = VER_FLG_WEAK; 870 } 871 } else { 872 /* 873 * If a version definition hasn't been specified assign any 874 * symbols to the base version. 875 */ 876 mv->mv_vdp = (Ver_desc *)ofl->ofl_verdesc->apl_data[0]; 877 } 878 879 return (TRUE); 880 } 881 882 /* 883 * Change the current scope for the given version. 884 * 885 * entry: 886 * mf - Mapfile descriptor 887 * scope_name - Name for new scope 888 * mv - Information related to version being defined 889 * 890 * exit: 891 * On success, mv is updated to change the current scope. 892 * On failure, mv->errcnt is incremented, and mv is otherwise unaltered. 893 */ 894 void 895 ld_map_sym_scope(Mapfile *mf, const char *scope_name, ld_map_ver_t *mv) 896 { 897 typedef struct { 898 const char *name; /* scope keyword string */ 899 ld_map_scope_t type; /* Resulting type */ 900 ofl_flag_t ofl_flags; /* 0, or ofl flags to add */ 901 } scope_t; 902 903 /* 904 * Valid symbol scope keywords 905 * 906 * All symbols added by a mapfile are actually global entries, and 907 * are assigned the scope that is presently in effect. 908 * 909 * If a protected/symbolic scope is detected, remember this. If 910 * a protected/symbolic scope is the only scope defined in this 911 * (or any other mapfiles), then the mode -Bsymbolic is established. 912 */ 913 static scope_t scope_list[] = { 914 { MSG_ORIG(MSG_MAPKW_DEFAULT), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB }, 915 { MSG_ORIG(MSG_MAPKW_ELIMINATE), FLG_SCOPE_ELIM, 0 }, 916 { MSG_ORIG(MSG_MAPKW_EXPORTED), FLG_SCOPE_EXPT, 0 }, 917 { MSG_ORIG(MSG_MAPKW_HIDDEN), FLG_SCOPE_HIDD, 0 }, 918 { MSG_ORIG(MSG_MAPKW_GLOBAL), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB }, 919 { MSG_ORIG(MSG_MAPKW_LOCAL), FLG_SCOPE_HIDD, 0 }, 920 { MSG_ORIG(MSG_MAPKW_PROTECTED), 921 FLG_SCOPE_PROT, FLG_OF_MAPSYMB }, 922 { MSG_ORIG(MSG_MAPKW_SINGLETON), 923 FLG_SCOPE_SNGL, FLG_OF_MAPGLOB }, 924 { MSG_ORIG(MSG_MAPKW_SYMBOLIC), 925 FLG_SCOPE_PROT, FLG_OF_MAPSYMB }, 926 927 /* List must be null terminated */ 928 { 0 } 929 }; 930 931 /* 932 * Size of buffer needed to format the names in scope_list[]. Must 933 * be kept in sync with scope_list. 934 */ 935 static size_t scope_list_bufsize = 936 KW_NAME_SIZE(MSG_MAPKW_DEFAULT) + 937 KW_NAME_SIZE(MSG_MAPKW_ELIMINATE) + 938 KW_NAME_SIZE(MSG_MAPKW_EXPORTED) + 939 KW_NAME_SIZE(MSG_MAPKW_HIDDEN) + 940 KW_NAME_SIZE(MSG_MAPKW_GLOBAL) + 941 KW_NAME_SIZE(MSG_MAPKW_LOCAL) + 942 KW_NAME_SIZE(MSG_MAPKW_PROTECTED) + 943 KW_NAME_SIZE(MSG_MAPKW_SINGLETON) + 944 KW_NAME_SIZE(MSG_MAPKW_SYMBOLIC); 945 946 scope_t *scope; 947 948 scope = ld_map_kwfind(scope_name, scope_list, 949 SGSOFFSETOF(scope_t, name), sizeof (scope_list[0])); 950 if (scope == NULL) { 951 char buf[VLA_SIZE(scope_list_bufsize)]; 952 953 mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMSCOPE), 954 ld_map_kwnames(scope_list, SGSOFFSETOF(scope_t, name), 955 sizeof (scope[0]), buf, scope_list_bufsize), scope_name); 956 mv->mv_errcnt++; 957 return; 958 } 959 960 mv->mv_scope = scope->type; 961 mf->mf_ofl->ofl_flags |= scope->ofl_flags; 962 } 963 964 /* 965 * Process the special auto-reduction directive ('*'). It can be specified 966 * in hidden/local, and eliminate scope. This directive indicates that all 967 * symbols processed that are not explicitly defined to be global are to be 968 * reduced to hidden/local scope in, or eliminated from, the output image. 969 * 970 * An auto-reduction directive also implies that a version definition must 971 * be created, as the user has effectively defined an interface. 972 */ 973 void 974 ld_map_sym_autoreduce(Mapfile *mf, ld_map_ver_t *mv) 975 { 976 switch (mv->mv_scope) { 977 case FLG_SCOPE_HIDD: 978 mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOLCL); 979 break; 980 case FLG_SCOPE_ELIM: 981 mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOELM); 982 break; 983 default: 984 /* 985 * Auto reduction has been applied to a scope that doesn't 986 * support it. This should be a fatal error, but we limit 987 * it to a warning for version 1 mapfiles. For years, we 988 * quietly ignored this case, so there may be mapfiles in 989 * production use that we do not wish to break. 990 */ 991 if (mf->mf_version == 1) { 992 mf_warn0(mf, MSG_INTL(MSG_MAP_BADAUTORED)); 993 } else { 994 mf_fatal0(mf, MSG_INTL(MSG_MAP_BADAUTORED)); 995 mv->mv_errcnt++; 996 } 997 } 998 } 999 1000 /* 1001 * Add a standard or auxiliary filter to the given symbol 1002 * 1003 * entry: 1004 * mf - Mapfile descriptor 1005 * mv - Information related to version being defined 1006 * ms - Information related to symbol being defined 1007 * dft_flag - One of FLG_SY_STDFLTR or FLG_SY_AUXFLTR, 1008 * specifying the type of filter. 1009 * filtee - String giving filtee to be added 1010 * 1011 * exit: 1012 * On success, the filtee is added. On failure, mv->errcnt is 1013 * incremented, and mv/ms are otherwise unaltered. 1014 */ 1015 void 1016 ld_map_sym_filtee(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms, 1017 Word dft_flag, const char *filtee) 1018 { 1019 /* 1020 * A given symbol can only be tied to a single filter, be it 1021 * a standard filter, or auxiliary. 1022 */ 1023 if (ms->ms_filtee) { 1024 mf_fatal0(mf, MSG_INTL(MSG_MAP_MULTFILTEE)); 1025 mv->mv_errcnt++; 1026 return; 1027 } 1028 1029 /* Symbol filtering is only for sharable objects */ 1030 if (!(mf->mf_ofl->ofl_flags & FLG_OF_SHAROBJ)) { 1031 mf_fatal0(mf, MSG_INTL(MSG_MAP_FLTR_ONLYAVL)); 1032 mv->mv_errcnt++; 1033 return; 1034 } 1035 1036 ms->ms_filtee = filtee; 1037 ms->ms_dft_flag = dft_flag; 1038 ms->ms_sdflags |= dft_flag; 1039 mf->mf_ofl->ofl_flags |= FLG_OF_SYMINFO; 1040 } 1041 1042 /* 1043 * Enter a mapfile defined symbol into the given version 1044 * 1045 * entry: 1046 * mf - Mapfile descriptor 1047 * ms - Information related to symbol being added to version 1048 * 1049 * exit: 1050 * On success, returns TRUE. On failure that requires an immediate 1051 * halt, returns FALSE. 1052 * 1053 * On failure that requires eventual halt, but for which it would 1054 * be OK to continue parsing in hopes of flushing out additional 1055 * problems, increments mv->mv_errcnt, and returns TRUE. 1056 */ 1057 Boolean 1058 ld_map_sym_enter(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms) 1059 { 1060 Ofl_desc *ofl = mf->mf_ofl; 1061 Word hash; 1062 avl_index_t where; 1063 Sym *sym; 1064 Sym_desc *sdp; 1065 const char *conflict; 1066 1067 /* 1068 * Add the new symbol. It should be noted that all 1069 * symbols added by the mapfile start out with global 1070 * scope, thus they will fall through the normal symbol 1071 * resolution process. Symbols defined as locals will 1072 * be reduced in scope after all input file processing. 1073 */ 1074 /* LINTED */ 1075 hash = (Word)elf_hash(ms->ms_name); 1076 DBG_CALL(Dbg_map_version(ofl->ofl_lml, mv->mv_name, ms->ms_name, 1077 mv->mv_scope)); 1078 if ((sdp = ld_sym_find(ms->ms_name, hash, &where, ofl)) == NULL) { 1079 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL) 1080 return (FALSE); 1081 1082 /* 1083 * Make sure any parent or external declarations 1084 * fall back to references. 1085 */ 1086 if (ms->ms_sdflags & (FLG_SY_PARENT | FLG_SY_EXTERN)) { 1087 /* 1088 * Turn it into a reference by setting 1089 * the section index to UNDEF. 1090 */ 1091 sym->st_shndx = ms->ms_shndx = SHN_UNDEF; 1092 1093 /* 1094 * It is wrong to specify size or value for an 1095 * external symbol. 1096 */ 1097 if (ms->ms_value_set || (ms->ms_size != 0)) { 1098 mf_fatal0(mf, MSG_INTL(MSG_MAP_NOEXVLSZ)); 1099 mv->mv_errcnt++; 1100 return (TRUE); 1101 } 1102 } else { 1103 sym->st_shndx = (Half)ms->ms_shndx; 1104 } 1105 1106 sym->st_value = ms->ms_value; 1107 sym->st_size = ms->ms_size; 1108 sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type); 1109 1110 if ((sdp = ld_sym_enter(ms->ms_name, sym, hash, 1111 ld_map_ifl(mf), ofl, 0, ms->ms_shndx, ms->ms_sdflags, 1112 &where)) == (Sym_desc *)S_ERROR) 1113 return (FALSE); 1114 1115 sdp->sd_flags &= ~FLG_SY_CLEAN; 1116 1117 /* 1118 * Identify any references. FLG_SY_MAPREF is 1119 * turned off once a relocatable object with 1120 * the same symbol is found, thus the existence 1121 * of FLG_SY_MAPREF at symbol validation is 1122 * used to flag undefined/misspelled entries. 1123 */ 1124 if (sym->st_shndx == SHN_UNDEF) 1125 sdp->sd_flags |= (FLG_SY_MAPREF | FLG_SY_GLOBREF); 1126 1127 } else { 1128 conflict = NULL; 1129 sym = sdp->sd_sym; 1130 1131 /* 1132 * If this symbol already exists, make sure this 1133 * definition doesn't conflict with the former. 1134 * Provided it doesn't, multiple definitions 1135 * from different mapfiles can augment each 1136 * other. 1137 */ 1138 /* BEGIN CSTYLED */ 1139 if (sym->st_value) { 1140 if (ms->ms_value && (sym->st_value != ms->ms_value)) 1141 conflict = MSG_INTL(MSG_MAP_DIFF_SYMVAL); 1142 } else { 1143 sym->st_value = ms->ms_value; 1144 } 1145 if (sym->st_size) { 1146 if (ms->ms_size && (sym->st_size != ms->ms_size)) 1147 conflict = MSG_INTL(MSG_MAP_DIFF_SYMSZ); 1148 } else { 1149 sym->st_size = ms->ms_size; 1150 } 1151 if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) { 1152 if ((ms->ms_type != STT_NOTYPE) && 1153 (ELF_ST_TYPE(sym->st_info) != ms->ms_type)) 1154 conflict = MSG_INTL(MSG_MAP_DIFF_SYMTYP); 1155 } else { 1156 sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type); 1157 } 1158 if (sym->st_shndx != SHN_UNDEF) { 1159 if ((ms->ms_shndx != SHN_UNDEF) && 1160 (sym->st_shndx != ms->ms_shndx)) 1161 conflict = MSG_INTL(MSG_MAP_DIFF_SYMNDX); 1162 } else { 1163 sym->st_shndx = sdp->sd_shndx = ms->ms_shndx; 1164 } 1165 /* END CSTYLED */ 1166 1167 if ((sdp->sd_flags & MSK_SY_GLOBAL) && 1168 (sdp->sd_aux->sa_overndx != VER_NDX_GLOBAL) && 1169 (mv->mv_vdp->vd_ndx != VER_NDX_GLOBAL) && 1170 (sdp->sd_aux->sa_overndx != mv->mv_vdp->vd_ndx)) { 1171 conflict = MSG_INTL(MSG_MAP_DIFF_SYMVER); 1172 } 1173 1174 if (conflict) { 1175 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1), 1176 demangle(ms->ms_name), 1177 sdp->sd_file->ifl_name, conflict); 1178 mv->mv_errcnt++; 1179 return (TRUE); 1180 } 1181 1182 /* 1183 * If this mapfile entry supplies a definition, 1184 * indicate that the symbol is now used. 1185 */ 1186 if (ms->ms_shndx != SHN_UNDEF) 1187 sdp->sd_flags |= FLG_SY_MAPUSED; 1188 } 1189 1190 /* 1191 * A symbol declaration that defines a size but no 1192 * value is processed as a request to create an 1193 * associated backing section. The intent behind this 1194 * functionality is to provide OBJT definitions within 1195 * filters that are not ABS. ABS symbols don't allow 1196 * copy-relocations to be established to filter OBJT 1197 * definitions. 1198 */ 1199 if ((ms->ms_shndx == SHN_ABS) && ms->ms_size && !ms->ms_value_set) { 1200 /* Create backing section if not there */ 1201 if (sdp->sd_isc == NULL) { 1202 Is_desc *isp; 1203 1204 if (ms->ms_type == STT_OBJECT) { 1205 if ((isp = ld_make_data(ofl, ms->ms_size)) == 1206 (Is_desc *)S_ERROR) 1207 return (FALSE); 1208 } else { 1209 if ((isp = ld_make_text(ofl, ms->ms_size)) == 1210 (Is_desc *)S_ERROR) 1211 return (FALSE); 1212 } 1213 1214 sdp->sd_isc = isp; 1215 isp->is_file = ld_map_ifl(mf); 1216 } 1217 1218 /* 1219 * Now that backing storage has been created, 1220 * associate the symbol descriptor. Remove the 1221 * symbols special section tag so that it will 1222 * be assigned the correct section index as part 1223 * of update symbol processing. 1224 */ 1225 sdp->sd_flags &= ~FLG_SY_SPECSEC; 1226 ms->ms_sdflags &= ~FLG_SY_SPECSEC; 1227 } 1228 1229 /* 1230 * Indicate the new symbols scope. Although the 1231 * symbols st_other field will eventually be updated as 1232 * part of writing out the final symbol, update the 1233 * st_other field here to trigger better diagnostics 1234 * during symbol validation (for example, undefined 1235 * references that are defined symbolic in a mapfile). 1236 */ 1237 if (mv->mv_scope == FLG_SCOPE_HIDD) { 1238 /* 1239 * This symbol needs to be reduced to local. 1240 */ 1241 if (ofl->ofl_flags & FLG_OF_REDLSYM) { 1242 sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM); 1243 sdp->sd_sym->st_other = STV_ELIMINATE; 1244 } else { 1245 sdp->sd_flags |= FLG_SY_HIDDEN; 1246 sdp->sd_sym->st_other = STV_HIDDEN; 1247 } 1248 } else if (mv->mv_scope == FLG_SCOPE_ELIM) { 1249 /* 1250 * This symbol needs to be eliminated. Note, 1251 * the symbol is also tagged as local to trigger 1252 * any necessary relocation processing prior 1253 * to the symbol being eliminated. 1254 */ 1255 sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM); 1256 sdp->sd_sym->st_other = STV_ELIMINATE; 1257 1258 } else { 1259 /* 1260 * This symbol is explicitly defined to remain 1261 * global. 1262 */ 1263 sdp->sd_flags |= ms->ms_sdflags; 1264 1265 /* 1266 * Qualify any global scope. 1267 */ 1268 if (mv->mv_scope == FLG_SCOPE_SNGL) { 1269 sdp->sd_flags |= (FLG_SY_SINGLE | FLG_SY_NDIR); 1270 sdp->sd_sym->st_other = STV_SINGLETON; 1271 } else if (mv->mv_scope == FLG_SCOPE_PROT) { 1272 sdp->sd_flags |= FLG_SY_PROTECT; 1273 sdp->sd_sym->st_other = STV_PROTECTED; 1274 } else if (mv->mv_scope == FLG_SCOPE_EXPT) { 1275 sdp->sd_flags |= FLG_SY_EXPORT; 1276 sdp->sd_sym->st_other = STV_EXPORTED; 1277 } else 1278 sdp->sd_flags |= FLG_SY_DEFAULT; 1279 1280 /* 1281 * Record the present version index for later 1282 * potential versioning. 1283 */ 1284 if ((sdp->sd_aux->sa_overndx == 0) || 1285 (sdp->sd_aux->sa_overndx == VER_NDX_GLOBAL)) 1286 sdp->sd_aux->sa_overndx = mv->mv_vdp->vd_ndx; 1287 mv->mv_vdp->vd_flags |= FLG_VER_REFER; 1288 } 1289 1290 conflict = NULL; 1291 1292 /* 1293 * Carry out some validity checks to ensure incompatible 1294 * symbol characteristics have not been defined. 1295 * These checks are carried out after symbols are added 1296 * or resolved, to catch single instance, and 1297 * multi-instance definition inconsistencies. 1298 */ 1299 if ((sdp->sd_flags & (FLG_SY_HIDDEN | FLG_SY_ELIM)) && 1300 ((mv->mv_scope != FLG_SCOPE_HIDD) && 1301 (mv->mv_scope != FLG_SCOPE_ELIM))) { 1302 conflict = MSG_INTL(MSG_MAP_DIFF_SYMLCL); 1303 1304 } else if ((sdp->sd_flags & 1305 (FLG_SY_SINGLE | FLG_SY_EXPORT)) && 1306 ((mv->mv_scope != FLG_SCOPE_DFLT) && 1307 (mv->mv_scope != FLG_SCOPE_EXPT) && 1308 (mv->mv_scope != FLG_SCOPE_SNGL))) { 1309 conflict = MSG_INTL(MSG_MAP_DIFF_SYMGLOB); 1310 1311 } else if ((sdp->sd_flags & FLG_SY_PROTECT) && 1312 ((mv->mv_scope != FLG_SCOPE_DFLT) && 1313 (mv->mv_scope != FLG_SCOPE_PROT))) { 1314 conflict = MSG_INTL(MSG_MAP_DIFF_SYMPROT); 1315 1316 } else if ((sdp->sd_flags & FLG_SY_NDIR) && 1317 (mv->mv_scope == FLG_SCOPE_PROT)) { 1318 conflict = MSG_INTL(MSG_MAP_DIFF_PROTNDIR); 1319 1320 } else if ((sdp->sd_flags & FLG_SY_DIR) && 1321 (mv->mv_scope == FLG_SCOPE_SNGL)) { 1322 conflict = MSG_INTL(MSG_MAP_DIFF_SNGLDIR); 1323 } 1324 1325 if (conflict) { 1326 /* 1327 * Select the conflict message from either a 1328 * single instance or multi-instance definition. 1329 */ 1330 if (sdp->sd_file->ifl_name == mf->mf_name) { 1331 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF2), 1332 demangle(ms->ms_name), conflict); 1333 } else { 1334 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1), 1335 demangle(ms->ms_name), 1336 sdp->sd_file->ifl_name, conflict); 1337 } 1338 mv->mv_errcnt++; 1339 return (TRUE); 1340 } 1341 1342 /* 1343 * Indicate that this symbol has been explicitly 1344 * contributed from a mapfile. 1345 */ 1346 sdp->sd_flags |= (FLG_SY_MAPFILE | FLG_SY_EXPDEF); 1347 1348 /* 1349 * If we've encountered a symbol definition simulate 1350 * that an input file has been processed - this allows 1351 * things like filters to be created purely from a 1352 * mapfile. 1353 */ 1354 if (ms->ms_type != STT_NOTYPE) 1355 ofl->ofl_objscnt++; 1356 DBG_CALL(Dbg_map_symbol(ofl, sdp)); 1357 1358 /* 1359 * If this symbol has an associated filtee, record the 1360 * filtee string and associate the string index with the 1361 * symbol. This is used later to associate the syminfo 1362 * information with the necessary .dynamic entry. 1363 */ 1364 if (ms->ms_filtee) { 1365 Dfltr_desc * dftp; 1366 Sfltr_desc sft; 1367 Aliste idx, _idx, nitems; 1368 1369 /* 1370 * Make sure we don't duplicate any filtee 1371 * strings, and create a new descriptor if 1372 * necessary. 1373 */ 1374 idx = nitems = alist_nitems(ofl->ofl_dtsfltrs); 1375 for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, _idx, dftp)) { 1376 if ((ms->ms_dft_flag != dftp->dft_flag) || 1377 (strcmp(dftp->dft_str, ms->ms_filtee))) 1378 continue; 1379 idx = _idx; 1380 break; 1381 } 1382 if (idx == nitems) { 1383 Dfltr_desc dft; 1384 1385 dft.dft_str = ms->ms_filtee; 1386 dft.dft_flag = ms->ms_dft_flag; 1387 dft.dft_ndx = 0; 1388 1389 /* 1390 * The following append puts the new 1391 * item at the offset contained in 1392 * idx, because we know idx contains 1393 * the index of the next available slot. 1394 */ 1395 if (alist_append(&ofl->ofl_dtsfltrs, &dft, 1396 sizeof (Dfltr_desc), AL_CNT_OFL_DTSFLTRS) == NULL) 1397 return (FALSE); 1398 } 1399 1400 /* 1401 * Create a new filter descriptor for this 1402 * symbol. 1403 */ 1404 sft.sft_sdp = sdp; 1405 sft.sft_idx = idx; 1406 1407 if (alist_append(&ofl->ofl_symfltrs, &sft, sizeof (Sfltr_desc), 1408 AL_CNT_OFL_SYMFLTRS) == NULL) 1409 return (FALSE); 1410 } 1411 1412 return (TRUE); 1413 } 1414 1415 /* 1416 * In both the version 1 and version 2 syntaxes, a version definition 1417 * can have 0 or more inherited versions following the closing '}', 1418 * terminated by a ';'. 1419 * 1420 * Add the inherited names, and return when the terminator is seen. 1421 */ 1422 Boolean 1423 ld_map_sym_ver_fini(Mapfile *mf, ld_map_ver_t *mv) 1424 { 1425 Token tok; 1426 ld_map_tkval_t tkv; /* Value of token */ 1427 Boolean done = FALSE; 1428 Conv_inv_buf_t inv_buf; 1429 const char *name; 1430 Ver_desc *vdp; 1431 Word hash; 1432 1433 /* 1434 * Read version names until we encounter the ';' terminator. 1435 */ 1436 while (!done) { 1437 switch (tok = ld_map_gettoken(mf, 0, &tkv)) { 1438 case TK_ERROR: 1439 return (FALSE); 1440 1441 case TK_STRING: 1442 name = tkv.tkv_str; 1443 1444 /* The unnamed global scope can't inherit */ 1445 if (mv->mv_vdp->vd_ndx == VER_NDX_GLOBAL) { 1446 mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXINHERIT), 1447 name); 1448 return (FALSE); 1449 } 1450 1451 /* 1452 * Generate a new version descriptor if it doesn't 1453 * already exist. 1454 */ 1455 /* LINTED */ 1456 hash = (Word)elf_hash(name); 1457 vdp = ld_vers_find(name, hash, mf->mf_ofl->ofl_verdesc); 1458 if ((vdp == NULL) && ((vdp = ld_vers_desc(name, hash, 1459 &mf->mf_ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR)) 1460 return (FALSE); 1461 1462 /* 1463 * Add the new version descriptor to the parent version 1464 * descriptors reference list. Indicate the version 1465 * descriptors first reference (used for error diags 1466 * if undefined version dependencies remain). 1467 */ 1468 if (ld_vers_find(name, hash, mv->mv_vdp->vd_deps) == 1469 NULL) 1470 if (aplist_append(&mv->mv_vdp->vd_deps, vdp, 1471 AL_CNT_VERDESCS) == NULL) 1472 return (FALSE); 1473 1474 if (vdp->vd_ref == NULL) 1475 vdp->vd_ref = mv->mv_vdp; 1476 break; 1477 1478 case TK_SEMICOLON: 1479 done = TRUE; 1480 break; 1481 1482 default: 1483 mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMEND), 1484 ld_map_tokenstr(tok, &tkv, &inv_buf)); 1485 return (FALSE); 1486 } 1487 } 1488 1489 return (TRUE); 1490 } 1491