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