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