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 (Original SysV syntax). 32 */ 33 #include <string.h> 34 #include <strings.h> 35 #include <stdio.h> 36 #include <unistd.h> 37 #include <errno.h> 38 #include <limits.h> 39 #include <ctype.h> 40 #include <elfcap.h> 41 #include <debug.h> 42 #include "msg.h" 43 #include "_libld.h" 44 #include "_map.h" 45 46 47 /* 48 * Process a hardware/software capabilities segment declaration definition. 49 * hwcap_1 = val,... [ OVERRIDE ] 50 * sfcap_1 = val,... [ OVERRIDE ] 51 * 52 * The values can be defined as a list of machine specify tokens, or numerics. 53 * Tokens are representations of the sys/auxv_$MACH.h capabilities, for example: 54 * 55 * #define AV_386_FPU 0x0001 is represented as FPU 56 * #define AV_386_TSC 0x0002 " " " " TSC 57 * 58 * Or, the above two capabilities could be represented as V0x3. Note, the 59 * OVERRIDE flag is used to ensure that only those values provided via this 60 * mapfile entry are recorded in the final image, ie. this overrides any 61 * hardware capabilities that may be defined in the objects read as part of this 62 * link-edit. Specifying: 63 * 64 * V0x0 OVERRIDE 65 * 66 * effectively removes any capabilities information from the final image. 67 */ 68 static Boolean 69 map_cap(Mapfile *mf, Word type, CapMask *capmask) 70 { 71 Token tok; /* Current token. */ 72 Xword number; 73 int used = 0; 74 Ofl_desc *ofl = mf->mf_ofl; 75 ld_map_tkval_t tkv; /* Value of token */ 76 elfcap_mask_t value = 0; 77 78 if (DBG_ENABLED) { 79 Dbg_cap_mapfile_title(ofl->ofl_lml, mf->mf_lineno); 80 Dbg_cap_entry2(ofl->ofl_lml, DBG_STATE_CURRENT, CA_SUNW_HW_1, 81 capmask, ld_targ.t_m.m_mach); 82 } 83 84 while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) != 85 TK_SEMICOLON) { 86 if (tok != TK_STRING) { 87 if (tok != TK_ERROR) 88 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT)); 89 return (FALSE); 90 } 91 92 /* 93 * First, determine if the token represents the reserved 94 * OVERRIDE keyword. 95 */ 96 if (strncmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_OVERRIDE), 97 MSG_MAP_OVERRIDE_SIZE) == 0) { 98 ld_map_cap_set_ovflag(mf, type); 99 used++; 100 continue; 101 } 102 103 /* Is the token a symbolic capability name? */ 104 if ((number = (Xword)elfcap_tag_from_str(ELFCAP_STYLE_LC, 105 type, tkv.tkv_str, ld_targ.t_m.m_mach)) != 0) { 106 value |= number; 107 used++; 108 continue; 109 } 110 111 /* 112 * Is the token a numeric value? 113 */ 114 if (tkv.tkv_str[0] == 'v') { 115 if (ld_map_strtoxword(&tkv.tkv_str[1], NULL, 116 &number) != STRTOXWORD_OK) { 117 mf_fatal(mf, MSG_INTL(MSG_MAP_BADCAPVAL), 118 tkv.tkv_str); 119 return (FALSE); 120 } 121 value |= number; 122 used++; 123 continue; 124 } 125 126 /* 127 * We have an unknown token. 128 */ 129 used++; 130 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKCAPATTR), tkv.tkv_str); 131 return (FALSE); 132 } 133 134 /* Catch empty declarations */ 135 if (used == 0) { 136 mf_warn0(mf, MSG_INTL(MSG_MAP_EMPTYCAP)); 137 return (TRUE); 138 } 139 140 Dbg_cap_entry(ofl->ofl_lml, DBG_STATE_NEW, type, value, 141 ld_targ.t_m.m_mach); 142 capmask->cm_value |= value; 143 144 /* Sanity check the resulting bits */ 145 if (!ld_map_cap_sanitize(mf, type, capmask)) 146 return (FALSE); 147 148 DBG_CALL(Dbg_cap_entry2(ofl->ofl_lml, DBG_STATE_RESOLVED, type, 149 capmask, ld_targ.t_m.m_mach)); 150 151 return (TRUE); 152 } 153 154 /* 155 * Parse the flags for a segment definition. Called by map_equal(). 156 * 157 * entry: 158 * mf - Mapfile descriptor 159 * sgp - Segment being defined 160 * b_flags - Address of b_flags variable from map_equal(). 161 * *bflags is TRUE if flags have already been seen in, the 162 * current segment definition directive, and FALSE otherwise. 163 * flag_tok - Flags string, starting with the '?' character. 164 * 165 * exit: 166 * On success, the flags have been parsed and the segment updated, 167 * *b_flags is set to TRUE, and TRUE is returned. On error, FALSE 168 * is returned. 169 */ 170 static Boolean 171 map_equal_flags(Mapfile *mf, Sg_desc *sgp, Boolean *b_flags, 172 const char *flag_tok) 173 { 174 Word tmp_flags = 0; 175 176 if (*b_flags) { 177 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 178 MSG_INTL(MSG_MAP_SEGFLAG)); 179 return (FALSE); 180 } 181 182 /* Skip over the leading '?' character */ 183 flag_tok++; 184 185 /* 186 * If ? has nothing following leave the flags cleared, 187 * otherwise OR in any flags specified. 188 */ 189 while (*flag_tok) { 190 switch (*flag_tok) { 191 case 'r': 192 tmp_flags |= PF_R; 193 break; 194 case 'w': 195 tmp_flags |= PF_W; 196 break; 197 case 'x': 198 tmp_flags |= PF_X; 199 break; 200 case 'e': 201 sgp->sg_flags |= FLG_SG_EMPTY; 202 break; 203 case 'o': 204 /* 205 * The version 1 ?O option is incompatible with 206 * the version 2 SEGMENT IS_ORDER attribute. 207 */ 208 if (aplist_nitems(sgp->sg_is_order) > 0) { 209 mf_fatal(mf, MSG_INTL(MSG_MAP_ISORDVER), 210 sgp->sg_name); 211 return (FALSE); 212 } 213 214 /* 215 * Set FLG_SG_IS_ORDER to indicate that segment has 216 * had the ?O flag set by a version 1 mapfile. 217 */ 218 sgp->sg_flags |= FLG_SG_IS_ORDER; 219 break; 220 case 'n': 221 /* 222 * If segment ends up as the first loadable segment, 223 * it will not include the the ELF and program headers. 224 */ 225 sgp->sg_flags |= FLG_SG_NOHDR; 226 break; 227 default: 228 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGFLG), *flag_tok); 229 return (FALSE); 230 } 231 flag_tok++; 232 } 233 234 /* 235 * Warn when changing flags except when we're adding or removing "X" 236 * from a RW PT_LOAD segment. 237 */ 238 if ((sgp->sg_flags & FLG_SG_P_FLAGS) && 239 (sgp->sg_phdr.p_flags != tmp_flags) && 240 !(sgp->sg_phdr.p_type == PT_LOAD && 241 (tmp_flags & (PF_R|PF_W)) == (PF_R|PF_W) && 242 (tmp_flags ^ sgp->sg_phdr.p_flags) == PF_X)) 243 mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT), 244 MSG_INTL(MSG_MAP_SEGFLAG), sgp->sg_name); 245 246 sgp->sg_flags |= FLG_SG_P_FLAGS; 247 sgp->sg_phdr.p_flags = tmp_flags; 248 *b_flags = TRUE; 249 250 return (TRUE); 251 } 252 253 /* 254 * Read an address (value) or size Xword from a TK_STRING token value 255 * where the first letter of the string is a letter ('v', 'l', 's', ...) 256 * followed by the numeric value. 257 * 258 * entry: 259 * mf - Mapfile descriptor 260 * tkv - TK_STRING token to parse 261 * value - Address of variable to receive the resulting value. 262 * 263 * exit: 264 * Returns TRUE for success. On failure, issues an error message 265 * and returns FALSE. 266 */ 267 static Boolean 268 valuetoxword(Mapfile *mf, ld_map_tkval_t *tkv, Xword *value) 269 { 270 switch (ld_map_strtoxword(&tkv->tkv_str[1], NULL, value)) { 271 case STRTOXWORD_OK: 272 return (TRUE); 273 274 case STRTOXWORD_TOOBIG: 275 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str, 276 MSG_INTL(MSG_MAP_EXCLIMIT)); 277 break; 278 default: 279 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str, 280 MSG_INTL(MSG_MAP_NOBADFRM)); 281 break; 282 } 283 284 return (FALSE); 285 } 286 287 /* 288 * Process a mapfile segment declaration definition. 289 * segment_name = segment_attribute; 290 * segment_attribute : segment_type segment_flags virtual_addr 291 * physical_addr length alignment 292 */ 293 static Boolean 294 map_equal(Mapfile *mf, Sg_desc *sgp) 295 { 296 /* 297 * Segment type. Users are permitted to define PT_LOAD, 298 * PT_NOTE, PT_SUNWSTACK and PT_NULL segments. Other segment 299 * types are only defined in seg_desc[]. 300 */ 301 typedef struct { 302 const char *name; /* Name for segment type */ 303 Word p_type; /* PT_ constant corresponding to name */ 304 sg_flags_t sg_flags; /* Seg descriptor flags to apply */ 305 } seg_types_t; 306 307 static seg_types_t seg_type_arr[] = { 308 { MSG_ORIG(MSG_MAP_LOAD), PT_LOAD, FLG_SG_P_TYPE }, 309 { MSG_ORIG(MSG_MAP_STACK), PT_SUNWSTACK, 310 FLG_SG_P_TYPE | FLG_SG_EMPTY }, 311 { MSG_ORIG(MSG_MAP_NULL), PT_NULL, FLG_SG_P_TYPE }, 312 { MSG_ORIG(MSG_MAP_NOTE), PT_NOTE, FLG_SG_P_TYPE }, 313 314 /* Array must be NULL terminated */ 315 { NULL } 316 }; 317 318 319 seg_types_t *seg_type; 320 Token tok; /* Current token. */ 321 ld_map_tkval_t tkv; /* Value of token */ 322 Boolean b_type = FALSE; /* True if seg types found. */ 323 Boolean b_flags = FALSE; /* True if seg flags found. */ 324 Boolean b_len = FALSE; /* True if seg length found. */ 325 Boolean b_round = FALSE; /* True if seg rounding found. */ 326 Boolean b_vaddr = FALSE; /* True if seg virtual addr found. */ 327 Boolean b_paddr = FALSE; /* True if seg physical addr found. */ 328 Boolean b_align = FALSE; /* True if seg alignment found. */ 329 330 while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) != 331 TK_SEMICOLON) { 332 if (tok != TK_STRING) { 333 if (tok != TK_ERROR) 334 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT)); 335 return (FALSE); 336 } 337 338 /* 339 * If it is the name of a segment type, set the type 340 * and flags fields in the descriptor. 341 */ 342 for (seg_type = seg_type_arr; seg_type->name; seg_type++) { 343 if (strcmp(tkv.tkv_str, seg_type->name) == 0) { 344 if (b_type) { 345 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 346 MSG_INTL(MSG_MAP_SEGTYP)); 347 return (FALSE); 348 } 349 if ((sgp->sg_flags & FLG_SG_P_TYPE) && 350 (sgp->sg_phdr.p_type != seg_type->p_type)) { 351 mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT), 352 MSG_INTL(MSG_MAP_SEGTYP), 353 sgp->sg_name); 354 } 355 356 sgp->sg_phdr.p_type = seg_type->p_type; 357 sgp->sg_flags |= seg_type->sg_flags; 358 break; 359 } 360 } 361 if (seg_type->name != NULL) /* Matched segment type */ 362 continue; /* next token */ 363 364 /* Segment Flags */ 365 if (*tkv.tkv_str == '?') { 366 if (!map_equal_flags(mf, sgp, &b_flags, tkv.tkv_str)) 367 return (FALSE); 368 continue; /* next token */ 369 } 370 371 372 /* Segment address, length, alignment or rounding number */ 373 if ((tkv.tkv_str[0] == 'l') || (tkv.tkv_str[0] == 'v') || 374 (tkv.tkv_str[0] == 'a') || (tkv.tkv_str[0] == 'p') || 375 (tkv.tkv_str[0] == 'r')) { 376 Xword number; 377 378 if (!valuetoxword(mf, &tkv, &number)) 379 return (FALSE); 380 381 switch (*tkv.tkv_str) { 382 case 'l': 383 if (b_len) { 384 mf_fatal(mf, 385 MSG_INTL(MSG_MAP_MOREONCE), 386 MSG_INTL(MSG_MAP_SEGLEN)); 387 return (FALSE); 388 } 389 if ((sgp->sg_flags & FLG_SG_LENGTH) && 390 (sgp->sg_length != number)) 391 mf_warn(mf, 392 MSG_INTL(MSG_MAP_REDEFATT), 393 MSG_INTL(MSG_MAP_SEGLEN), 394 sgp->sg_name); 395 sgp->sg_length = number; 396 sgp->sg_flags |= FLG_SG_LENGTH; 397 b_len = TRUE; 398 break; 399 case 'r': 400 if (b_round) { 401 mf_fatal(mf, 402 MSG_INTL(MSG_MAP_MOREONCE), 403 MSG_INTL(MSG_MAP_SEGROUND)); 404 return (FALSE); 405 } 406 if ((sgp->sg_flags & FLG_SG_ROUND) && 407 (sgp->sg_round != number)) 408 mf_warn(mf, 409 MSG_INTL(MSG_MAP_REDEFATT), 410 MSG_INTL(MSG_MAP_SEGROUND), 411 sgp->sg_name); 412 sgp->sg_round = number; 413 sgp->sg_flags |= FLG_SG_ROUND; 414 b_round = TRUE; 415 break; 416 case 'v': 417 if (b_vaddr) { 418 mf_fatal(mf, 419 MSG_INTL(MSG_MAP_MOREONCE), 420 MSG_INTL(MSG_MAP_SEGVADDR)); 421 return (FALSE); 422 } 423 if ((sgp->sg_flags & FLG_SG_P_VADDR) && 424 (sgp->sg_phdr.p_vaddr != number)) 425 mf_warn(mf, 426 MSG_INTL(MSG_MAP_REDEFATT), 427 MSG_INTL(MSG_MAP_SEGVADDR), 428 sgp->sg_name); 429 /* LINTED */ 430 sgp->sg_phdr.p_vaddr = (Addr)number; 431 sgp->sg_flags |= FLG_SG_P_VADDR; 432 b_vaddr = TRUE; 433 break; 434 case 'p': 435 if (b_paddr) { 436 mf_fatal(mf, 437 MSG_INTL(MSG_MAP_MOREONCE), 438 MSG_INTL(MSG_MAP_SEGPHYS)); 439 return (FALSE); 440 } 441 if ((sgp->sg_flags & FLG_SG_P_PADDR) && 442 (sgp->sg_phdr.p_paddr != number)) 443 mf_warn(mf, 444 MSG_INTL(MSG_MAP_REDEFATT), 445 MSG_INTL(MSG_MAP_SEGPHYS), 446 sgp->sg_name); 447 /* LINTED */ 448 sgp->sg_phdr.p_paddr = (Addr)number; 449 sgp->sg_flags |= FLG_SG_P_PADDR; 450 b_paddr = TRUE; 451 break; 452 case 'a': 453 if (b_align) { 454 mf_fatal(mf, 455 MSG_INTL(MSG_MAP_MOREONCE), 456 MSG_INTL(MSG_MAP_SEGALIGN)); 457 return (FALSE); 458 } 459 if ((sgp->sg_flags & FLG_SG_P_ALIGN) && 460 (sgp->sg_phdr.p_align != number)) 461 mf_warn(mf, 462 MSG_INTL(MSG_MAP_REDEFATT), 463 MSG_INTL(MSG_MAP_SEGALIGN), 464 sgp->sg_name); 465 /* LINTED */ 466 sgp->sg_phdr.p_align = (Xword)number; 467 sgp->sg_flags |= FLG_SG_P_ALIGN; 468 b_align = TRUE; 469 break; 470 } 471 472 continue; /* next token */ 473 } 474 475 /* 476 * If we reach the bottom of this loop, we have an 477 * unrecognized token. 478 */ 479 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGATT), tkv.tkv_str); 480 return (FALSE); 481 } 482 483 /* 484 * Empty segments can be used to define PT_LOAD segment reservations, or 485 * to reserve PT_NULL program headers. 486 * 487 * PT_LOAD reservations are only allowed within executables, as the 488 * reservation must be established through exec() as part of initial 489 * process loading. In addition, PT_LOAD reservations must have an 490 * associated address and size. Note: This is an obsolete feature, 491 * not supported by the newer mapfile syntax. 492 * 493 * PT_NULL program headers are established for later use by applications 494 * such as the post-optimizer. PT_NULL headers should have no other 495 * attributes assigned. 496 */ 497 if ((sgp->sg_flags & FLG_SG_EMPTY) && 498 (sgp->sg_phdr.p_type != PT_SUNWSTACK)) { 499 500 /* 501 * Any style of empty segment should have no permissions. 502 */ 503 if (sgp->sg_phdr.p_flags != 0) { 504 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGEMNOPERM), 505 EC_WORD(sgp->sg_phdr.p_flags)); 506 return (FALSE); 507 } 508 509 if (sgp->sg_phdr.p_type == PT_LOAD) { 510 if ((mf->mf_ofl->ofl_flags & FLG_OF_EXEC) == 0) { 511 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPEXE)); 512 return (FALSE); 513 } 514 if ((sgp->sg_flags & 515 (FLG_SG_LENGTH | FLG_SG_P_VADDR)) != 516 (FLG_SG_LENGTH | FLG_SG_P_VADDR)) { 517 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPATT)); 518 return (FALSE); 519 } 520 } else if (sgp->sg_phdr.p_type == PT_NULL) { 521 if ((sgp->sg_flags & 522 (FLG_SG_LENGTH | FLG_SG_P_VADDR)) && 523 ((sgp->sg_length != 0) || 524 (sgp->sg_phdr.p_vaddr != 0))) { 525 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPNOATT)); 526 return (FALSE); 527 } 528 } else { 529 mf_warn0(mf, MSG_INTL(MSG_MAP_SEGEMPLOAD)); 530 sgp->sg_phdr.p_type = PT_LOAD; 531 } 532 } 533 534 /* 535 * All segment attributes have now been scanned. Certain flags do not 536 * make sense if this is not a loadable segment, fix if necessary. 537 * Note, if the segment is of type PT_NULL it must be new, and any 538 * defaults will be applied by ld_map_seg_insert(). When clearing an 539 * attribute leave the flag set as an indicator for later entries 540 * re-specifying the same segment. 541 */ 542 if ((sgp->sg_phdr.p_type != PT_NULL) && 543 (sgp->sg_phdr.p_type != PT_LOAD)) { 544 const char *fmt; 545 546 if (sgp->sg_phdr.p_type == PT_SUNWSTACK) 547 fmt = MSG_INTL(MSG_MAP_NOSTACK1); 548 else 549 fmt = MSG_INTL(MSG_MAP_NONLOAD); 550 551 if ((sgp->sg_flags & FLG_SG_P_FLAGS) && 552 (sgp->sg_phdr.p_type != PT_SUNWSTACK)) { 553 if (sgp->sg_phdr.p_flags != 0) { 554 mf_warn(mf, MSG_INTL(MSG_MAP_NONLOAD), 555 MSG_INTL(MSG_MAP_SEGFLAG)); 556 sgp->sg_phdr.p_flags = 0; 557 } 558 } 559 if (sgp->sg_flags & FLG_SG_LENGTH) 560 if (sgp->sg_length != 0) { 561 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGLEN)); 562 sgp->sg_length = 0; 563 } 564 if (sgp->sg_flags & FLG_SG_ROUND) 565 if (sgp->sg_round != 0) { 566 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGROUND)); 567 sgp->sg_round = 0; 568 } 569 if (sgp->sg_flags & FLG_SG_P_VADDR) { 570 if (sgp->sg_phdr.p_vaddr != 0) { 571 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGVADDR)); 572 sgp->sg_phdr.p_vaddr = 0; 573 } 574 } 575 if (sgp->sg_flags & FLG_SG_P_PADDR) 576 if (sgp->sg_phdr.p_paddr != 0) { 577 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGPHYS)); 578 sgp->sg_phdr.p_paddr = 0; 579 } 580 if (sgp->sg_flags & FLG_SG_P_ALIGN) 581 if (sgp->sg_phdr.p_align != 0) { 582 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGALIGN)); 583 sgp->sg_phdr.p_align = 0; 584 } 585 } 586 return (TRUE); 587 } 588 589 590 /* 591 * Process a mapfile mapping directives definition. 592 * 593 * segment_name : section_attribute [ : file_name ] 594 * 595 * Where segment_attribute is one of: section_name section_type section_flags; 596 */ 597 static Boolean 598 map_colon(Mapfile *mf, Ent_desc *enp) 599 { 600 Token tok; 601 ld_map_tkval_t tkv; 602 Boolean b_name = FALSE; 603 Boolean b_type = FALSE; 604 Boolean b_attr = FALSE; 605 Boolean b_bang = FALSE; 606 607 608 /* 609 * Start out assuming that this entrance criteria will be empty, 610 * and therefore match anything. We clear the CATCHALL flag below 611 * if this turns out not to be the case. 612 */ 613 enp->ec_flags |= FLG_EC_CATCHALL; 614 615 while (((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_COLON) && 616 (tok != TK_SEMICOLON)) { 617 if (tok == TK_ERROR) 618 return (FALSE); 619 if (tok != TK_STRING) { 620 mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM)); 621 return (FALSE); 622 } 623 624 /* Segment type. */ 625 626 if (*tkv.tkv_str == '$') { 627 if (b_type) { 628 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 629 MSG_INTL(MSG_MAP_SECTYP)); 630 return (FALSE); 631 } 632 b_type = TRUE; 633 tkv.tkv_str++; 634 ld_map_lowercase(tkv.tkv_str); 635 if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_PROGBITS)) == 636 0) 637 enp->ec_type = SHT_PROGBITS; 638 else if (strcmp(tkv.tkv_str, 639 MSG_ORIG(MSG_STR_SYMTAB)) == 0) 640 enp->ec_type = SHT_SYMTAB; 641 else if (strcmp(tkv.tkv_str, 642 MSG_ORIG(MSG_STR_DYNSYM)) == 0) 643 enp->ec_type = SHT_DYNSYM; 644 else if (strcmp(tkv.tkv_str, 645 MSG_ORIG(MSG_STR_STRTAB)) == 0) 646 enp->ec_type = SHT_STRTAB; 647 else if ((strcmp(tkv.tkv_str, 648 MSG_ORIG(MSG_STR_REL)) == 0) || 649 (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_RELA)) == 0)) 650 enp->ec_type = ld_targ.t_m.m_rel_sht_type; 651 else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_HASH)) == 652 0) 653 enp->ec_type = SHT_HASH; 654 else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_LIB)) == 655 0) 656 enp->ec_type = SHT_SHLIB; 657 else if (strcmp(tkv.tkv_str, 658 MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) 659 enp->ec_type = SHT_DYNAMIC; 660 else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_NOTE)) == 661 0) 662 enp->ec_type = SHT_NOTE; 663 else if (strcmp(tkv.tkv_str, 664 MSG_ORIG(MSG_STR_NOBITS)) == 0) 665 enp->ec_type = SHT_NOBITS; 666 else { 667 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSECTYP), 668 tkv.tkv_str); 669 return (FALSE); 670 } 671 672 enp->ec_flags &= ~FLG_EC_CATCHALL; 673 674 /* 675 * Segment flags. 676 * If a segment flag is specified then the appropriate bit is 677 * set in the ec_attrmask, the ec_attrbits fields determine 678 * whether the attrmask fields must be tested true or false 679 * ie. for ?A the attrmask is set and the attrbit is set, 680 * for ?!A the attrmask is set and the attrbit is clear. 681 */ 682 } else if (*tkv.tkv_str == '?') { 683 if (b_attr) { 684 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 685 MSG_INTL(MSG_MAP_SECFLAG)); 686 return (FALSE); 687 } 688 b_attr = TRUE; 689 b_bang = FALSE; 690 tkv.tkv_str++; 691 ld_map_lowercase(tkv.tkv_str); 692 for (; *tkv.tkv_str != '\0'; tkv.tkv_str++) 693 switch (*tkv.tkv_str) { 694 case '!': 695 if (b_bang) { 696 mf_fatal(mf, 697 MSG_INTL(MSG_MAP_BADFLAG), 698 tkv.tkv_str); 699 return (FALSE); 700 } 701 b_bang = TRUE; 702 break; 703 case 'a': 704 if (enp->ec_attrmask & SHF_ALLOC) { 705 mf_fatal(mf, 706 MSG_INTL(MSG_MAP_BADFLAG), 707 tkv.tkv_str); 708 return (FALSE); 709 } 710 enp->ec_attrmask |= SHF_ALLOC; 711 if (!b_bang) 712 enp->ec_attrbits |= SHF_ALLOC; 713 b_bang = FALSE; 714 break; 715 case 'w': 716 if (enp->ec_attrmask & SHF_WRITE) { 717 mf_fatal(mf, 718 MSG_INTL(MSG_MAP_BADFLAG), 719 tkv.tkv_str); 720 return (FALSE); 721 } 722 enp->ec_attrmask |= SHF_WRITE; 723 if (!b_bang) 724 enp->ec_attrbits |= SHF_WRITE; 725 b_bang = FALSE; 726 break; 727 case 'x': 728 if (enp->ec_attrmask & SHF_EXECINSTR) { 729 mf_fatal(mf, 730 MSG_INTL(MSG_MAP_BADFLAG), 731 tkv.tkv_str); 732 return (FALSE); 733 } 734 enp->ec_attrmask |= SHF_EXECINSTR; 735 if (!b_bang) 736 enp->ec_attrbits |= 737 SHF_EXECINSTR; 738 b_bang = FALSE; 739 break; 740 default: 741 mf_fatal(mf, 742 MSG_INTL(MSG_MAP_BADFLAG), 743 tkv.tkv_str); 744 return (FALSE); 745 } 746 if (enp->ec_attrmask != 0) 747 enp->ec_flags &= ~FLG_EC_CATCHALL; 748 749 /* 750 * Section name. 751 */ 752 } else { 753 if (b_name) { 754 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 755 MSG_INTL(MSG_MAP_SECNAME)); 756 return (FALSE); 757 } 758 b_name = TRUE; 759 enp->ec_is_name = tkv.tkv_str; 760 enp->ec_flags &= ~FLG_EC_CATCHALL; 761 } 762 } 763 if (tok == TK_COLON) { 764 /* 765 * File names. 766 */ 767 while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) { 768 Word ecf_type; 769 770 if (tok != TK_STRING) { 771 if (tok != TK_ERROR) 772 mf_fatal0(mf, 773 MSG_INTL(MSG_MAP_MALFORM)); 774 return (FALSE); 775 } 776 777 /* 778 * A leading '*' means that this should be a basename 779 * comparison rather than a full path. It's not a glob 780 * wildcard, although it looks like one. 781 */ 782 if (tkv.tkv_str[0] == '*') { 783 ecf_type = TYP_ECF_BASENAME; 784 tkv.tkv_str++; 785 } else { 786 ecf_type = TYP_ECF_PATH; 787 } 788 if (!ld_map_seg_ent_files(mf, enp, ecf_type, 789 tkv.tkv_str)) 790 return (FALSE); 791 enp->ec_flags &= ~FLG_EC_CATCHALL; 792 } 793 } 794 return (TRUE); 795 } 796 797 /* 798 * Process a mapfile size symbol definition. 799 * segment_name @ symbol_name; 800 */ 801 static Boolean 802 map_atsign(Mapfile *mf, Sg_desc *sgp) 803 { 804 Token tok; /* Current token. */ 805 ld_map_tkval_t tkv; /* Value of token */ 806 807 if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) { 808 if (tok != TK_ERROR) 809 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_1)); 810 return (FALSE); 811 } 812 813 /* Add the symbol to the segment */ 814 if (!ld_map_seg_size_symbol(mf, sgp, TK_PLUSEQ, tkv.tkv_str)) 815 return (FALSE); 816 817 818 if (ld_map_gettoken(mf, 0, &tkv) != TK_SEMICOLON) { 819 if (tok != TK_ERROR) 820 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL)); 821 return (FALSE); 822 } 823 824 return (TRUE); 825 } 826 827 828 static Boolean 829 map_pipe(Mapfile *mf, Sg_desc *sgp) 830 { 831 Token tok; /* current token. */ 832 ld_map_tkval_t tkv; /* Value of token */ 833 834 if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) { 835 if (tok != TK_ERROR) 836 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEC)); 837 return (FALSE); 838 } 839 840 if (!ld_map_seg_os_order_add(mf, sgp, tkv.tkv_str)) 841 return (FALSE); 842 843 if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) { 844 if (tok != TK_ERROR) 845 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL)); 846 return (FALSE); 847 } 848 849 return (TRUE); 850 } 851 852 /* 853 * Process a mapfile library specification definition. 854 * shared_object_name - shared object definition 855 * shared object definition : [ shared object type [ = SONAME ]] 856 * [ versions ]; 857 */ 858 static Boolean 859 map_dash(Mapfile *mf, char *name) 860 { 861 Token tok; 862 Sdf_desc *sdf; 863 ld_map_tkval_t tkv; /* Value of token */ 864 enum { 865 MD_NONE = 0, 866 MD_ADDVERS, 867 } dolkey = MD_NONE; 868 869 /* Get descriptor for dependency */ 870 if ((sdf = ld_map_dv(mf, name)) == NULL) 871 return (FALSE); 872 873 /* 874 * Get the shared object descriptor string. 875 */ 876 while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) { 877 if ((tok != TK_STRING) && (tok != TK_EQUAL)) { 878 if (tok != TK_ERROR) 879 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSO)); 880 return (FALSE); 881 } 882 883 /* 884 * Determine if the library type is accompanied with a SONAME 885 * definition. 886 */ 887 if (tok == TK_EQUAL) { 888 if ((tok = ld_map_gettoken(mf, 0, &tkv)) != 889 TK_STRING) { 890 if (tok != TK_ERROR) 891 mf_fatal0(mf, 892 MSG_INTL(MSG_MAP_EXPSO)); 893 return (FALSE); 894 } 895 switch (dolkey) { 896 case MD_ADDVERS: 897 if (!ld_map_dv_entry(mf, sdf, TRUE, 898 tkv.tkv_str)) 899 return (FALSE); 900 break; 901 case MD_NONE: 902 mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '='); 903 return (FALSE); 904 } 905 dolkey = MD_NONE; 906 continue; 907 } 908 909 /* 910 * A shared object type has been specified. This may also be 911 * accompanied by an SONAME redefinition (see above). 912 */ 913 if (*tkv.tkv_str == '$') { 914 if (dolkey != MD_NONE) { 915 mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '$'); 916 return (FALSE); 917 } 918 tkv.tkv_str++; 919 ld_map_lowercase(tkv.tkv_str); 920 if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_ADDVERS)) == 921 0) { 922 dolkey = MD_ADDVERS; 923 } else { 924 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSOTYP), 925 tkv.tkv_str); 926 return (FALSE); 927 } 928 continue; 929 } 930 931 /* 932 * shared object version requirement. 933 */ 934 if (!ld_map_dv_entry(mf, sdf, FALSE, tkv.tkv_str)) 935 return (FALSE); 936 } 937 938 return (TRUE); 939 } 940 941 942 /* 943 * Process a symbol definition. Historically, this originated from processing 944 * a version definition. However, this has evolved into a generic means of 945 * defining symbol references and definitions (see Defining Additional Symbols 946 * in the Linker and Libraries guide for the complete syntax). 947 * 948 * [ name ] { 949 * scope: 950 * symbol [ = [ type ] [ value ] [ size ] [ attribute ] ]; 951 * } [ dependency ]; 952 * 953 */ 954 static Boolean 955 map_version(Mapfile *mf, char *name) 956 { 957 Token tok; 958 ld_map_tkval_t tkv; /* Value of token */ 959 ld_map_ver_t mv; 960 ld_map_sym_t ms; 961 Ofl_desc *ofl = mf->mf_ofl; 962 963 /* Establish the version descriptor and related data */ 964 if (!ld_map_sym_ver_init(mf, name, &mv)) 965 return (FALSE); 966 967 /* 968 * Scan the mapfile entry picking out scoping and symbol definitions. 969 */ 970 while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_RIGHTBKT) { 971 uint_t filter = 0; 972 973 if (tok != TK_STRING) { 974 if (tok == TK_ERROR) { 975 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_2)); 976 return (FALSE); 977 } 978 mv.mv_errcnt++; 979 continue; 980 } 981 982 /* The default value for all the symbol attributes is 0 */ 983 (void) memset(&ms, 0, sizeof (ms)); 984 ms.ms_name = tkv.tkv_str; 985 986 tok = ld_map_gettoken(mf, 0, &tkv); 987 if (tok == TK_ERROR) { 988 mv.mv_errcnt++; 989 continue; 990 } 991 992 /* 993 * Turn off the WEAK flag to indicate that definitions are 994 * associated with this version. It would probably be more 995 * accurate to only remove this flag with the specification of 996 * global symbols, however setting it here allows enough slop 997 * to compensate for the various user inputs we've seen so far. 998 * Only if a closed version is specified (i.e., "SUNW_1.x {};") 999 * will a user get a weak version (which is how we document the 1000 * creation of weak versions). 1001 */ 1002 mv.mv_vdp->vd_flags &= ~VER_FLG_WEAK; 1003 1004 switch (tok) { 1005 case TK_COLON: 1006 ld_map_sym_scope(mf, ms.ms_name, &mv); 1007 continue; 1008 1009 case TK_EQUAL: 1010 /* 1011 * A full blown symbol definition follows. 1012 * Determine the symbol type and any virtual address or 1013 * alignment specified and then fall through to process 1014 * the entire symbols information. 1015 */ 1016 while ((tok = ld_map_gettoken(mf, 0, &tkv)) != 1017 TK_SEMICOLON) { 1018 if (tok == TK_ERROR) 1019 return (FALSE); 1020 if (tok != TK_STRING) { 1021 mf_fatal0(mf, 1022 MSG_INTL(MSG_MAP_MALFORM)); 1023 return (FALSE); 1024 } 1025 1026 /* 1027 * If we had previously seen AUX or FILTER, 1028 * the next string is the filtee itself. 1029 * Add it, and clear the filter flag. 1030 */ 1031 if (filter) { 1032 ld_map_sym_filtee(mf, &mv, &ms, 1033 filter, tkv.tkv_str); 1034 filter = 0; 1035 continue; 1036 } 1037 1038 /* 1039 * Determine any Value or Size attributes. 1040 */ 1041 ld_map_lowercase(tkv.tkv_str); 1042 1043 if (tkv.tkv_str[0] == 'v' || 1044 tkv.tkv_str[0] == 's') { 1045 Xword number; 1046 1047 if (!valuetoxword(mf, &tkv, &number)) { 1048 mv.mv_errcnt++; 1049 return (FALSE); 1050 } 1051 1052 switch (*tkv.tkv_str) { 1053 case 'v': 1054 /* BEGIN CSTYLED */ 1055 if (ms.ms_value) { 1056 mf_fatal(mf, 1057 MSG_INTL(MSG_MAP_MOREONCE), 1058 MSG_INTL(MSG_MAP_SYMVAL)); 1059 mv.mv_errcnt++; 1060 continue; 1061 } 1062 /* LINTED */ 1063 ms.ms_value = (Addr)number; 1064 ms.ms_value_set = TRUE; 1065 break; 1066 /* END CSTYLED */ 1067 case 's': 1068 /* BEGIN CSTYLED */ 1069 if (ms.ms_size) { 1070 mf_fatal(mf, 1071 MSG_INTL(MSG_MAP_MOREONCE), 1072 MSG_INTL(MSG_MAP_SYMSIZE)); 1073 mv.mv_errcnt++; 1074 continue; 1075 } 1076 /* LINTED */ 1077 ms.ms_size = (Addr)number; 1078 break; 1079 /* END CSTYLED */ 1080 } 1081 1082 } else if (strcmp(tkv.tkv_str, 1083 MSG_ORIG(MSG_MAP_FUNCTION)) == 0) { 1084 ms.ms_shndx = SHN_ABS; 1085 ms.ms_sdflags |= FLG_SY_SPECSEC; 1086 ms.ms_type = STT_FUNC; 1087 } else if (strcmp(tkv.tkv_str, 1088 MSG_ORIG(MSG_MAP_DATA)) == 0) { 1089 ms.ms_shndx = SHN_ABS; 1090 ms.ms_sdflags |= FLG_SY_SPECSEC; 1091 ms.ms_type = STT_OBJECT; 1092 } else if (strcmp(tkv.tkv_str, 1093 MSG_ORIG(MSG_MAP_COMMON)) == 0) { 1094 ms.ms_shndx = SHN_COMMON; 1095 ms.ms_sdflags |= FLG_SY_SPECSEC; 1096 ms.ms_type = STT_OBJECT; 1097 } else if (strcmp(tkv.tkv_str, 1098 MSG_ORIG(MSG_MAP_PARENT)) == 0) { 1099 ms.ms_sdflags |= FLG_SY_PARENT; 1100 ofl->ofl_flags |= FLG_OF_SYMINFO; 1101 } else if (strcmp(tkv.tkv_str, 1102 MSG_ORIG(MSG_MAP_EXTERN)) == 0) { 1103 ms.ms_sdflags |= FLG_SY_EXTERN; 1104 ofl->ofl_flags |= FLG_OF_SYMINFO; 1105 } else if (strcmp(tkv.tkv_str, 1106 MSG_ORIG(MSG_MAP_DIRECT)) == 0) { 1107 ms.ms_sdflags |= FLG_SY_DIR; 1108 ofl->ofl_flags |= FLG_OF_SYMINFO; 1109 } else if (strcmp(tkv.tkv_str, 1110 MSG_ORIG(MSG_MAP_NODIRECT)) == 0) { 1111 ms.ms_sdflags |= FLG_SY_NDIR; 1112 ofl->ofl_flags |= FLG_OF_SYMINFO; 1113 ofl->ofl_flags1 |= 1114 (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR); 1115 } else if (strcmp(tkv.tkv_str, 1116 MSG_ORIG(MSG_MAP_FILTER)) == 0) { 1117 /* Next token is the filtee */ 1118 filter = FLG_SY_STDFLTR; 1119 continue; 1120 } else if (strcmp(tkv.tkv_str, 1121 MSG_ORIG(MSG_MAP_AUXILIARY)) == 0) { 1122 /* Next token is the filtee */ 1123 filter = FLG_SY_AUXFLTR; 1124 continue; 1125 } else if (strcmp(tkv.tkv_str, 1126 MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) { 1127 /* BEGIN CSTYLED */ 1128 if (!(ofl->ofl_flags & FLG_OF_EXEC)) { 1129 mf_fatal0(mf, 1130 MSG_INTL(MSG_MAP_NOINTPOSE)); 1131 mv.mv_errcnt++; 1132 break; 1133 } 1134 /* END CSTYLED */ 1135 ms.ms_sdflags |= FLG_SY_INTPOSE; 1136 ofl->ofl_flags |= FLG_OF_SYMINFO; 1137 ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE; 1138 continue; 1139 } else if (strcmp(tkv.tkv_str, 1140 MSG_ORIG(MSG_MAP_DYNSORT)) == 0) { 1141 ms.ms_sdflags |= FLG_SY_DYNSORT; 1142 ms.ms_sdflags &= ~FLG_SY_NODYNSORT; 1143 continue; 1144 } else if (strcmp(tkv.tkv_str, 1145 MSG_ORIG(MSG_MAP_NODYNSORT)) == 0) { 1146 ms.ms_sdflags &= ~FLG_SY_DYNSORT; 1147 ms.ms_sdflags |= FLG_SY_NODYNSORT; 1148 continue; 1149 } else { 1150 mf_fatal(mf, 1151 MSG_INTL(MSG_MAP_UNKSYMDEF), 1152 tkv.tkv_str); 1153 mv.mv_errcnt++; 1154 continue; 1155 } 1156 } 1157 /* FALLTHROUGH */ 1158 1159 case TK_SEMICOLON: 1160 /* Auto-reduction directive ('*')? */ 1161 if (*ms.ms_name == '*') { 1162 ld_map_sym_autoreduce(mf, &mv); 1163 continue; 1164 } 1165 1166 /* 1167 * Catch the error where the AUX or FILTER keyword 1168 * was used, but the filtee wasn't supplied. 1169 */ 1170 if (filter && (ms.ms_filtee == NULL)) { 1171 mf_fatal(mf, MSG_INTL(MSG_MAP_NOFILTER), 1172 ms.ms_name); 1173 mv.mv_errcnt++; 1174 continue; 1175 } 1176 1177 /* 1178 * Add the new symbol. It should be noted that all 1179 * symbols added by the mapfile start out with global 1180 * scope, thus they will fall through the normal symbol 1181 * resolution process. Symbols defined as locals will 1182 * be reduced in scope after all input file processing. 1183 */ 1184 if (!ld_map_sym_enter(mf, &mv, &ms)) 1185 return (FALSE); 1186 break; 1187 1188 default: 1189 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL)); 1190 mv.mv_errcnt++; 1191 continue; 1192 } 1193 } 1194 1195 if (mv.mv_errcnt) 1196 return (FALSE); 1197 1198 /* 1199 * Determine if any version references are provided after the close 1200 * bracket, parsing up to the terminating ';'. 1201 */ 1202 if (!ld_map_sym_ver_fini(mf, &mv)) 1203 return (FALSE); 1204 1205 return (TRUE); 1206 } 1207 1208 /* 1209 * Parse the mapfile --- Sysv syntax 1210 */ 1211 Boolean 1212 ld_map_parse_v1(Mapfile *mf) 1213 { 1214 Sg_desc *sgp1; /* seg descriptor being manipulated */ 1215 Ent_desc *enp; /* segment entrance criteria. */ 1216 Token tok; /* current token. */ 1217 Boolean new_segment; /* If true, defines new segment */ 1218 char *name; 1219 Ofl_desc *ofl = mf->mf_ofl; 1220 ld_map_tkval_t tkv; /* Value of token */ 1221 avl_index_t where; 1222 1223 /* 1224 * We now parse the mapfile until the gettoken routine returns EOF. 1225 */ 1226 while ((tok = ld_map_gettoken(mf, TK_F_EOFOK, &tkv)) != TK_EOF) { 1227 Xword ndx; 1228 1229 /* 1230 * At this point we are at the beginning of a line, and the 1231 * variable tkv.tkv_str points to the first string on the line. 1232 * All mapfile entries start with some string token except it 1233 * is possible for a scoping definition to start with `{'. 1234 */ 1235 if (tok == TK_LEFTBKT) { 1236 if (!map_version(mf, NULL)) 1237 return (FALSE); 1238 continue; 1239 } 1240 if (tok != TK_STRING) { 1241 if (tok != TK_ERROR) 1242 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGNAM)); 1243 return (FALSE); 1244 } 1245 1246 /* 1247 * Save the initial token. 1248 */ 1249 name = tkv.tkv_str; 1250 1251 /* 1252 * Now check the second character on the line. The special `-' 1253 * and `{' characters do not involve any segment manipulation so 1254 * we handle them first. 1255 */ 1256 tok = ld_map_gettoken(mf, 0, &tkv); 1257 if (tok == TK_ERROR) 1258 return (FALSE); 1259 if (tok == TK_DASH) { 1260 if (!map_dash(mf, name)) 1261 return (FALSE); 1262 continue; 1263 } 1264 if (tok == TK_LEFTBKT) { 1265 if (!map_version(mf, name)) 1266 return (FALSE); 1267 continue; 1268 } 1269 1270 /* 1271 * If we're here we need to interpret the first string as a 1272 * segment name. Is this an already known segment? 1273 */ 1274 sgp1 = ld_seg_lookup(mf->mf_ofl, name, &where); 1275 new_segment = sgp1 == NULL; 1276 if (!new_segment) 1277 sgp1->sg_flags &= ~FLG_SG_DISABLED; 1278 1279 /* 1280 * If the second token is a '|' then we had better have found a 1281 * segment. It is illegal to perform section within segment 1282 * ordering before the segment has been declared. 1283 */ 1284 if (tok == TK_PIPE) { 1285 if (sgp1 == NULL) { 1286 mf_fatal(mf, MSG_INTL(MSG_MAP_SECINSEG), 1287 name); 1288 return (FALSE); 1289 } 1290 if (!map_pipe(mf, sgp1)) 1291 return (FALSE); 1292 continue; 1293 } 1294 1295 /* 1296 * If segment does not exist, allocate a descriptor with 1297 * its values set to 0 so that map_equal() can detect 1298 * changing attributes. 1299 */ 1300 if (new_segment && 1301 ((sgp1 = ld_map_seg_alloc(name, PT_NULL, 0)) == NULL)) 1302 return (FALSE); 1303 1304 /* 1305 * Now check the second token from the input line. 1306 */ 1307 switch (tok) { 1308 case TK_EQUAL: /* Create/modify segment */ 1309 /* 1310 * We use the same syntax for hardware/software 1311 * capabilities as we do for segments. If the 1312 * "segment name" matches one of these, then 1313 * process the capabilities instead of treating it 1314 * as a segment. Note that no dynamic memory has 1315 * been allocated for the segment descriptor yet, 1316 * so we can bail without leaking memory. 1317 */ 1318 if (strcmp(sgp1->sg_name, 1319 MSG_ORIG(MSG_STR_HWCAP_1)) == 0) { 1320 if (!map_cap(mf, CA_SUNW_HW_1, 1321 &ofl->ofl_ocapset.c_hw_1)) 1322 return (FALSE); 1323 continue; 1324 1325 } 1326 if (strcmp(sgp1->sg_name, 1327 MSG_ORIG(MSG_STR_SFCAP_1)) == 0) { 1328 if (!map_cap(mf, CA_SUNW_SF_1, 1329 &ofl->ofl_ocapset.c_sf_1)) 1330 return (FALSE); 1331 continue; 1332 1333 } 1334 1335 /* 1336 * If not a new segment, show the initial value 1337 * before modifying it. 1338 */ 1339 if (!new_segment && DBG_ENABLED) { 1340 ndx = ld_map_seg_index(mf, sgp1); 1341 Dbg_map_seg(ofl, DBG_STATE_MOD_BEFORE, 1342 ndx, sgp1, mf->mf_lineno); 1343 } 1344 1345 /* Process the segment */ 1346 if (!map_equal(mf, sgp1)) 1347 return (FALSE); 1348 1349 /* 1350 * Special case for STACK "segments": 1351 * 1352 * The ability to modify the stack flags was added 1353 * long after this sysv syntax was designed. It was 1354 * fit into the existing syntax by treating it as a 1355 * segment. However, there can only be one stack program 1356 * header, while segment syntax requires user to supply 1357 * a name. This is confusing, and it allows the user to 1358 * attempt to create more than one stack segment. The 1359 * original implementation had a test to catch this. 1360 * 1361 * If this is a stack segment, locate the real stack 1362 * descriptor and transfer the flags to it. We then 1363 * free the allocated descriptor without inserting it. 1364 * The end result is that all stack segments simply 1365 * alter the one stack descriptor, and the segment 1366 * name is ignored. 1367 */ 1368 if (sgp1->sg_phdr.p_type == PT_SUNWSTACK) { 1369 Sg_desc *stack = ld_map_seg_stack(mf); 1370 1371 if (sgp1->sg_flags & FLG_SG_P_FLAGS) 1372 stack->sg_phdr.p_flags = 1373 sgp1->sg_phdr.p_flags; 1374 free(sgp1); 1375 1376 DBG_CALL(Dbg_map_seg(ofl, 1377 DBG_STATE_MOD_AFTER, ndx, sgp1, 1378 mf->mf_lineno)); 1379 break; 1380 } 1381 1382 /* 1383 * If this is a new segment, finish its initialization 1384 * and insert it into the segment list. 1385 */ 1386 if (new_segment) { 1387 switch (ld_map_seg_insert(mf, DBG_STATE_NEW, 1388 sgp1, where)) { 1389 case SEG_INS_SKIP: 1390 continue; 1391 case SEG_INS_FAIL: 1392 return (FALSE); 1393 } 1394 } else { 1395 /* Not new. Show what's changed */ 1396 DBG_CALL(Dbg_map_seg(ofl, 1397 DBG_STATE_MOD_AFTER, ndx, sgp1, 1398 mf->mf_lineno)); 1399 } 1400 break; 1401 1402 case TK_COLON: /* Section to segment mapping */ 1403 /* 1404 * If this is a new segment, finish its initialization 1405 * and insert it into the segment list. 1406 * 1407 * If it is not a new segment, ensure that it is 1408 * not an empty segment reservation, as sections 1409 * cannot be assigned to those. 1410 */ 1411 if (new_segment) { 1412 switch (ld_map_seg_insert(mf, 1413 DBG_STATE_NEW_IMPLICIT, sgp1, where)) { 1414 case SEG_INS_SKIP: 1415 continue; 1416 case SEG_INS_FAIL: 1417 return (FALSE); 1418 } 1419 } else if (sgp1->sg_flags & FLG_SG_EMPTY) { 1420 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPSEC)); 1421 return (FALSE); 1422 } 1423 1424 /* 1425 * Create new entrance criteria descriptor, and 1426 * process the mapping directive. 1427 */ 1428 enp = ld_map_seg_ent_add(mf, sgp1, NULL); 1429 if ((enp == NULL) || !map_colon(mf, enp)) 1430 return (FALSE); 1431 DBG_CALL(Dbg_map_ent(ofl->ofl_lml, enp, ofl, 1432 mf->mf_lineno)); 1433 break; 1434 1435 case TK_ATSIGN: /* Section size symbol */ 1436 /* 1437 * If this is a new segment, finish its initialization 1438 * and insert it into the segment list. 1439 */ 1440 if (new_segment) { 1441 switch (ld_map_seg_insert(mf, 1442 DBG_STATE_NEW_IMPLICIT, sgp1, where)) { 1443 case SEG_INS_SKIP: 1444 continue; 1445 case SEG_INS_FAIL: 1446 return (FALSE); 1447 } 1448 } 1449 if (!map_atsign(mf, sgp1)) 1450 return (FALSE); 1451 break; 1452 1453 case TK_ERROR: 1454 return (FALSE); /* Error was already issued */ 1455 1456 default: 1457 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPEQU)); 1458 return (FALSE); 1459 } 1460 } 1461 1462 return (TRUE); 1463 } 1464