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